必须知道的C语言八大排序算法(收藏)

2020-01-06 17:55:59刘景俊

1)n 个结点的完全二叉树,则最后一个结点是第c语言,八大排序算法,c语言排序算法个结点的子树。

2)筛选从第c语言,八大排序算法,c语言排序算法个结点为根的子树开始,该子树成为堆。

3)之后向前依次对各结点为根的子树进行筛选,使之成为堆,直到根结点。

如图建堆初始过程:无序序列:(49,38,65,97,76,13,27,49)


                              c语言,八大排序算法,c语言排序算法


                              c语言,八大排序算法,c语言排序算法

 算法的实现:

从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。 


void print(int a[], int n){ 
 for(int j= 0; j<n; j++){ 
 cout<<a[j] <<" "; 
 } 
 cout<<endl; 
} 
/** 
 * 已知H[s…m]除了H[s] 外均满足堆的定义 
 * 调整H[s],使其成为大顶堆.即将对第s个结点为根的子树筛选, 
 * 
 * @param H是待调整的堆数组 
 * @param s是待调整的数组元素的位置 
 * @param length是数组的长度 
 * 
 */ 
void HeapAdjust(int H[],int s, int length) 
{ 
 int tmp = H[s]; 
 int child = 2*s+1; //左孩子结点的位置。(i+1 为当前调整结点的右孩子结点的位置) 
 while (child < length) { 
 if(child+1 <length && H[child]<H[child+1]) { // 如果右孩子大于左孩子(找到比当前待调整结点大的孩子结点) 
 ++child ; 
 } 
 if(H[s]<H[child]) { // 如果较大的子结点大于父结点 
 H[s] = H[child]; // 那么把较大的子结点往上移动,替换它的父结点 
 s = child; // 重新设置s ,即待调整的下一个结点的位置 
 child = 2*s+1; 
 } else { // 如果当前待调整结点大于它的左右孩子,则不需要调整,直接退出 
 break; 
 } 
 H[s] = tmp; // 当前待调整的结点放到比其大的孩子结点位置上 
 } 
 print(H,length); 
} 
/** 
 * 初始堆进行调整 
 * 将H[0..length-1]建成堆 
 * 调整完之后第一个元素是序列的最小的元素 
 */ 
void BuildingHeap(int H[], int length) 
{ 
 //最后一个有孩子的节点的位置 i= (length -1) / 2 
 for (int i = (length -1) / 2 ; i >= 0; --i) 
 HeapAdjust(H,i,length); 
} 
/** 
 * 堆排序算法 
 */ 
void HeapSort(int H[],int length) 
{ 
 //初始堆 
 BuildingHeap(H, length); 
 //从最后一个元素开始对序列进行调整 
 for (int i = length - 1; i > 0; --i) 
 { 
 //交换堆顶元素H[0]和堆中最后一个元素 
 int temp = H[i]; H[i] = H[0]; H[0] = temp; 
 //每次交换堆顶元素和堆中最后一个元素之后,都要对堆进行调整 
 HeapAdjust(H,0,i); 
 } 
} 
int main(){ 
 int H[10] = {3,1,5,7,2,4,9,6,10,8}; 
 cout<<"初始值:"; 
 print(H,10); 
 HeapSort(H,10); 
 //selectSort(a, 8); 
 cout<<"结果:"; 
 print(H,10); 
}