Selection algorithm (modified based on quick sort): select the i-th smallest value

1. Select the maximum and minimum values:
a) Select the maximum or minimum value , you can traverse all the elements of the array and complete it in linear time O(n).
Code:

int findmax(int* A,int N)
{
    
    
	int max = A[0];
	int tmp;
	for(int i = 1;i<N;i++){
    
    
		tmp = A[i];
		if(tmp>max){
    
     max = tmp; }
	}
	return max;
}

b) Select the maximum and minimum values ​​at the same time
Analysis: Find the maximum and minimum values ​​independently, the time complexity is O(2(n-1));
therefore,Compare a pair of input data, the smaller is compared with the current minimum, the larger is compared with the current maximum. So 4 elements are compared 3 times, the time complexity is O(3[n/2]).
Insert picture description here
Fake code:

int findmax(int* A,int N)
{
    
    
	int max,min; 
	if(n%2 == 0) {
    
     //n为偶数
		if(A[0]>A[1]) {
    
    max =A[0]; min =A[1];}
		else {
    
     max =A[1]; min =A[0]; }
	}
	else{
    
    
		max =min =A[0];
	}
	int tmp1,tmp2; //同时比较两个数
	。。。
	return max, min;
}

2. Selection algorithm: Return the i-th smallest element in the array A[p...r]
Idea: Divide and conquer, the modification of quick sort, the time complexity is O(n);
like quick sort, the input data is still divided recursively. But quicksort continues to recurse on both sides, so the time complexity is O(nlgn), but the selection algorithm only recurses on one side, and the time complexity is O(n).
Code (assuming that the elements are different):

int SelectK(int *A, int l, int r, int k);//找第k小数
{
    
    
	if(l == r) return A[l];
	int pivot = Partition(A, l, r); //返回主元的下标
	if(pivot == k-1) return A[pivot]; // 主元的下标为k-1则返回(下标从0开始,所以-1)
	else if(pivot >k-1) return SelectK(A, l, pivot-1, k); // 若下标大则在左边递归
	else return SelectK(A, pivot+1, r, k-pivor-2); // 小则在右边递归
}

int Partition(int *A, int l, int r)
{
    
    
	int pivot = A[r]; //将数组最后一个值作为主元
	int i = l;
	int j = r-1;
	for(;;){
    
    
		while (A[i]<pivot){
    
    i++;}
		while (A[j]>pivot){
    
    j--;}
		if(i<j) swap(A[i],A[j]);
		else break;
	}
	swap(A[i],A[right]); //将主元放在中间位置
	return i;
}

Note: The last value of the array is used as the pivot, and the subscript where the pivot is located is used to indicate the number of elements.

Guess you like

Origin blog.csdn.net/qq_33726635/article/details/105632370