Finding Second Smallest Element In an Unsorted Array

How should I go about finding the 2nd, or 3rd smallest element in an array?
Where the minimum is not equals to the next minimum.

Here is the psuedocode I've found
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Min(A[i..j], int&min, int &next_min)

if (i=j) then min=A[i] and next_min = infinity

else
mid = (i+j)/2

Min(A[i to mid]),a,b)
Min(A[mid+1 to j],c,d)

Let min be minimum among a,b,c,d
Let next_min be the next_min among a,b,c,d

min != next_min


Here is what I wrote but it does not seem to work. Can anyone point me to the right direction? Thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include<iostream>
#include<vector>
#include <cstdlib>

using namespace std;


void minfind(vector<int> &array,int left,int right, int &min, int &next_min);

int main(){
	cout << "Enter integers one line at a time. (Enter -999 to terminate)" << endl;

    vector<int> array;  // you can also use an array to do this, e.g., int A[21];
	int input;

    //let user enter till termination condition
	while(true){
        cin >> input;
		if(input == -999) //check for termination condition
			break;
        array.push_back(input);
    }

int imin = 0;
int imax = array.size();
int q;
int r;

minfind(array, imin, imax, q, r);

   
    
    cout<<"Min number is " << r <<endl;

    cin.get();
    system("pause");
    return 0;
}


void minfind(vector<int> &array,int left,int right, int &min, int &next_min)
{
    int a;
    int b;
    int c;
    int d;
    
	if(left == right){ 
    min = array[left];
    
    next_min = 2147483647;
    
    }
    else {
        
         int mid= (right+left)/2;
                  
        minfind(array,left,mid,a,b);
        minfind(array,mid+1,right,c,d);
         
         
         if (a<b){ 
         min = a;
            if (b<c && b<d)
            next_min = b;
        }
        
        else if (b<a){
        min = b;
            if (a<c&& a<d)
            next_min = a;
        }
         
        if (c<d){ 
         min = c;
            if (d<a && d<b)
            next_min = d;
        }
        
        else if (d<c){
        min = d;
            if (c<a && c<b)
            next_min = c;
        } 
         
        
        
    }
}


Maybe you're thinking too complicated. Element 2 should be smaller than element 1 yet the highest in its rank. This implies that 3 is smaller than 2, and thus you can use the same loop just with different integers. Check the 4th block of code (containing 2 for loops).


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <vector>
#include <iostream>


int main()
{
    enum {SIZE = 16, NUMS = 100, LIM = 100};

    int highest[SIZE] {0};
    std::vector<int> v;
    for (int i = 0; i < NUMS; ++i)
        v.emplace_back(std::rand() % LIM);

    for (auto &x : v)
        if (x > highest[0])
            highest[0] = x;

    for (int i = 0; i < SIZE; ++i)
        for (auto &x : v)
            if (x > highest[i + 1] && x < highest[i])
                highest[i + 1] = x;

    for (auto &x : v)
        std::cout << x << std::endl;

    for (int i = 0; i < SIZE; ++i)
        std::cout << i << ": " << highest[i] << std::endl;

    return 0;
}
y cant u just use SORT?
with algortihm
@topnik1

Using sort means that equivalent elements come after each other. So vector[0] may contain 99, and so does vector[1] or even vector[2] because you may have the number 99, 3 times in the vector/array.
That is a case that would render nth_element useless too.

If one knows the N-1th smallest value X, then one can write the usual find min element with a twist: call all the <=X values "too big" in the test.

There is always the std::map. Filling it is an implisit sort, and it can hide the repeated values in its value_type.
Last edited on
Topic archived. No new replies allowed.