這裡介紹兩種選擇排序演算法:直接選擇排序和堆排序
選擇排序基本思想:每一趟從待排序的序列中選出關鍵字最小(最大)的元素,順序放在已排好序的子串行的最後,直到全部元素排序完畢。
1、直接選擇排序
基本原理:每一次從待排序序列中選取最小的元素順序放在以排好的序列後面,例如序列r,先從r中選擇最小的元素,將之與r[0]交換,使這個最小值在序列最前端,然後再在剩餘的n-1個元素中選取最小的元素與r[1]交換,使之在序列的第二個位置,依此迴圈,直到最後排序完畢,n個元素的序列共需要進行n-1次比較選擇就可以得到排序後的序列。直接選擇排序屬於就地排序,但是是不穩定的例如(2,2,1)。
動畫:2、堆排序
若將此序列所儲存的向量r[1..n]看做是一棵完全二叉樹的儲存結構,則堆實質上是滿足如下性質的完全二叉樹:樹中任一非葉結點的關鍵字均不大於(或不小於)其左右孩子(若存在)結點的關鍵字。
【例】關鍵字序列(10,15,56,25,30,70)和(70,56,30,25,15,10)分別滿足堆性質(1)和(2),故它們均是堆,其對應的完全二叉樹分別如小根堆示例和大根堆示例所示。
堆排序利用了大根堆(或小根堆)堆頂記錄的關鍵字最大(或最小)這一特徵,使得在當前無序區中選取最大(或最小)關鍵字的記錄變得簡單。
大根堆排序基本原理和過程:利用堆的結構特徵,將堆頂最大元素和堆尾元素交換,使之處於堆尾,然後對堆進行調整,使剩餘的元素中最大的又在堆頂,從而與堆尾倒數第爾個數交換,迴圈,就能將堆重的元素從大到小依次從堆尾排到堆頂;前提是要初始化堆,使資料按堆的結構排列;
動畫:下面簡單說明一下大根堆排序實現**:這裡新建了3個函式:
void heapinit(vector &vec);
void heapsock(vector &vec);
void heapadjust(vector &vec,int n,int m);
分別用來進行堆初始化,堆排序,堆調整;
初始資料要通過堆初始化,使資料結構符合大根堆的結構模式。然後對堆進行排序,每選擇一次堆元素(堆頂元素排序)後,需要重新對剩餘資料進行調整,使之依然符合堆結構。
下面為兩種排序方法的**實現:
#include
#include
using
namespace
std;
const
int n = 20; //定義常量 也可以這樣 #define n 20
void disp(vector
vec); //輸出函式,
void selectsort(vector
&vec); //直接選擇演算法
void selectsort2(vector
&vec); //直接選擇演算法2(改進)
void heapinit(vector
&vec); //堆初始
void heapsock(vector
&vec); //排序
void heapadjust(vector
&vec,int n,int m); //堆調整
int main()
; for(int i = 0; i < n; i++)
vec1[i] = a[i];
vec2 = vec1;
vec2[0] = 0; //這裡為了方便,堆排序從vec2[1]開始
disp(vec1);
disp(vec2);
selectsort2(vec1); //直接選擇排序
heapsock(vec2); //堆排序
disp(vec1);
disp(vec2);
return0;}
void disp(vector
vec) //輸出函式
void selectsort(vector
&vec)}}
}//另一種實現方法,不用每次都對值進行交換,只需記錄位置資訊即可
void selectsort2(vector
&vec)
if(pos != i)
}}void heapinit(vector
&vec)//注意這裡樹的頂端節點為1,不是0,為了方便,這裡對vec1的1-19個數排序,忽略vec[0]
}else
if(2*i <= n-1 && 2*i + 1 > n-1) //只有左子節點的情況}}
heapadjust(vec,2,n-1); //從堆的第二個節點開始進行調整
/* for(int j = 2; j<=(n-1)/2; j++) //從第二個節點開始,向下調整堆
}else if(2*j <= n-1 && 2*j + 1 > n-1) //注意邊界,只有左子節點的情況}}
*/}void heapsock(vector
&vec)
}void heapadjust(vector
&vec, int n, int m)
}else
if(2*j <= m && 2*j + 1 > m) //注意邊界,只有左子節點的情況}}
}
選擇類排序 直接選擇與堆排
思想 一開始整個陣列預設是無序區,有序區元素為空,每趟從無序區裡面選出乙個最小的元素,與無序區的第乙個元素進行交換,整個時候有序區的元素的元素 1,無序區的元素會 1,下一趟排序再從無序區選擇乙個最小的與無序區的元素進行交換,無序區元素 1.有序區 1,以後執行同樣的操作 如下 void selec...
排序演算法(直接選擇排序)
為什麼我們要叫直接選擇排序呢?在最開始的時候,待排序區間是整個陣列,從區間選乙個最小的與區間第乙個交換位置,然後將待排序區間從第二個開始,繼續以上操作,直至待排序區間長度為0 我們還是以為例 初始 3 5 7 9 8 6 2 1 4 0 第一趟 05 7 9 8 6 2 1 4 3 第二趟 0 17...
排序演算法 直接選擇排序
選擇排序的基本思想是 每一趟從待排序的記錄中選出關鍵字最小的記錄,順序放入已排序數列的最後,直到全部記錄排序完畢。直接選擇排序是一種簡單直觀的排序演算法。它的工作原理 首先在未排序序列中找到最小 大 元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小 大 元素,然後放到已排序序列...