堆排序
堆排序是在排序过程当中,将向量中存储的数据当作一颗彻底二叉树,利用彻底二叉树中双亲结点和孩子结点之间的内在关系来选择关键字的最小的记录,即待排序记录中仍采用向量数组的方式存储,并不是采用树的存储结构,二仅仅是采用彻底二叉树的顺序结构的特征进行分析而已。
二叉树的顺序表示, 每一个结点最多有两个孩子结点(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; }
运行结果以下:
数组