堆排序 C語言

堆排序
  堆排序是在排序過程當中,將向量中存儲的數據當作一顆徹底二叉樹,利用徹底二叉樹中雙親結點和孩子結點之間的內在關係來選擇關鍵字的最小的記錄,即待排序記錄中仍採用向量數組的方式存儲,並不是採用樹的存儲結構,二僅僅是採用徹底二叉樹的順序結構的特徵進行分析而已。
   二叉樹的順序表示, 每一個結點最多有兩個孩子結點(left, right), 這樣表示出來的二叉樹是一顆徹底二叉樹。若是父結點的下標爲i, 則其左孩子下標爲 2i+1, 右孩子下標爲2i+2;若是一個結點的下標爲j, 則其父結點的下標爲(j-1)/ 2。web

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define NUMBER 15

void OneAdjust(int* arr,int len,int root)
{
 int tmp=arr[root];
 int left=2*root+1;
 int right=2*root+2;

while(left<len)
 {
  int max=left;
  if(right<len&&arr[left]<arr[right])
  {
   max=right;
  }
  if(arr[max]<tmp)
  {
   break;
  }
  arr[root]=arr[max];
  root=max;
  left=2*root+1;
  right=2*root+2;
 }
 arr[root]=tmp;
}
void CreateHeap(int* arr,int len)//建大根堆
{
 int root=(len-2)/2;//最後一個結點的下標是len-1,算出的root爲最後一棵子樹的根結點下標
 for(;root>=0;--root)
 {
  OneAdjust(arr,len,root);
 }
 }
 
void Swap(int* a,int* b)
{
 int tmp=*a;
 *a=*b;
 *b=tmp;
}

void HeapSort(int* arr,int len)//堆排序
{
 CreateHeap (arr,len);
 for(int i=0;i<len-1;++i)
 {
  Swap(&arr[0],&arr[len-1-i]);
  OneAdjust (arr,len-i-1,0);
 }
}

int main()
{
 srand((unsigned int)time(NULL));
 int arr[NUMBER]={0};
 for(int i=0;i<NUMBER;++i)
 {
  arr[i]=rand()%100;
  printf("%d ",arr[i]);
 }
 printf("\n");
 HeapSort(arr,NUMBER);
 for(int i=0;i<NUMBER;++i)
 {
  printf("%d ",arr[i]);
 }
 printf("\n");
 return 0;
}

運行結果以下:
在這裏插入圖片描述數組