经典排序--快速排序、合并排序、堆排序
(一)快速排序
思想:用枢纽元素pivot将待排数组分成两个子表,左表中元素全都小于右表元素,,递归执行
int partition(int a[],int low,int high){
int pivot=a[low];
while(low=pivot) high--;
a[low]=a[high];
while(low
(二)合并排序
思想:将数组分为两段,段内已经有序,主体部分就是将两个有序的子表借助一个辅助数组B合并成一个
void merge(int a[],int low,int mid,int high){ //A[low-mid],A[mid+1-high]已经分别有序
for(int k=low;k<=high;k++){
b[k]=a[k];
}
for(int i=low,j=mid+1,k=i;i<=mid&&j<=high;k++){
if(b[i]<=b[j]){
a[k]=b[i];
i++;
}
else{
a[k]=b[j];
j++;
}
}
while(i<=mid) a[k++]=b[i++]; //注意:k+已经在上一个for循环里实现
while(j<=high) a[k++]=b[j++];
}
void mergesort(int a[],int low,int high){
if(low>high) return ;
int mid=(low+high)/2;
mergesort(a,low,mid); //一直划分子表
mergesort(a,mid+1,high);
merge(a,low,mid,high); //合并排序
}
(三)堆排序
思想:初始建立一个大根堆,后输出最大值后不断调整成堆的过程,三个函数实现
void adjustdown(int a[],int k,int len){ //以k为根的子树!,len为元素个数
int temp=a[k]; //暂存要向下调整的根结点的值
for(int i=2*k;i<=len;i*=2){ //主体!!!!!!
if(a[i]=a[i]) break; //跳出本轮循环,不需要下调
a[k]=a[i];
k=i; //k已经走到它的孩子结点,还要继续往下走
}
a[k]=temp;
}
void BuildMaxheap(int a[],int len){ //建立大根堆的实体代码
for(int i=len/2;i>0;i--){ //从第一个非叶子结点开始调整
adjustdown(a,i,len);
}
}
void heapsort(int a[],int len){
BuildMaxheap(a,len); //初始建堆
for(int i=len;i>1;i--){
swap(a[1],a[i]); //根节点总是到最后
adjustdown(a,1,i-1); //将剩余结点调整成堆
}
}