插入,選擇,交換,歸併,基數排序

2021-06-20 01:36:50 字數 3915 閱讀 6444

1. 插入排序

1.1 直接插入排序 

(將後面的元素插入到前面已經排好的序列)

穩定;空間代價θ(1),時間代價:θ(n*n)

/****************** 直接插入排序 ******************/

template void improvedinsertsort (record array, int n)

array[j+1] = temprecord;

}}

1.2 shell 排序 

(依次增量插入)

不穩定;空間代價θ

(1),時間代價:θ(n*n)。shell最好的增量,呈 2p3q 形式的一系列整數:1, 2, 3, 4, 6, 8, 9, 12

template void modinssort(record array, int n, int delta)

array[j+delta] = temprecord; //此時j後面就是記錄i的正確位置,回填

}}template void shellsort(record array, int n) //shell排序,array為待排序陣列,n為陣列長度

; //析構函式

void buildheap();

bool isleaf(int pos) const; //如果是葉結點,返回true

int leftchild(int pos) const; //返回左孩子位置

int rightchild(int pos) const; //返回右孩子位置

int parent(int pos) const; //返回父結點位置

bool remove(int pos, t& node); //刪除給定下標的元素

void siftdown(int left); //篩選法函式,引數left表示開始處理的陣列下標

void siftup(int position); //從position向上開始調整,使序列成為堆

bool insert(const t& newnode); //向堆中插入新元素newnode

void movemax(); //從堆頂移動最大值到尾部

t& removemax(); //從堆頂刪除最大值

};templatemaxheap::maxheap(t* array,int num,int max)

templatevoid maxheap::buildheap()

templatebool maxheap::isleaf(int pos) const

templateint maxheap::rightchild(int pos) const

templateint maxheap::parent(int pos) const //返回父節點位置

templatevoid maxheap::siftdown(int left)

templatet& maxheap::removemax()

else

}templatevoid maxheap::movemax()

else

return;

}templatebool maxheap::remove(int pos, t& node)

//堆排序,array為待排序陣列,n為陣列長度

template void heapsort(record array, int n)

if (noswap) // 如果沒發生過交換,表示已排好序,結束演算法

return;

}}

3.2 快速排序

(選擇乙個軸值,

把陣列分成左邊比軸值小,右邊比軸值大的兩個陣列,然後繼續分治)

不穩定;平均

空間代價:θ(log n)(遞迴呼叫使用到棧);平均時間代價:θ(nlog n);

/****************** 快速排序 ******************/

void swap(record *array, int &id1, int &id2) // 交換陣列中兩個下標的值

int selectpivot(int left, int right) // 選擇軸值,引數left,right分別表示序列的左右端下標

template int partition(record array, int left, int right) // 分割函式,分割後軸值已到達正確位置

// r指標向左移動,直到找到乙個小於等於軸值的記錄

while (array[r] > temprecord && r > l) // 這裡也可以把">"改寫為">=",減少記錄移動

r--;

if (l < r) // 若l,r尚未相遇,將逆置元素換到左邊的空位

} //end while

array[l] = temprecord; // 把軸值回填到分界位置l上

return l; // 返回分界位置l

}template void quicksort(record array, int left, int right) // array為待排序陣列,left,right分別為陣列兩端

4. 歸併排序

(將陣列劃分為兩個子串行,分別對每個子串行歸併排序,然後合併有序子串行)

穩定;空間代價:θ(n),平均時間代價均為 θ(nlog n)

/****************** 歸併排序 ******************/

template void merge(record array, record temparray, int left, int right, int middle) //歸併過程

while (index1 <= middle) // 只剩左序列,可以直接複製

array[i++] = temparray[index1++];

while (index2 <= right) // 與上個迴圈互斥,直接複製剩餘的右序列

array[i++] = temparray[index2++];

}template void mergesort(record array, record temparray, int left, int right)

}

5. 分配排序和基數排序

不需要進行紀錄之間兩兩比較,需要事先知道記錄序列的一些具體情況

5.1 桶排序

(記錄元素

分布區間[0,max),把資料放入對應的桶,並計數。然後從後往前讀取資料,查詢桶中計數,判斷具體位置.)

穩定;總的時間代價為 θ(m+n),空間代價θ(m+n),m為區間個數 (適合於 m 比較小的情況)

/****************** 桶排序 ******************/

template void bucketsort(record array, int n, int max)

5.2 基數排序

(原理同桶排序一樣,只是當 m 很大時,將乙個記錄的值即排序碼拆分為多個部分來進行比較)

穩定;空間代價:θ(n+r),時間代價:θ(d·(n+r))

/****************** 基數排序 ******************/

template void radixsort(record array, int n, int d, int r)

for (j=0; jarray[j] = temparray[j];

radix *= r; // 往左進一位,修改模radix

}}

資料結構 排序(插入,選擇,交換,歸併)及其特性

直接插入排序 基本思想 把待排序的記錄按其關鍵碼值的大小逐個插入到乙個已經排好序的有序序列中,直到所有的記錄插入完為止,得到乙個新的有序序列。直接插入排序 void insertsort int array,int size if j i 1 直接插入排序的特性總結 元素集合越接近有序,直接插入排序...

冒泡 插入 選擇 歸併排序

演算法原理 比較相鄰的元素。如果第乙個比第二個大,就交換他們兩個。對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。針對所有的元素重複以上的步驟,除了最後乙個。持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。若檔案的初始狀態是正序...

歸併與基數排序

1.輸入10 5個只有一位數字的整數,可以用o n 複雜度將其排序的演算法是 桶排序 2.資料序列只能是下列哪種排序演算法的兩趟排序結果?b a 氣泡排序 b 快速排序 c 插入排序 d 堆排序 解析 如果是氣泡排序,末尾是最大或最小的兩個數 如果是插入排序,最前面應該是最大或最小的兩個數 如果是堆...