首先來看一下簡單選擇排序:
思想:在未排序的序列中選出最小的元素和當前序列的第乙個元素互換,然後在剩下的元素中選出乙個與剩下元素的第乙個位置互換,依次交換,最後就會形成乙個從小到大的已排序序列。
void ******selectsort(int *a, int n)
}//迴圈完一遍 已找到最小元素
//交換
a[i] = a[i]^a[min];
a[min] = a[min]^a[i];
a[i] = a[i]^a[min];
}}
簡單選擇排序是給每個位置選擇當前元素最小的,比如給第乙個位置選擇最小的,在剩餘元素裡面給第二個元素選擇第二小的,依次類推,直到第n-1個元素,第n個 元素不用選擇了,因為只剩下它乙個最大的元素了。那麼,在一趟選擇,如果當前元素比乙個元素小,而更小的元素又出現在乙個和當前元素相等的元素後面,那麼 交換後穩定性就被破壞了。比較拗口,舉個例子,序列5 8 5 2 9, 我們知道第一遍選擇第1個元素5會和2交換,那麼原序列中2個5的相對前後順序就被破壞了,所以選擇排序是乙個不穩定的排序演算法。仔細觀察可以發現,簡單選擇排序的瓶頸部分在於找到最小元素的過程和不停的交換過程。每次取最小的元素這乙個步驟,我們能夠聯想到「最小堆」這個資料結構,使用這個資料結構可以幫我們找到最小元素。不知道什麼是最小堆?看這裡。
堆排序:
堆排序(heapsort)是由2023年計算機先驅獎獲得者、史丹福大學電腦科學系教授 羅伯特·弗洛伊德(robert w.floyd) 和 威廉士(j.williams) 在2023年共同提出的。堆排序是指利用堆這種資料結構所設計的一種排序演算法,一般情況下堆排序是用陣列的方式來實現。
思想:
利用最小堆(或最大堆)輸出堆頂元素,即最小值(或最大值),將剩餘的元素重新生成最小堆(或最大堆),繼續輸出堆頂元素,重複此過程,直到全部元素都已輸出,得到的輸出元素序列即為有序序列。
一種實現方法是:額外開闢乙個陣列,然後每次輸出最小堆的堆頂元素儲存到該陣列中,然後重新調整為最小堆,然後輸出堆頂元素,如此迴圈,直到最小堆無元素,最後把該陣列元素複製回原來的陣列。但是這種方式,需要額外的空間消耗。我們一般使用更巧妙一點的方式。
另一種:將待排序列調整成最大堆,然後每次將堆頂元素(最大值)和當前堆的最後乙個元素交換,把除去堆末尾已經交換過的值以外的元素重新調整為最大堆,然後如此迴圈,最後就會形成從小到大的已排序序列。
需要注意的:因為這裡的元素是從0開始存放的,所以和最大堆的**不同,對於第i個結點,其左孩子的編號是2i+1,右孩子編號是2i+2,父親結點的編號是|(i-1)/2|。
void percdownheap(int *a, int p, int n)else
break;}}
a[parent] = top;
}void heap_sort(int *a, int n)
for (int i=n-1; i>0; i--)
}
我們知道堆的結構是節點i的孩子為2*i和2*i+1節點,大頂堆要求父節點大於等於其2個子節點,小頂堆要求父節點小於等於其2個子節點。在乙個長為n 的序列,堆排序的過程是從第n/2開始和其子節點共3個值選擇最大(大頂堆)或者最小(小頂堆),這3個元素之間的選擇當然不會破壞穩定性。但當為n /2-1, n/2-2, ...1這些個父節點擊擇元素時,就會破壞穩定性。有可能第n/2個父節點交換把後面乙個元素交換過去了,而第n/2-1個父節點把後面乙個相同的元素沒 有交換,那麼這2個相同的元素之間的穩定性就被破壞了。所以,堆排序是不穩定的排序演算法。
排序演算法 二 選擇排序
之前給大家分享了排序演算法裡面比較簡單的氣泡排序,今天來分享一下選擇排序的演算法 選擇排序的思想 1.以公升序為例 在一組數中選出最大的數放到第乙個位置,或者選出最小的數放到最後乙個位置,2.在選取剩餘元素的最大數放到第二個位置,或選出剩餘元素中的最小值放到倒數第二哥位置,3.依次往下選取,直到遍歷...
排序演算法 二 選擇排序
演算法實現 selectsort.c include void selectsort int arr,int len if min i for k 0 k演算法思想 保證將要成為有序範圍內的那個位置的值是無序裡的最小值。ex 從陣列選出最小的放在第乙個位置上,在從剩餘陣列選出最小放在第二個位置上,以...
排序演算法(二) 選擇排序
選擇排序是一種簡單的直觀的排序演算法,基本原理如下 對於給定的一組記錄,經過一輪比較後得到最小的記錄,然後將該記錄的位置與第乙個記錄的位置交換 接著對不包括第乙個記錄以外的其他記錄進行第二次比較,得到最小記錄並與第二個位置記錄交換,重複該過程,直到進行比較的記錄只剩下乙個為止 從簡單排序的過程來看,...