//快排为非稳定排序,因为两个相等的元素,在选择某数为基准数的情况下,可能会互换位置,具体去想原理;
//当利用C语言快排函数时,可利用结构体的优先元素排序解决不稳定的问题
//快排基于分治思想
//快排例程很多,自我感觉最全面可靠的是黑皮书教材上的,老美就是厉害,这一点确实得佩服人家,国内的计算机教材真心不敢恭维
//几个快排例程:
//一:教材(赞一个)
int Median3(int array[],int left,int right){//left,middle,right三个位置的数据按大小顺序排好,并且把基准数array[middle](三者中位数)与array[right-1]交换
int middle=(left+right)/2;
if(array[left]>array[middle])
swap(array[left],array[middle]);
if(array[middle]>array[right])
swap(array[middle],array[right]);
if(array[left]>array[right])
swap(array[left],array[right]);
swap(array[middle],array[right-1]);
return array[right-1];
}
void Qsort(int array[],int left,int right){
int pivot,i,j;
if(left>=right)//由代码判断,left>right应该出现不了吧(待定)
return;
pivot=Median3(array,left,right);//取基准数
i=left;
j=right-1;
if(j-i<=1)//j-i=0或1,说明当前排序序列一共俩/仨元素,那么经过Median3(),已排好序
return;
while(1){
while(array[++i]<pivot);
while(array[--j]>pivot);
if(i>j)
swap(array[i],array[j]);
else
break;
}
swap(array[i],array[right-1]);
Qsort(array,left,i-1);
Qsort(array,i+1,right);
}
void QuickSort(int array[],int n){//与主程序接口
Qsort(array,0,n-1);
}
//二:啊哈算法
void QuickSort(int array[],int left,int right)
{
int base=array[left];//取最左边的数为基准数,最后小于等于基准数的在基准数左,大于等于基准数的在右
int i=left;//哨兵,从左向右走;
int j=right;//哨兵,从右往左走;
if(left>=right)//递归出口,当left==right,为一个元素;left>right,说明上次i=j时,i,j均在当次快排的端点
return;
base=array[left];
while(i!=j){//哨兵相遇时,跳出while
while(array[j]>=base&&i<j)//j哨兵先走;理由在下方
j--;
while(array[i]<=base&&i<j)//i哨兵再走
i++;
if(i<j){//当哨兵不相遇,交换元素
int temp;
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
//当哨兵相遇,将基准数归位
array[left]=array[i];
array[i]=base;
QuickSort(array,left,i-1);//递归处理
QuickSort(array,i+1,right);//递归处理
}
//j先走理由:
//如:数组为 5 3 4 6 7 8 10 11 12
//若先走i,第一次会交换5(temp)和6,明显不符合
//三:其他书籍
void Sort(int array[],int left,int right)
{
int temp=array[left];
int i,j;
i=left;
j=right;
if(i>=j)
return;
while(i<j){//此处不可以用while(i!=j),,因为i可能直接到最后right的后面
while(array[i]<=temp&&i<=j)//先动i
i++;
while(array[j]>=temp&&i<=j)
j--;
if(i<j){
int t=array[i];
array[i]=array[j];
array[j]=t;
}
}
array[left]=array[i-1];
array[i-1]=temp;
Sort(array,left,i-2);
Sort(array,i,right);
}
//为何与array[i-1]交换? 与先动i有关系
//最后有两种情况:
//一,i直接到right后,此时array[right]<=temp
//二,经过几次交换,或者i直接到j,i和j相遇,j再退一步到i前面,此时array[i-1]小于等于temp,array[i]>temp