转自:https://blog.csdn.net/vayne_xiao/article/details/53508973
为什么快速排序一定要先从右边开始
while(arr[j]>=temp&&i<j){
j--;
}
while(arr[i]<=temp&&i<j){
i++;
}
这里两个while的顺序是不能改变的,想一想:
假设对如下进行排序:
如上图,6在左,9在右 我们将6作为基数。
假设从左边开始(与正确程序正好相反)
于是i 就会移动到现在的 数字 7 那个位置停下来,而 j 原来在 数字 9 那个位置 ,因为
while(arr[j]>=temp&&i<j)
于是,j 也会停留在数字7 那个位置,于是问题来了。当你最后交换基数6与7时,不对呀!!。
问题在于当我们先从在边开始时,那么 i 所停留的那个位置肯定是大于基数6的,而在上述例子中,为了满足 i<j 于是 j也停留在7的位置
但最后交换回去的时候,7就到了左边,不行,因为我们原本 交换后数字6在边应该是全部小于6,右边全部大于6.但现在不行了。
于是,我们必须从右边开始,也就是从基数的对面开始。
求数组的前K个最小的数
#include<stdio.h>
#include<error.h>
#define ERROR -22
static int quicksort(int *arr, int left, int right, int k)
{
int l, r, base, temp;
if(arr==NULL){
fprintf(stderr, "arr should not be NULL\n");
return ERROR;
}
if(left>right){
return 0;
}
base = arr[left];
l = left;
r = right;
while(l<r){
// 为什么一定是先右边呢?
//先右边
while(base<=arr[r]&&l<r){
r--;
}
//再左边
while(base>=arr[l]&&l<r){
l++;
}
if(l<r){
temp = arr[r];
arr[r] = arr[l];
arr[l] = temp;
}
}
arr[left] = arr[l];
arr[l] = base;
if(l<k){
quicksort(arr, left, l-1, k);
quicksort(arr, l+1, right, k);
}else{
quicksort(arr, left, l-1, k);
}
return base;
}
int main()
{
int arr[] = {6,1,2,5,4,3,9,7,10,8};
int b = 0;
int k = 3;
int ret = quicksort(arr, 0, sizeof(arr)/sizeof(arr[0]), k);
int i =0;
for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++){
printf("%d\t", arr[i]);
}
printf("\n");
}
出现次数超过一半的数
#include<stdio.h>
#include<error.h>
#define ERROR -22
static int quicksort(int *arr, int left, int right, int k)
{
int l, r, base, temp;
if(arr==NULL){
fprintf(stderr, "arr should not be NULL\n");
return ERROR;
}
if(left>right){
return 0;
}
base = arr[left];
l = left;
r = right;
while(l<r){
// 为什么一定是先右边呢?
//先右边
while(base<=arr[r]&&l<r){
r--;
}
//再左边
while(base>=arr[l]&&l<r){
l++;
}
if(l<r){
temp = arr[r];
arr[r] = arr[l];
arr[l] = temp;
}
}
arr[left] = arr[l];
arr[l] = base;
if(l==k){
return arr[k];
}else if(l>k){
quicksort(arr, left, l-1, k);
}else{
quicksort(arr, l+1, right, k);
}
return 0;
}
int main()
{
int arr[] = {6,6,2,5,4,3,6,6,6,6};
int b = 0;
int k = sizeof(arr)/sizeof(arr[0])/2;
int ret = quicksort(arr, 0, sizeof(arr)/sizeof(arr[0]), k);
printf("%d\n", arr[k]);
}