日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

c++深入淺出講解堆排序和堆_C 語言

作者:YR_T ? 更新時間: 2022-06-01 編程語言

堆是什么

堆是一種特殊的完全二叉樹

如果你是初學者,你的表情一定是這樣的??

別想復雜

首先,你一定見過這種圖

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETkBZUl9U,size_12,color_FFFFFF,t_70,g_se,x_16

咱們暫時不管數字

這就是一個堆

堆又分為最大堆和最小堆

最大堆

看這張圖

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETkBZUl9U,size_20,color_FFFFFF,t_70,g_se,x_16

上面的節點的數都比下面的節點的數大,最上面的數是最大的,這就叫最大堆??

最小堆

還是一樣的數,看這張圖

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETkBZUl9U,size_20,color_FFFFFF,t_70,g_se,x_16

這是一個最小堆,同最大堆,最上面的節點的數最小,上面的節點的數比下面的節點的數大

怎么樣,是不是很簡單?

堆排序

堆排序的基本思想是利用堆,使在排序中比較的次數明顯減少使速度更快

堆排序的時間復雜度為O(n*log(n)), 非穩定排序,原地排序(空間復雜度O(1))。

堆排序的關鍵在于建堆和調整堆,下面簡單介紹一下建堆的過程:

可以用STL下的

make_heap()

具體步驟:

第1趟將索引0至n-1處的全部數據建大頂(或小頂)堆,就可以選出這組數據的最大值(或最小值)。將該堆的根節點與這組數據的最后一個節點交換,就使的這組數據中最大(最小)值排在了最后。

第2趟將索引0至n-2處的全部數據建大頂(或小頂)堆,就可以選出這組數據的最大值(或最小值)。將該堆的根節點與這組數據的倒數第二個節點交換,就使的這組數據中最大(最小)值排在了倒數第2位。

第k趟將索引0至n-k處的全部數據建最大(或最小)堆,就可以選出這組數據的最大值(或最小值)。將該堆的根節點與這組數據的倒數第k個節點交換,就使的這組數據中最大(最小)值排在了倒數第k位。

其實整個堆排序過程中, 我們只需重復做兩件事:

建堆(初始化+調整堆, 時間復雜度為O(n));

拿堆的根節點和最后一個節點交換(siftdown, 時間復雜度為O(n*log n) ).

因而堆排序整體的時間復雜度為O(n*log n)

沒看懂可以看看這個圖

最終代碼

#include <iostream>
#include <stdlib.h>
using namespace std;
 
/*******************************************/
/*  堆排序
/******************************************/
 
void swap(int &a, int &b)  //位置互換函數
{
	int temp = a;
	a = b;
	b = temp;
}
 
 
void Heap(int array[], int length, int index)  //堆排序算法(大頂堆)
{
	int left = 2 * index + 1;  //左節點數組下標
	int right = 2 * index + 2;  //右節點數組下標
	int max = index;  //index是父節點
 
	if (left < length && array[left] > array[max])  //左節點與父節點比較
	{
		max = left;
	}
	
	if (right < length && array[right] > array[max])  //右節點與父節點比較
	{
		max = right;
	}
 
	if (array[index] != array[max])
	{
		swap(array[index], array[max]);
		Heap(array, length, max);  //遞歸調用
	}
}
 
 
void HeapSort(int array[], int size)  //堆排序函數
{
	for (int i = size / 2 - 1; i >= 0; i--)  // 創建一個堆
	{
		Heap(array, size, i);
	}
 
	for (int i = size - 1; i >= 1; i--)
	{
		swap(array[0], array[i]);  //將array[0]的最大值放到array[i]的位置上,最大值往后靠
		Heap(array, i, 0);  //調用堆排序算法進行比較
	}
}
 
 
int main(void)  //主程序
{
	const int n = 6;  //數組元素的數量
	int array[n];
	cout << "請輸入6個整數:" << endl;
	for (int i = 0; i < n; i++)
	{
		cin >> array[i];
	}
 
	cout << endl;  //換行
 
	HeapSort(array, n);  // 調用HeapSort函數  進行比較
 
	cout << "由小到大的順序排列后:" << endl;
	for (int i = 0; i < n; i++)
	{
		cout << "Array" << "[" << i << "]" << " = " << array[i] << endl;
	}
 
	cout << endl << endl;  //換行
 
	system("pause");  //調試時,黑窗口不會閃退,一直保持
	return 0;
}

關于堆

C++中堆的應用:make_heap, pop_heap, push_heap, sort_heap

函數說明: make_heap將[start, end)范圍進行堆排序,默認使用less, 即最大元素放在第一個。

pop_heap將front(即第一個最大元素)移動到end的前部,同時將剩下的元素重新構造成(堆排序)一個新的heap。

push_heap對剛插入的(尾部)元素做堆排序。

sort_heap將一個堆做排序,最終成為一個有序的系列,可以看到sort_heap時,必須先是一個堆(兩個特性:1、最大元素在第一個 2、添加或者刪除元素以對數時間),因此必須先做一次make_heap.

原文鏈接:https://blog.csdn.net/m0_64036070/article/details/123770678

欄目分類
最近更新