1. 程式人生 > >資料結構之堆排序C語言實現

資料結構之堆排序C語言實現

堆排序:
時間複雜度:O(nlogn)
穩定性:不穩定
實現原理:將待排序的序列構造成一個大頂堆(或小頂堆) 整個序列的最大值就是堆頂的根節點,將它移走 (就是將其與對陣列的末尾元素交換,此時末尾元素就是最大值)。然後將剩餘的n-1個序列重新
構成一個堆,這樣就會的到n個元素中 的最大值如此反覆執行,得到一個有序序列。
大頂堆:根節點是最大者
小頂堆:根節點是最小者
大頂堆滿足條件:K[i]>=K[2*i+1] 且K[i]>=K[2*i+2] (0<=i<=n/2-1) K[i]為堆頂 K[2*i+1]為堆頂左子樹 K[2*i+2]為堆頂的右子樹
小頂堆滿足條件:K[i]<=K[2*i+1] 且K[i]<=K[2*i+2] (0<=i<=n/2-1)
實現步驟:
1.先將初始檔案R[1..n]建成一個大頂堆,此堆為初始的無序區
2. 再將關鍵字最大的記錄R

1和無序區的最後一個記錄R[n]交換,
3. 由此得到新的無序區R[1..n-1]和有序區R[n],且滿足R[1..n-1].keys≤R[n].key
4. 由於交換後新的根R[1]可能違反堆性質,故應將當前無序區R[1..n-1]調整為堆。
5.然後再次將R[1..n-1]中關鍵字最大的記錄R[1]和該區間的最後一個記錄R[n-1]交換,
6.由此得到新的無序區R[1..n-2]和有序區R[n-1..n],且仍滿足關係R[1..n- 2].keys≤R[n-1..n].keys,
7.同樣要將R[1..n-2]調整為堆。
…… 直到無序區只有一個元素為止
大頂堆排構建的基本操作:
初始化操作:將R[1..n]構造為初始堆;
每一趟排序的基本操作:將當前無序區的堆頂記錄R[1]和該區間的最後一個記錄交換,然後將新的無序區調整為堆(亦稱重建堆)。
小頂堆的構建與大頂堆相反

