說到堆排序,它的思想**於優先佇列,我們首先來說一下什麼是優先佇列。
一、優先佇列
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...