c++中八大排序算法

2020-01-06 15:52:04王冬梅

2)筛选从第个结点为根的子树开始,该子树成为堆。

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

如图建堆初始过程:无序序列:(49,38,65,97,76,13,27,49)八大排序算法,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[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); 
 
}