亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

 更新時(shí)間:2022年03月29日 15:15:38   作者:YR_T  
在c++里有很多排序方法,比如相對(duì)簡(jiǎn)單的冒泡排序、選擇排序、插入排序,還有 STL里的sort函數(shù)  手寫(xiě)快排  歸并排序等,還有就是堆排序,這次主要說(shuō)堆排序和堆

堆是什么

堆是一種特殊的完全二叉樹(shù)

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

別想復(fù)雜

首先,你一定見(jiàn)過(guò)這種圖

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

咱們暫時(shí)不管數(shù)字

這就是一個(gè)堆

堆又分為最大堆和最小堆

最大堆

看這張圖

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

上面的節(jié)點(diǎn)的數(shù)都比下面的節(jié)點(diǎn)的數(shù)大,最上面的數(shù)是最大的,這就叫最大堆??

最小堆

還是一樣的數(shù),看這張圖

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

這是一個(gè)最小堆,同最大堆,最上面的節(jié)點(diǎn)的數(shù)最小,上面的節(jié)點(diǎn)的數(shù)比下面的節(jié)點(diǎn)的數(shù)大

怎么樣,是不是很簡(jiǎn)單?

堆排序

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

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

堆排序的關(guān)鍵在于建堆和調(diào)整堆,下面簡(jiǎn)單介紹一下建堆的過(guò)程:

可以用STL下的

make_heap()

具體步驟:

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

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

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

其實(shí)整個(gè)堆排序過(guò)程中, 我們只需重復(fù)做兩件事:

建堆(初始化+調(diào)整堆, 時(shí)間復(fù)雜度為O(n));

拿堆的根節(jié)點(diǎn)和最后一個(gè)節(jié)點(diǎn)交換(siftdown, 時(shí)間復(fù)雜度為O(n*log n) ).

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

沒(méi)看懂可以看看這個(gè)圖

最終代碼

#include <iostream>
#include <stdlib.h>
using namespace std;
 
/*******************************************/
/*  堆排序
/******************************************/
 
void swap(int &a, int &b)  //位置互換函數(shù)
{
	int temp = a;
	a = b;
	b = temp;
}
 
 
void Heap(int array[], int length, int index)  //堆排序算法(大頂堆)
{
	int left = 2 * index + 1;  //左節(jié)點(diǎn)數(shù)組下標(biāo)
	int right = 2 * index + 2;  //右節(jié)點(diǎn)數(shù)組下標(biāo)
	int max = index;  //index是父節(jié)點(diǎn)
 
	if (left < length && array[left] > array[max])  //左節(jié)點(diǎn)與父節(jié)點(diǎn)比較
	{
		max = left;
	}
	
	if (right < length && array[right] > array[max])  //右節(jié)點(diǎn)與父節(jié)點(diǎn)比較
	{
		max = right;
	}
 
	if (array[index] != array[max])
	{
		swap(array[index], array[max]);
		Heap(array, length, max);  //遞歸調(diào)用
	}
}
 
 
void HeapSort(int array[], int size)  //堆排序函數(shù)
{
	for (int i = size / 2 - 1; i >= 0; i--)  // 創(chuàng)建一個(gè)堆
	{
		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);  //調(diào)用堆排序算法進(jìn)行比較
	}
}
 
 
int main(void)  //主程序
{
	const int n = 6;  //數(shù)組元素的數(shù)量
	int array[n];
	cout << "請(qǐng)輸入6個(gè)整數(shù):" << endl;
	for (int i = 0; i < n; i++)
	{
		cin >> array[i];
	}
 
	cout << endl;  //換行
 
	HeapSort(array, n);  // 調(diào)用HeapSort函數(shù)  進(jìn)行比較
 
	cout << "由小到大的順序排列后:" << endl;
	for (int i = 0; i < n; i++)
	{
		cout << "Array" << "[" << i << "]" << " = " << array[i] << endl;
	}
 
	cout << endl << endl;  //換行
 
	system("pause");  //調(diào)試時(shí),黑窗口不會(huì)閃退,一直保持
	return 0;
}

關(guān)于堆

C++中堆的應(yīng)用:make_heap, pop_heap, push_heap, sort_heap

函數(shù)說(shuō)明: make_heap將[start, end)范圍進(jìn)行堆排序,默認(rèn)使用less, 即最大元素放在第一個(gè)。

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

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

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

