資料結構 堆排序

2021-07-27 15:44:47 字數 2925 閱讀 3445

說到堆排序,它的思想**於優先佇列,我們首先來說一下什麼是優先佇列。

一、優先佇列

1.優先佇列的定義:優先佇列是允許以下兩種操作的資料結構:insert(插入)相當於入隊、deletemin(刪除最小元)。

2.使用資料結構:相比於單鏈表和二叉排序樹的缺點,我們使用二叉堆這種結構,它有兩個重要的性質就是:

結構性——完全二叉樹

堆序行——小頂堆或大頂堆

3.實現:因為完全二叉樹有規律,我們使用陣列實現,對於陣列中任一位置i上的元素,其左兒子為2*i,右兒子為 2*i+1,父親為  i/2,(下標從1開始

)。4.思想:

插入:將乙個元素x插入到堆中後,我們在下乙個位置建立乙個空穴,如果x不破壞堆結構,那麼insert完成。否則,我們把該空穴的父親節點移動到該空穴,直到x被放入到空穴為止。我們把這種操作稱為上濾。

刪除最小元:刪除最小元後產生乙個空穴,堆中最後乙個元素x必須移動到堆中的某個地方,如果x可以被放到空穴,那麼delelemin完成,否則,將空穴較小的兒子移入空穴,直至x被移動到正確的位置。我們把這種操作稱為下濾。

5.實現:

宣告:

#include #include #define elementtype int

/*優先佇列陣列實現

*/typedef struct heapstrcut //堆結構

*priorityqueue;

priorityqueue initialize(int maxelements); //建立初始化優先佇列

void insert(elementtype x, priorityqueue h);//插入

elementtype deletemin(priorityqueue h); //刪除最小節點

int isempty(priorityqueue h); //判斷優先佇列是否為空

int isfull(priorityqueue h); //判斷優先佇列是否已滿

實現:

/*

建立初始化優先佇列

小頂堆,最小元在根節點

*/priorityqueue initialize(int maxelements)

//申請儲存資料陣列elements空間

h->elements = (elementtype *)malloc(sizeof(elementtype)*maxelements);

if (h->elements == null)

//初始化優先佇列

h->capcity = maxelements;

h->size = 0;}/*

插入,交換而實施的賦值語句為d+1

*/void insert(elementtype x, priorityqueue h)

for (i = ++h->size; h->elements[i / 2] > x; i /= 2)

h->elements[i] = h->elements[i / 2];

h->elements[i] = x;

}//我的插入寫法,交換而實施的賦值語句為3d

void insert2(elementtype x, priorityqueue h)

h->elements[++h->size] = x;

tmp = h->elements[h->size];

for (i = h->size; i / 2 > 0; i /= 2)

if (h->elements[i / 2] > h->elements[i])

h->elements[i] = h->elements[i / 2];

else

break;

h->elements[i] = tmp;}/*

刪除最小節點

*/elementtype deletemin(priorityqueue h)

minelement = h->elements[1];

lastelement = h->elements[h->size--];

for (i = 1; i * 2 <= h->size; i = child)

h->elements[i] = lastelement;

return minelement;}/*

判斷優先佇列是否為空

*/int isempty(priorityqueue h)

/*判斷優先佇列是否已滿

*/int isfull(priorityqueue h)

/*顯示優先佇列元素

*/void show(priorityqueue h)

int main()

} return 0;

}

二、堆排序

1.思路:將要排序的資料構建成小頂堆,交換根與最後節點,下濾重新構建堆。

2.實現:

陣列實現,下標從0開始:

/*

堆排序思路:堆排序分為構建堆、刪除最值、調整堆即上濾下濾操作。

方法:使用陣列代替adt(抽象資料型別)的方式實現初始堆陣列下標從零開始。

總結:時間複雜度為n*logn。

*///上濾操作

void percdown(elementtype a, int i, int n) //i為父節點下標

a[i] = tmp;

}//堆排序

void heapsort(elementtype a, int n)

}

3.分析:堆排序的時間複雜度為o(longn),構建n個資料的二叉堆需要o(n)時間,deletemin需要o(nlogn)時間。

堆排序是乙個穩定的排序,無論起始的資料序列是如何的。

資料結構 堆排序 堆排序 Heap Sort

堆排序是一種選擇排序,其時間複雜度為o nlogn 堆的定義 n個元素的序列當且僅當滿足下列關係之一時,稱之為堆。情形1 ki k2i 且ki k2i 1 最小化堆或小頂堆 情形2 ki k2i 且ki k2i 1 最大化堆或大頂堆 其中i 1,2,n 2向下取整 若將和此序列對應的一維陣列 即以一...

資料結構 堆排序

include include void maxheapify int a,int length,int i void buildmaxheapify int a,int length void heapsort int a,int length void main void printf heap...

資料結構 堆排序

1 堆排序的時間複雜度與歸併排序相同,o nlogn 堆排序的優勢在與他只需要固定數量的額外空間,堆排序要比空間複雜性為o n 的歸併排序稍微慢一些,但是比空間複雜性為o 1 的歸併排序要快。2 對序列 26,5,77,1,61,11,59,15,48,19 進行堆排序 過程 調整最大堆 二叉堆 v...