//程式碼實現:    
#include <stdio.h>
#inlude <stdlib.h>
/****************************************************************************
  功能:實現大頂堆的構建
  輸入引數: int i:起始操作的元素的下標 
             2*i+1:表示i的左子樹下標
             2*i+2:表示i的右子樹小標
             int len:需要構建大頂堆的陣列的長度
返回值:無
*******************************************************************************/
void HeapAdjust(int a[],int i,int len) { while( 2*i+1 < len ) { int maxindex=2*i+1; //將最大的下標初始化為s的子樹下標 if(2*i+2<len) { //比較左子樹和右子樹,記錄最大值的Index if(a[2*i+1]<a[2*i+2]) { maxindex=2*i+2; } } if(a[i]<a[maxindex]) { //交換i與maxindex的資料 a[i]=a[i]^a[maxindex]; a[maxindex]=a[i]^a[maxindex]; a[i]=a[i]^a[maxindex]; //堆被破壞,需重新調整 i=maxindex; } else { //比較左右孩子均大則堆未破壞,不再需要調整 break; } } return; } //堆排序 void HeapSort(int a[],int len) { int i=0; //將a[0,Len-1]建成大頂堆 for(i=len/2-1;i>=0;i--) { //呼叫構建大頂堆函式 HeapAdjust(a,i,len); } //只需做n-1趟排序 for(i=len-1;i>0;i--) { //將字最大的記錄R[1](即堆頂)和無序區的最後一個記錄R[n]交換 a[0]=a[0]^a[i]; a[i]=a[0]^a[i]; a[0]=a[0]^a[i]; //將a[0..i]重新調整為大頂堆 HeapAdjust(a,0,i); } return; } int main(int argc, char const *argv[]) { int a[]={45,569,213,123,12,56,45,56,10}; HeapSort(a,9); int i; for(i=0;i<9;i++) { printf("%d ",a[i]); } printf("\n"); return 0; }

編譯執行結果正確,如果有錯誤,歡迎指出。

相關推薦

資料結構排序C語言實現

堆排序: 時間複雜度:O(nlogn) 穩定性:不穩定 實現原理:將待排序的序列構造成一個大頂堆(或小頂堆) 整個序列的最大值就是堆頂的根節點,將它移走 (就是將其與對陣列的末尾元素交換,此時末尾元素就是最大值)。然後將剩餘的n-1個序列重新 構成

資料結構連結串列C語言實現以及使用場景分析

連結串列是資料結構中比較基礎也是比較重要的型別之一,那麼有了陣列,為什麼我們還需要連結串列呢!或者說設計連結串列這種資料結構的初衷在哪裡? 這是因為,在我們使用陣列的時候,需要預先設定目標群體的個數,也即陣列容量的大小,然而實時情況下我們目標的個數我們是不確定的,因此我們總是要把陣列的容量設定的

資料結構陣列(C語言實現

陣列是大家很熟悉的一種資料型別,而且在我們的程式設計中也應用非常廣泛。這裡以抽象資料型別的形式討論陣列的定義和實現。 一、陣列的定義 假設n維陣列中含有第i維的長度為b(i),則陣列的總長度為b(0) *b(1)*...*b(n-1),每個元素都受著n個

軟考:資料結構基礎——迴圈佇列C語言實現

  迴圈佇列得實現: 1.     在入隊和出隊時,我們通過      q->rear = (q->rear +1)%MAX_LENTH 來實現迴圈入隊     q

簡單資料結構 vector 棧(C++ vector 實現)

/* ============================================================================ Name : stack_array.cpp Author : ntsk13 [em

資料結構鏈式表的實現--單鏈表(C語言)

學習參考: 嚴蔚敏: 《資料結構-C語言版》 基本操作: 單鏈表的建立 新增結點(頭插法) 新增結點(尾插法) 單鏈表的輸出 單鏈表的修改 單鏈表的插入 單鏈表的刪除 單鏈表按

資料結構鏈式表的實現--單向迴圈連結串列(C語言)

 學習參考: 嚴蔚敏: 《資料結構-C語言版》 單向迴圈連結串列的基本操作 單向迴圈連結串列的建立 單向迴圈連結串列新增結點(頭插法) 單向迴圈連結串列新增結點(尾插法) 單向迴圈連結串列

資料結構與演算法順序表C語言實現

順序表等相關概念請自行查閱資料,這裡主要是實現。 注: 1.順序表C語言實現; 2.按較簡單的方式實現,主要幫助理解,可在此基礎上修改,更加完善; 3.提供幾個簡單函式,可自行新增功能; 4.可用C++封裝,得知STL中vector原理。    順序表容量。 #def

資料結構與演算法分析c語言描述(Mark Allen)--佇列ADT連結串列實現

佇列ADT連結串列實現 使用連結串列儲存 操作集合 入隊 出隊 初始化 返回隊前元素 列印 #include <stdio.h> #includ

資料結構與演算法分析c語言描述(Mark Allen)--迴圈佇列ADT陣列實現

迴圈佇列ADT陣列實現 使用陣列儲存 操作集合 入隊 出隊 清空 初始化 返回隊前元素 列印 重點注意! 對於一個迴圈佇列 front == rear時候佇列

資料結構中,幾種樹的結構表示方法(C語言實現

//***************************************** //樹的多種結構定義 //***************************************** #define MAX_TREE_SIZE 100 typedef int TempType;

C++資料結構鏈式佇列模版實現

鏈佇列的儲存結構   將對頭指標front指向鏈佇列的頭結點(頭節點為空,不存資料),隊尾指標rear指向終端結點。元素從隊尾進入,隊首出列。 元素為空時,隊尾指標指向隊頭指標。 鏈式佇列模版實現: 功能: 1 建立 2 遍歷 4 入隊,出隊 5 獲取

資料結構與演算法分析c語言描述(Mark Allen)--線性錶鏈表方法實現

線性表--連結串列實現 標頭檔案 #define ElementType int #define INF INT_MAX #ifndef _List_H struct Node; typedef struct Node *PtrToNode; typedef PtrToN

資料結構與演算法分析c語言描述(Mark Allen)--多項式ADT陣列實現

多項式ADT陣列實現 使用陣列進行儲存 操作集合 乘法 加法 標頭檔案 //cpp head file PloynomialADTarray.h #define MaxDegree 1000 typedef struct Pol { int C

資料結構與演算法分析c語言描述(Mark Allen)--多項式ADT連結串列實現

多項式ADT連結串列實現 使用連結串列結構儲存 操作集合 多項式加法 多項式乘法 多項式的顯示 標頭檔案 //標頭檔案 typedef struct Node *PtrToNode; struct Node { int Cofficient

資料結構與演算法分析c語言描述(Mark Allen)--棧ADT陣列實現

棧ADT陣列實現 使用陣列儲存 操作集合 入棧push 出棧pop 清空 初始化 返回棧頂元素 得到一個隨機棧 列印整個棧 #include <stdio.h> #include <stdlib.h> #include <

資料結構與演算法(C語言) | 二叉排序

二叉排序樹的定義—— 二叉排序樹 ( Binary Sort Tree) 或者為空;或者是具有如下特性的二叉樹: (1)若根的左子樹不空,則左子樹上所有結點的關鍵字均小於根結點的關鍵字; (2)若

C語言實現(摘自資料結構與演算法分析 C語言描述)

一、概述: 棧(stack)是限制插入和刪除只能在一個位置上進行的表,該位置是表的末端,叫做棧的頂(top)。對棧的基本操作有Push(進棧)和Pop(出棧),前者相當於插入,後者則是刪除最後插入的元素。 棧有時又叫做LIFO(後進先出)表。在圖1中描述的模型只象徵著Pus

資料結構(Heap)的實現

  堆資料結構是一種陣列物件,它可以被視為一棵完全二叉樹結構,所以堆也叫做二叉堆。二叉堆滿足二個特性:  1.父結點的鍵值總是大於或等於(小於或等於)任何一個子節點的鍵值。  2.每個結點的左子樹和右子樹都是一個二叉堆(都是最大堆或最小堆)。  當父結點的鍵值總是大於或等於任

快速排序(分而治策略及C語言實現

提出的問題 分而治之的策略 重要的分而治之演算法 快速排序 問題 要在一個長為x,寬為y的長方形中畫出均勻且大小相等的正方形 那麼正方形的邊長為多少 (1)可以看出正方形的邊長需要是x和y的最大公約數 如何求最大公約數?