经典排序--快速排序、合并排序、堆排序


(一)快速排序

思想:用枢纽元素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);  //将剩余结点调整成堆 
	} 
}

相关