到此這篇關(guān)于c++深入淺出講解堆排序和堆的文章就介紹到這了,更多相關(guān)c++ 堆排序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Qt實(shí)現(xiàn)矩形大小任意縮放的示例代碼

    Qt實(shí)現(xiàn)矩形大小任意縮放的示例代碼

    這篇文章主要介紹了Qt如何實(shí)現(xiàn)在窗口上繪制任意大小的矩形,并且通過(guò)邊角的拖曳按鈕可改變矩形大小,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-06-06
  • C語(yǔ)言中數(shù)據(jù)如何存儲(chǔ)進(jìn)內(nèi)存揭秘

    C語(yǔ)言中數(shù)據(jù)如何存儲(chǔ)進(jìn)內(nèi)存揭秘

    使用編程語(yǔ)言進(jìn)行編程時(shí),需要用到各種變量來(lái)存儲(chǔ)各種信息。變量保留的是它所存儲(chǔ)的值的內(nèi)存位置。這意味著,當(dāng)您創(chuàng)建一個(gè)變量時(shí),就會(huì)在內(nèi)存中保留一些空間。您可能需要存儲(chǔ)各種數(shù)據(jù)類(lèi)型的信息,操作系統(tǒng)會(huì)根據(jù)變量的數(shù)據(jù)類(lèi)型,來(lái)分配內(nèi)存和決定在保留內(nèi)存中存儲(chǔ)什么
    2022-08-08
  • 基于C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易的掃雷游戲

    基于C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易的掃雷游戲

    這篇文章主要為大家詳細(xì)介紹了基于C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易的掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C++中關(guān)于互斥量的全面認(rèn)知

    C++中關(guān)于互斥量的全面認(rèn)知

    線(xiàn)程的主要優(yōu)勢(shì)在于,能夠通過(guò)全局變量來(lái)共享信息。不過(guò),這種便捷的共享是有代價(jià)的:必須確保多個(gè)線(xiàn)程不會(huì)同時(shí)修改同一變量,或者某一線(xiàn)程不會(huì)讀取正由其他線(xiàn)程修改的變量。為了防止出現(xiàn)線(xiàn)程某甲試圖訪(fǎng)?問(wèn)一共享變量時(shí),線(xiàn)程某乙正在對(duì)其進(jìn)行修改。引入了互斥量
    2022-05-05
  • C++數(shù)據(jù)結(jié)構(gòu)與算法之反轉(zhuǎn)鏈表的方法詳解

    C++數(shù)據(jù)結(jié)構(gòu)與算法之反轉(zhuǎn)鏈表的方法詳解

    這篇文章主要介紹了C++數(shù)據(jù)結(jié)構(gòu)與算法之反轉(zhuǎn)鏈表的方法,結(jié)合實(shí)例形式分析了C++反轉(zhuǎn)鏈表的原理、實(shí)現(xiàn)方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-08-08
  • C++ 類(lèi)和對(duì)象基礎(chǔ)篇

    C++ 類(lèi)和對(duì)象基礎(chǔ)篇

    類(lèi)是創(chuàng)建對(duì)象的模板,一個(gè)類(lèi)可以創(chuàng)建多個(gè)對(duì)象,每個(gè)對(duì)象都是類(lèi)類(lèi)型的一個(gè)變量;創(chuàng)建對(duì)象的過(guò)程也叫類(lèi)的實(shí)例化。每個(gè)對(duì)象都是類(lèi)的一個(gè)具體實(shí)例(Instance),擁有類(lèi)的成員變量和成員函數(shù)
    2020-01-01
  • C語(yǔ)言 動(dòng)態(tài)內(nèi)存開(kāi)辟常見(jiàn)問(wèn)題解決與分析流程

    C語(yǔ)言 動(dòng)態(tài)內(nèi)存開(kāi)辟常見(jiàn)問(wèn)題解決與分析流程

    動(dòng)態(tài)內(nèi)存是相對(duì)靜態(tài)內(nèi)存而言的。所謂動(dòng)態(tài)和靜態(tài)就是指內(nèi)存的分配方式。動(dòng)態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存
    2022-03-03
  • C語(yǔ)言圖書(shū)管理系統(tǒng)課程設(shè)計(jì)

    C語(yǔ)言圖書(shū)管理系統(tǒng)課程設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言圖書(shū)管理系統(tǒng)課程設(shè)計(jì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • c++11?實(shí)現(xiàn)枚舉值到枚舉名的轉(zhuǎn)換問(wèn)題

    c++11?實(shí)現(xiàn)枚舉值到枚舉名的轉(zhuǎn)換問(wèn)題

    這篇文章主要介紹了c++11?實(shí)現(xiàn)枚舉值到枚舉名的轉(zhuǎn)換,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • C++宏函數(shù)和內(nèi)聯(lián)函數(shù)的使用

    C++宏函數(shù)和內(nèi)聯(lián)函數(shù)的使用

    本文主要介紹了C++宏函數(shù)和內(nèi)聯(lián)函數(shù)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07

最新評(píng)論