1.堆排序
【演算法引出】:是簡單選擇排序演算法的改進演算法,簡單選擇排序中每一趟比較選出乙個最小值,但是後一趟的比較中會重複前面的比較結果,存在重複。堆排序對其的改進體現在—— 每次選擇最小值的同時,根據結果對其他的值進行調整。
【堆的概念】:堆是具有以下性質的完全二叉樹,每個節點都大於或等於左右孩子節點的值,稱為大頂堆;每個節點都小於等於左右孩子節點的值,稱為小頂堆。
【演算法思想】:以大頂端堆為例,(1)首先構造乙個大頂堆,即堆頂為所有元素的最大值;(2)其次,將該堆頂元素與堆末尾元素互換,此時堆末尾便儲存了最大元素;(3)除去堆末尾元素,對於剩餘的n-i個元素反覆執行(1)、(2)操作即可完成排序。
//堆排序,i表示當前節點編號,n表示全部節點編號,n從0開始
void heapadjust(int arr, int i, int n)
if(arr[j] <= arr[i])
//否則交換子節點和父節點
swap(arr[j],arr[i]);
//迴圈變數增加
i= j;
j= 2*i + 1;
} } void heapsort(int arr, int n)
//把頂取出,放入最末元素進行調整,總共進行n次,時間複雜度nlogn
for(int i = n-1; i >= 0; i--)
}
歸併排序
參考:
歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法(divide and conquer)的乙個非常典型的應用。
首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第乙個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再進行比較,如果有數列為空,那直接將另乙個數列的資料依次取出即可。
可以看出合併有序數列的效率是比較高的,可以達到o(n)。
解決了上面的合併有序數列問題,再來看歸併排序,其的基本思路就是將陣列分成二組a,b,如果這二組組內的資料都是有序的,那麼就可以很方便的將這二組資料進行排序。如何讓這二組組內資料有序了?
可以將a,b組各自再分成二組。依次類推,當分出來的小組只有乙個資料時,可以認為這個小組組內已經達到了有序,然後再合併相鄰的二個小組就可以了。這樣通過先遞迴的分解數列,再合併數列就完成了歸併排序。
歸併排序的效率是比較高的,設數列長為n,將數列分開成小數列一共要logn步,每步都是乙個合併有序數列的過程,時間複雜度可以記為o(n),故一共為o(n*logn)。因為歸併排序每次都是在相鄰的資料中進行操作,所以歸併排序在o(n*logn)的幾種排序方法(快速排序,歸併排序,希爾排序,堆排序)也是效率比較高的。
//將有序陣列//將有二個有序數列a[first...mid]和a[mid...last]合併。
void mergearray(int a, int first, int mid, int last, int c)
else
}while(i <= n)
while(j <= m)
for (i = 0; i < k; i++)
}void mergesort(int a, int first, int last, int temp)
//將s[j]填到s[i]中,s[j]就形成了乙個新的坑
if(i < j)
//從左向右找大於或等於x的數來填s[j]
while(i < j && s[i] < x)
//將s[i]填到s[j]中,s[i]就形成了乙個新的坑
if(i < j)
}//退出時,i等於j。將x填到這個坑中。
s[i] = x;
return i;
}
void quick_sort1(int s, int l, int r)
}
排序演算法歸類
插入排序類
選擇排序類
交換排序類
歸併排序類
直接插入排序
希爾排序
直接選擇排序
堆排序氣泡排序
快速排序
歸併排序
排序演算法彙總:
平均時間複雜度
最好情況
最差情況
空間複雜度
穩定性
直接插入排序
o(n2)
o(n)
o(n2)
o(1) 穩定
氣泡排序
o(n2)
o(n)
o(n2)
o(1) 穩定
直接選擇排序
o(n2)
o(n2)
o(n2)
o(1)
不穩定希爾排序
o(nlogn)~o(n2)
o(n1.3)
o(n2)
o(1)
不穩定快速排序
o(nlogn)
o(nlogn)
o(n2)
o(logn)
不穩定堆排序
o(nlogn)
o(nlogn)
o(nlogn)
o(1)
不穩定歸併排序
o(nlogn)
o(nlogn)
o(nlogn)
o(n)穩定
備戰2014筆面試 遞迴的應用 排列組合的實現
1.有重複的排列問題 例題 用3,2,1這三個數字組成乙個4位數,數字可以重複。這裡顯然有3的4次方種可能性,可以用遞迴實現如下 void quanpailie1 int a,int i,int n count cout 例題有陣列,試輸出該陣列的所有組合。這裡可得每乙個數均有放入子集和不放入子集兩...
面試排序演算法
private void swap int nums,int i,int j 每輪找出最小的值放在左側 private void selectionsort int nums swap nums,i,min 假設前i有序,把i 1的元素,通過交換插入到前面的i個中 private void inse...
人人網2014筆試演算法題彙總
1.給出乙個有序陣列啊,長度為len,另外給出第三個數x,問是否能在陣列中找到兩個數,這兩個數之和等於第三個數x。我們首先看到第一句話,這個陣列是有序的,所以,我們可以定義兩個指標,乙個指向陣列的第乙個元素,另乙個指向應該指向的位置 這個需要看具體的實現和陣列給定的值 首先計算兩個位置的和是否等於給...