【自考】 資料結構知識總結【CH7】
CH7 排序
1. 基本概念
排序就是將一組物件按照規定的次序重新排列的過程, 排序往往是為檢索服務的。
穩定性:相同鍵值兩個記錄在排序前後相對位置的變化情況。
相鄰的元素進行比較的演算法,如直接插入演算法,氣泡排序,歸併排序。
不相鄰的元素進行比較的演算法,如選擇排序中的直接選擇排序和堆排序以及快速排序。
內部排序:待排序的記錄全部存放在計算機記憶體中進行的排序。
外部排序:待排序的記錄數量很大,記憶體不能儲存全部記錄,需要對外存進行訪問的排序過程
時間複雜度:通過 鍵值比較次數和記錄移動次數來分析。
當記錄基本有序時,插入排序和交換排序比較有效,直接插入和氣泡排序的時間複雜度都是O(n)
當待排記錄數量較大時,選擇排序比較有效。
2. 插入排序
直接插入排序: 依次將每個記錄插入到一個已排好序的有序表中。不到最後一趟,都不能確定每個鍵值的最終位置。
時間複雜度:
void StarightInsertSort(List R, int n)
{
for (i=2;i<=n;i++)
{
R[0] = R[i];
j = i-1;
while (R[0].key < R[j].key)
{
R[j+1] = R[j];
j--;
}
R[j+1] = R[0];
} // end of for
}
3. 交換排序
基本思想
比較兩個記錄鍵值的大小,如果這兩個記錄鍵值的大小出現逆序,則交換這兩個記錄。
氣泡排序
void BubbleSort(List R,int n)
{ int i,j,temp,endsort;
for (i = 1; i<=n-1 ; i++)
{ endsort = 0;
for (j=1;j<=n-1;j++)
{
if(R[j].key>R[j+1].key)
{ temp = R[j];
R[j] = R[j+1];
R[j+1] = temp;
endsort = 1;
} // end of if
} // end of for
if (endsort == 0) break;
} // end of for
}
快速排序
// 快速排序
int QuickPartition(List R,int low,int high)
{ x = R[low];
while(low < high)
{
while ((low < high) && R[high].key >= x.key)) high--;
R[low] = R[high];
while ((low < high) && R[low].key <= x.key)) low++;
R[high] = R[low];
}
R[low] = x;
return low;
}
// 遞迴實現
void QuickSort(List R,int low,int high)
{ if (low<high)
{
temp = QuickPartition(R, low ,high);
QuickSort(R, low, temp-1);
QuickSort(R, temp+1, high);
}
}
4. 選擇排序
基本思想
每一次在n-i+1個記錄中選取鍵值最小的記錄,並和第i個記錄交換。
直接選擇
void SelectSort(List R,int n)
{ int min,i,j;
for (i = 1;i <= n-1; i++)
{ min = i;
for (j = i+1;j <= n; j++)
{
if (R[j].key < R[min].key) min = j;
if (min != i) swap(R[min],R[i]);
}
}
}
堆排序
自堆頂向下調整過程稱為“篩選”。
時間複雜度 一共有n個結點,每次篩選會最多進行log2(n)次比較,O(n * log2(n))
歸併排序
基本思想
要求待排序列是由若干個有序序列組成。
合併的方法是比較各子序列的第一個記錄的鍵值,最小的一個就是排序後序列的第一個記錄的鍵值。取出這個記錄,繼續比較各個子序列現有的第一個記錄的鍵值,便可以找出排序後面的的第二個記錄。
空間複雜度,由於要用到和待排記錄等數量的陣列b來存放結果,所以實現歸併排序需要附加一倍的儲存開銷。
一共有log2(n)趟,每趟進行(n-區間數)次比較。O(比表示式階級大或者相等的階級)= O(n * log2(n))