www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 公眾號精選 > C語言編程
[導(dǎo)讀]01—認(rèn)識堆排序堆排序是利用堆這種數(shù)據(jù)結(jié)構(gòu)而設(shè)計(jì)的一種排序算法,它的最好、最好、平均復(fù)雜度都為nlog(n),它也是不穩(wěn)定排序算法。堆是具有以下性質(zhì)的完全二叉樹:每個結(jié)點(diǎn)的值都大于等于其左右孩子結(jié)點(diǎn)的值,稱為最大堆。每個結(jié)點(diǎn)的值都小于等于其左右孩子結(jié)點(diǎn)的值,稱為最小堆。如下圖:0...


01

認(rèn)識堆排序


堆排序是利用堆這種數(shù)據(jù)結(jié)構(gòu)而設(shè)計(jì)的一種排序算法,它的最好、最好、平均復(fù)雜度都為nlog(n),它也是不穩(wěn)定排序算法。

堆是具有以下性質(zhì)的完全二叉樹:每個結(jié)點(diǎn)的值都大于等于其左右孩子結(jié)點(diǎn)的值,稱為最大堆。每個結(jié)點(diǎn)的值都小于等于其左右孩子結(jié)點(diǎn)的值,稱為最小堆。如下圖:


02

堆排序思想及其實(shí)現(xiàn)

無論網(wǎng)上還是書本上介紹堆排序的實(shí)現(xiàn)都是用數(shù)組實(shí)現(xiàn),但是今天我們用二叉樹的思想實(shí)現(xiàn)堆排序。

堆排序思想:將待排序列構(gòu)造成一個最小堆,此時整個序列的最小值就是堆的根結(jié)點(diǎn),新結(jié)點(diǎn)插入都將從左子樹開始填充到右子樹,新插入的結(jié)點(diǎn)先成為葉子結(jié)點(diǎn),再從新插入的結(jié)點(diǎn)開始往上遍歷,如果父結(jié)點(diǎn)的值比該結(jié)點(diǎn)的值大則交換數(shù)據(jù),直到父結(jié)點(diǎn)的值比其結(jié)點(diǎn)的值小為止。重復(fù)對n個值進(jìn)行操作,依次取出根結(jié)點(diǎn),則整個序列是有序的。定義堆結(jié)點(diǎn)和聲明操作函數(shù):

#define?INT_NAN (0xFFFFFFFF - 1)

typedef?struct?tree_node{
????struct?tree_node?*left;
????struct?tree_node?*right;
????int?data;
????int?height;
}tree_node_t;
extern?tree_node_t *new_tree_node(int?data);
extern?int?heap_sort_get_node(tree_node_t?**root);
extern?void?heap_sort_insert_node(tree_node_t?**root, int?data);
extern?void?destroy_heap_tree(tree_node_t?*root);
extern?void?tree_print(tree_node_t?*root);

堆結(jié)點(diǎn)里的高度并不是二叉樹的高度,由于二叉堆是完全二叉樹,因此只要結(jié)點(diǎn)的左右子樹不是滿二叉樹且高度不一致時,就可繼續(xù)插入結(jié)點(diǎn),直到左右子樹都是滿二叉樹且高度一致,再往下一層插入結(jié)點(diǎn)。新建堆結(jié)點(diǎn)函數(shù)實(shí)現(xiàn):


tree_node_t?*new_tree_node(int?data){
????tree_node_t?*node = malloc(sizeof(tree_node_t));
????if(node == NULL){
????????return?NULL;
????}
????node->data = data;
????node->left = NULL;
????node->right = NULL;
????node->height = 1;

????return?node;
}

釋放堆結(jié)點(diǎn)函數(shù)實(shí)現(xiàn):
if(node == NULL){
????????return;
????}
????node->left = NULL;
????node->right = NULL;
????free(node);
}

二叉堆插入結(jié)點(diǎn)步驟:將新插入的結(jié)點(diǎn)按照層級結(jié)構(gòu)成為葉子結(jié)點(diǎn),再從新結(jié)點(diǎn)往根結(jié)點(diǎn)遍歷,如果其父結(jié)點(diǎn)的值比該結(jié)點(diǎn)的值小,則交換數(shù)據(jù),這個過程稱為上濾。新插入的結(jié)點(diǎn)不斷上濾,直到父結(jié)點(diǎn)的值比其結(jié)點(diǎn)的值小則停止上濾。如圖所示:

交換數(shù)據(jù)函數(shù)實(shí)現(xiàn):


void?swap(int?*a, int?*b){
????int?c = *a;
????*a = *b;
????*b = c;
}

上濾操作函數(shù)實(shí)現(xiàn):
tree_node_t *up_filter(tree_node_t *root){
????if(root == NULL){
????????return?NULL;
????}
????if(root->left != NULL?
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉
關(guān)閉