選擇排序 堆排序

2021-08-25 22:59:47 字數 2783 閱讀 5257

* **實現

* 結語

* 背景

近期溫習演算法,看到自己塵封許久的演算法專欄,也應該增加新的成員了。今天給大家分享的是堆排序,選擇排序的一種演算法。

堆排序是利用對這種資料結構而設計的一種排序演算法,他的最壞,最好,平均時間複雜度均為o(nlogn),同時也是不穩定的排序。

* 知識儲備

堆是具有如下性質的完全二叉樹:每個節點的內容都大於或等於其左右孩子節點的值,為大頂堆;或者每個節點的值都小於等於其左右孩子節點的值成為小頂堆。如下圖:(來自社會)

對於堆的資料結構我們的儲存方式可以採用線性儲存,也可以採用鏈式儲存,這裡我們用線性儲存的陣列來存放他。

如果用陣列的儲存,我們來描述一下他的堆的定義:

大頂堆:arr[i]>=arr[2*i+1] && arr[i]>=arr[2*i+1]

小頂堆:arr[i]<=arr[2*i+1] && arr[i]<=arr[2*i+1]

* 堆排序的步驟

首先規定,我們排序的結果是公升序,那我們就要構造大頂堆,這時根節點便是最大值,此時我們用最後一層的葉子節點與其交換,此時末尾的便是最大值,然後將剩餘的n-1個節點重新構造成乙個最大堆,然後根節點便成為n-1個節點的最大值,如此反覆,便可以得到乙個公升序的序列了。

這裡我們說一下建堆的過程,假定無序序列為:4,6,8,5,9,轉換為二叉樹的結構為:

1. 我們從最後一層的葉子節點(從右往左)的父節點開始,使其滿足最大堆的性質,那麼我們先比較的是根節點為6的節點和其孩子節點是否滿足性質。首先比較其左右孩子節點,5和9,發現9大,之後比較根節點6和右孩子9,發現9依然大,我們讓9佔到根節點的位置,那麼6呢?因為9沒有孩子節點了,所以6可以直接佔到右孩子的位置。至此,這三個節點變滿足了最大堆的性質了。構建過程如下:

2.最後一層的葉子節點的父節點我們已經排完了,繼續上一層葉子節點(從右到左)的父節點為4,我們構建最大堆,這是比較父節點為4的孩子節點9,8發現9大,於是我們比較根節點4和9,依然是9大,這時9便坐到根節點的位置,那麼原來的4呢?直接和左孩子交換嗎?不是的,我們可以存在臨時變數tmp裡,這是我們讓左孩子成為父節點,比較其孩子節點,發現6大,這是我們比較tmp和6,發現6比4大,於是原來右孩子6現在成為父節點,而4最後坐到了右孩子的位置,至此我們構建成大頂堆。構建過程如下:

將堆頂元素與末尾元素進行交換,使末尾元素最大。然後繼續調整堆,再將堆頂元素與末尾元素交換,得到第二大元素。如此反覆進行交換、重建、交換。具體重建堆的步驟不再贅述,請參考3.1

最後的調整結果為:

* **實現

如果這裡沒有**,我認為我便是在耍流氓。下面是自己寫的**,當然之前自己也手寫過,發現還是有必要執行一下,我們的思想和機器的思想有一些差別的。

/**

* 建堆過程(最小堆)-lyw--2023年8月25日23:40:52

*/public

void

sfit(int arr,int k,int n)

if (tmp break;

}else

}arr[i]=tmp;

}

/**

* 交換

*@param

*@param

*/public

void

swap(int arrtmp,int x,int y)

int arr=;

/** * 堆排序全過程--劉雅雯--2023年8月26日08:10:23

*/@test

public

void

heapsort()

//迴圈一次構建乙個最小堆

for (int i=arr.length-1;i>0;i--)

//列印結果

system.out.print("堆排序的結果:");

for (int i=0;i", ");}}

* 結語

真的做起來也不是很困難,更多的是我們想不想話時間去做下去,我想這也是高階開發程式設計師必備的技能吧。

排序 選擇排序 選擇排序 堆排序

寫在前面 上傳github交換排序選擇排序 堆排序 選擇排序 顧名思義,我們就可以猜到,它是原則合適的元素放到合適的位置 從圖中,我們可以得到 1.用第乙個元素,和其他所有的元素進行比較,找出最小的,然後進行交換 2.然後進行,資料的遞增 3.直到資料全部有序 void selectsort int...

選擇排序 堆排序

選擇排序 selection sort 是一種簡單直觀的排序演算法。它的工作原理是每一次從待排序的資料元素中選出最小 或最大 的乙個元素,存放在序列的起始位置,直到全部待排序的資料元素排完。選擇排序是不穩定的排序方法 比如序列 5,5,3 第一次就將第乙個 5 與 3 交換,導致第乙個5挪動到第二個...

選擇排序 堆排序

堆排序 堆排序分為兩個過程 1 將原來無序的數列,轉化成堆序列 建初識堆的過程 2 輸出堆頂元素並調整建新堆的過程 資料結構偽 typeof sqlist heaptype void heapadjuisti heaptype h,int s int m for i h.length i 1 i c...