排序演算法一 堆排序

2021-07-29 07:48:12 字數 1716 閱讀 7727

一、演算法介紹

堆排序(heapsort)是指利用堆積樹(堆)這種

資料結構

所設計的一種

排序演算法

,它是選擇排序的一種。可以利用

陣列的特點快速定位指定索引的元素。堆分為大根堆和小根堆,是

完全二叉樹

。大根堆的要求是每個節點的值都不大於其父節點的值,即

a[parent[i]] >= a[i]。

在陣列的非降序排序中,需要使用的就是大根堆,因為根據大根堆的要求可知,最大的值一定在堆頂

。二、演算法說明

本文以大根堆為例來說明,假設要排序的陣列為a,陣列大小為n

i的兒子節點為2*i+1 , 2*i+2

演算法主要分為兩個部分:

1.建立大根堆,然而建立的大根堆只能保證本身的特性(

每個節點的值都不大於其父節點的值

),並沒有辦法保證自身按照層次遍歷的元素是有序的。

從a[n/2-1](從結尾開始第乙個有兒子的節點)到根節點開始調節陣列(完全二叉樹),形成乙個大根堆

2.大根堆能保證根節點一定是整個樹當中最大的,因此排序就可以這麼來安排:

將a[0]與a[n-1]進行交換,然後將a[0]到a[n-2]重新進行關於大根堆的調整

將a[0]與a[n-2]進行交換,然後將a[0]到a[n-3]重新進行關於大根堆的調整

。。。重複這個過程

第一次交換的過程中,取出陣列第一大的數放在最後

第二次交換的過程中,取出陣列第二大的數放在最後

。。。迴圈之後就完成了排序的過程

三、複雜度

空間複雜度

因為堆排序是就地排序,空間複雜度為常數:o(1)

四、示例**

如果還是不怎麼懂的同學,**run一下 通過輸出的樹狀結構更容易理解

public class stacksort ;

sort(a);

}//堆排需方法

public static void sort(int a)

system.out.println("---------------------------------------");

for (int i = n - 2; i >= 0; i--)

display(a, "after sort : ");

}/**

* 調整堆的方法

* 每次呼叫的目的就是調節傳入的a[i]值 使得它在整個堆中處於正確的位置

* @param a 要調整的陣列,即堆

* @param i 調整的根節點,即起始位置

* @param n 要調整的終止位置

*/public static void adjust(int a, int i, int n)

a[(j - 1) / 2] = temp;//將根節點賦值給最後乙個空出來的節點

}//以圖形形式表現二叉樹

public static void display(int a, string str)

++count;

}system.out.printf("%3s",a[i]);

num = (int)math.pow(2,h-count+1);

for(int j = 0 ; j < num-1 ; j++)

}system.out.print("\n");

}}

**內容來自

整理而成

時間複雜度

演算法系列之一 堆排序

前序 二叉 堆資料結構是一種陣列物件,它可以被視為一棵完全二叉樹。樹中每個節點與陣列中存放該節點值的那個元素對應。樹的每一層都是填滿的,最後一層除外。樹的根為a 1 在這裡是從1開始的,也可以從0開始 給定了某個節點的下標i,其父節點為i 2,左二子為2 i,右兒子為2 i 1。二叉堆滿足二個特性 ...

常用排序演算法總結7一一堆排序

在了解堆排序之前,我們有必要清楚 什麼是堆呢?堆 英語 heap 是電腦科學中一類特殊的資料結構的統稱。堆通常是乙個可以被看做一棵樹的陣列物件。在佇列中,排程程式反覆提取佇列中第乙個作業並執行,因為實際情況中某些時間較短的任務將等待很長時間才能結束,或者某些不短小,但具有重要性的作業,同樣應當具有優...

演算法 堆排序(堆)

使用情形 插入乙個數 求集合當中的最小值 刪除最小值 刪除任意乙個元素 修改任意乙個元素 用一維陣列儲存二叉樹,左兒子在陣列中為根節點在陣列中的位置的2倍,右兒子在陣列中為根節點在陣列中的位置的二倍加一。求當前堆的最小值 void down int u 輸入乙個長度為n的整數數列,從小到大輸出前m小...