思想:
父子结点关联:(下标从0开始)
父 子
i 2*i+1,2*i+2
(i-1)/2 i
思路演绎:
原始数据:7 4 9 5 12 6 8 3 10 23 11


调整后为:23 12 9 10 11 6 8 3 5 4 7

循环之最后的结果图为:

时间复杂度:O(nlogn) //从上往下调整的时候需要遍历->O(n),根节点与左右孩子交换时i=2*i+m ->O(logn).因此循环嵌套时,总时间复杂度为O(nlogn)
空间复杂度:O(1)
稳定性:不稳定
代码:
-
- //大根堆
- //调整为大根堆:左右孩子最大值和根交换的函数
- void HeapAdjust(int* arr, int start,int end)
- {
- int temp = arr[start];
- for(int i=2*start+1;i<=end;i=2*i+1)//2*start+1左孩子
- {
- if(i
1])//有右孩子并且小于右孩子 - {
- i++;
- }//i一定是左右孩子最大值
- if(arr[i]>temp)
- {
- arr[start]=arr[i];
- start=i;
- }
- else
- break;
- }
- arr[start]=temp;
- }
- void HeapSort(int* arr, int len)
- {
- int i;
- //1.左右孩子最大值和根交换
- for (int i = (len - 1 - 1) / 2; i >= 0; i--)
- {
- HeapAdjust(arr,i,len-1);//i:根开始下标;len-1:根截止下标(均设置为len-1)
- }
- //2.下标为0的根开始和待排序的最后一个值交换//3.再次调整
- int temp;
- for (int i = 0; i < len - 1; i++)//=len-1时没必要再和自己交换而且也不需要再次调整
- {
- temp = arr[0];
- arr[0] = arr[len - 1 - i];//下标从0开始 len-1
- arr[len - 1 - i] = temp;
- HeapAdjust(arr, 0,len - 1 - i - 1);
- }
- }
-
- void Show(int* arr,int len)
- {
- for (int i = 0; i < len; i++)
- {
- printf("%d ", arr[i]);
- }
- }
- int main()
- {
- int arr[] = { 6,4 ,7,8,10,-5,90,34,55};
- Show(arr,sizeof(arr) / sizeof(arr[0]));
- printf("\n ");
- HeapSort(arr, sizeof(arr) / sizeof(arr[0]));
- Show(arr, sizeof(arr) / sizeof(arr[0]));
- }
-
运行结果:
