排序演算法(2) 選擇排序 堆排序

2021-08-27 22:33:00 字數 3528 閱讀 5184

繼續上篇的

交換排序--氣泡排序&快速排序,本篇介紹選擇排序和堆排序

一、選擇排序

非常的簡單直觀,每次找出最小或者最大的值儲存起來,繼續找剩下的值儲存起來,直達最後乙個元素。

從arr[0]~arr[n]中找出最小的值,放在arr[0],此時arr[0]已經排好序

從arr[1]~arr[n]中找出最小的值,放在arr[1],

....從arr[i]~arr[n]中找出最小的值,放在arr[i],

找到i==n,排序完成

public void sort(int arr) 

} int temp = arr[i];

arr[i] = arr[index];

arr[index] = temp;

}}

二、堆排序堆排序(heap sort)是指利用堆這種資料結構所設計的一種排序演算法。

堆實際上就是一顆完全二叉樹。

堆分為大頂堆和小頂堆,又叫最大堆和最小堆。

大頂堆:父節點比左右節點的值都要大,用來做公升序。

小頂堆:父節點比左右節點的值都要小,用來做降序。

大頂堆和小頂堆是對稱關係,理解其中一種即可。本文將對大頂堆實現的公升序排序進行詳細說明。

堆排序時間複雜度

是o(n*lgn)。

1、基本思想

(1)、初始化堆:將數列a[0...n]構造成最大堆。

(2)、交換資料:將a[0]和a[n]交換,使a[n]是a[0...n]中的最大值;然後將a[0...n-1]重新調整為最大堆。 接著,將a[1]和a[n-1]交換,使a[n-1]是a[1...n-1]中的最大值;然後將a[1...n-2]重新調整為最大值。 依次類推,直到整個數列都是有序的。

2、陣列實現的二叉堆的性質

陣列和堆的對應關係如下:

陣列和堆有三個對應關係:

(1)、索引為i的左孩子的索引是 (2*i+1);

(2)、索引為i的左孩子的索引是 (2*i+2);

(3)、索引為i的父結點的索引是 floor((i-1)/2);即取整

比如30,索引為1,左孩子是40索引是3,右孩子是70索引是4。

3、例子演示

(1)、初始化堆

在堆排序演算法中,首先要將待排序的陣列轉化成二叉堆。

下面演示將陣列轉換為最大堆的步驟。

1.1 i=陣列長度/2-1=11/2-1,即i=4

上面是maxheap_down(a, 4, 10)調整過程。maxheap_down(a, 4, 10)的作用是將a[4...10]進行下調;a[4]的左孩子是a[9],右孩子是a[10]。調整時,選擇左右孩子中較大的乙個(即a[10])和a[4]交換。

上面是maxheap_down(a, 3, 10)調整過程。maxheap_down(a, 3, 10)的作用是將a[3...10]進行下調;a[3]的左孩子是a[7],右孩子是a[8]。調整時,選擇左右孩子中較大的乙個(即a[8])和a[4]交換。

上面是maxheap_down(a, 2, 10)調整過程。maxheap_down(a, 2, 10)的作用是將a[2...10]進行下調;a[2]的左孩子是a[5],右孩子是a[6]。調整時,選擇左右孩子中較大的乙個(即a[5])和a[2]交換。

上面是maxheap_down(a, 1, 10)調整過程。maxheap_down(a, 1, 10)的作用是將a[1...10]進行下調;a[1]的左孩子是a[3],右孩子是a[4]。調整時,選擇左右孩子中較大的乙個(即a[3])和a[1]交換。

交換之後,a[3]為30,它比它的右孩子a[8]要大,接著,再將它們交換。

上面是maxheap_down(a, 0, 10)調整過程。maxheap_down(a, 0, 10)的作用是將a[0...10]進行下調;a[0]的左孩子是a[1],右孩子是a[2]。調整時,選擇左右孩子中較大的乙個(即a[2])和a[0]交換。

交換之後,a[2]為20,它比它的左右孩子要大,選擇較大的孩子(即左孩子)和a[2]交換。

調整完畢,就得到了最大堆。此時,陣列也就變成了。

(2)、交換資料

在將陣列轉換成最大堆之後,接著要進行交換資料,從而使陣列成為乙個真正的有序陣列。

交換資料部分相對比較簡單,下面僅僅給出將最大值放在陣列末尾的示意圖。

上面是當n=10時,交換資料的示意圖。

當n=10時,首先交換a[0]和a[10],使得a[10]是a[0...10]之間的最大值;然後,調整a[0...9]使它稱為最大堆。交換之後:a[10]是有序的。

當n=9時, 首先交換a[0]和a[9],使得a[9]是a[0...9]之間的最大值;然後,調整a[0...8]使它稱為最大堆。交換之後:a[9...10]是有序的。

...依此類推,直到a[0...10]是有序的。

4、**

private void maxheapdown(int arr,int start,int end)

//3、交換節點

arr[parentindex] = arr[maxindex];

arr[maxindex] = parentvalue;

//4.繼續處理

parentindex = maxindex;

left = 2*parentindex+1; }}

public void heapsort(int arr)

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

}

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

選擇排序,依次找到資料集n n 1 n 2 中比它大 小的最大 最小者,最終達到全部資料有序。1 選擇排序 直接的依次找到資料集合n n 1 n 2.的最大 最小者形成排序,非常好理解。選擇排序可能是和氣泡排序一樣,最直觀能想到的排序方法。顯然選擇排序和氣泡排序一樣,無所謂最好 最壞 平均,選擇排序...

選擇排序演算法 堆排序

選擇排序演算法 堆排序 堆排序的結構思想就是 先構建 例如大頂堆 然後調整。構建堆,在構建過程中,用到3個變數,root,last,child,其中有兩步 比較左右孩子大小,然後將大的值與root比較並且 是否 交換位置。另外,構建完成之後,接著迴圈將最後乙個元素與第乙個元素交換位置,然後接著從第乙...

排序演算法之選擇排序 選擇排序 堆排序

直接選擇排序 如下 下面 是一次迴圈同時挑選出最大和最小數,並將其與左右交換 選擇排序 void selectionsort int a,int len swap a min a left 如果最大數的下標在為left,證明要交換的最大數已經被 換到min小標所表示的位置,只需要將right和min...