1.氣泡排序
時間複雜度:進行兩重迴圈,因此是o(n^2)
空間複雜度:原地排序,無需其他額外的空間,因此是o(1)
void bubblesort(int array, int length) }}
}
2.快速排序
思想:快排的乙個重要思想是遞迴。每一輪遞迴,需要選出乙個基準元素(最好隨機選取,下面附的**是以第乙個元素為基準元素),將大於此基準元素的放到其右側;小於他的放到其左側。然後左側和右側分別進行下一輪遞迴。
時間複雜度:由於快排能指數級的降低複雜度,因此是o(nlogn)
空間複雜度:o(logn)
void quicksort(int a, int l, int r)
}quicksort(a, l, j);
quicksort(a, j + 1, r);
}
1.簡單插入排序
思想:維護前x個元素為有序的,當第x+1個元素要插入時,將其插入到合適的位置即可。
時間複雜度:o(n^2)
空間複雜度:o(1)
void insertsort(int array, int length)
array[preindex + 1] = current;
}}
2.希爾排序
思想:首先把整個陣列,分成若干個小組,然後對每個小組進行插入排序,由於小組的資料量小,因此插入起來效率較高。小組是通過增量來形成的。較簡單的增量序列是[lenght/2, lenth/4 .....],也有個別情景指定給出增量序列的。對於增量為length/2時,小組為[0, length /2]、[1, length /2 + 1]......
時間複雜度:o(nlogn)
空間複雜度:o(1)
void sheelsort(int array, int length)
}}//改寫插入排序
void insertsort(int array, int gap, int i)
arr[j + gap] = insert;
}
1.選擇排序
思想:每一輪遍歷,把最小的元素放到最前面。
時間複雜度:o(n^2)
空間複雜度:o(1)
void selectsort(int array, int length)
int temp = array[index];
array[index] = array[i];
array[i] = temp;
}}
2.堆排序
思想:是利用堆這種資料結構來進行排序的演算法。例如小頂堆,我們可以得到堆頂的最小值(根節點),將其與堆的最後乙個元素交換,此時前n-1個元素可能不滿足小頂堆的特性,因此讓剩下n-1個元素重建乙個小頂堆,則得到n個元素中的次小值。如此反覆即可。
大頂堆:父親節點的值大於其左右兒子的值。
小頂堆:父親節點的值小於其左右兒子的值。
時間複雜度:o(nlogn)
空間複雜度:o(1)
void heapsort(int array, int length)
for(int i = length - 1; i > 0; i--)
}void heapadjust(int array, int i, int length)
if(array[k] > value)
else
}// i 就是最後合適的位置
array[i] = value;
}
1.二路歸併排序
思想:將兩個有順序的陣列合併成乙個有序陣列。
時間複雜度:o(nlogn)
空間複雜度:o(n)
void merge(int* a, int left, int right)
// copy
for (int i = left; i <= right; i++)
delete(ta);
}void mergesort(int* a, int left, int right)
}
1.計數排序
思想:計數排序的思想比較直觀,從前到後,掃瞄下原序列,記錄每個值下元素的個數,然後從最小值開始輸出,如果此值對應的個數為2,那麼輸出兩次就好。
如果資料的最小值,不是從0開始的,那麼這個地方,在統計該值的個數時,可以減去最小值,整體的把資料平移一下。
在其他的排序場景下,例如統計學生的成績,如果條件是成績相同,我們需要保留原有資料的順序,那麼普通的計數排序無法保證保留原有順序,他會打亂相同值的順序(不穩定)。因此可以將其改進一下。
①用countarray陣列統計每個值的個數
③從後向前掃瞄原序列,通過其值v在value陣列中找到對應的位置pos。位置pos=countarray[v]-1。在獲得該位置後,countarray[v]--(這個地方很巧妙)。
計數排序不太適合資料較為離散的情況,以及小數的排序。
時間複雜度:o(n + m) m是最大值最小值之差
空間複雜度:o(m)
// 改進前的計數排序
void countsort(int* array, int length)
// 2 countarray陣列儲存每個值的個數
int *countarray = new int[maxt - mint + 1];
// 3 遍歷數列,獲得每個值的個數
for(int i = 0; i < length; i++)
countarray[array[i] - mint]++;
// 4 遍歷統計陣列,輸出結果
int index = 0;
for (int i = 0; i < (maxt - mint + 1); i++)
}}
2.基數排序
思想:①分配根據關鍵字,把陣列元素從前往後,分別裝到相應的桶中,②收集,再從桶中收集回來。就以簡單的數字排序為例,如果是個位、十位、百位的順序,那就是最低位優先;與之相反,是最高位優先。
時間複雜度:o(n*k) k是關鍵字的個數
空間複雜度:o(n + m)
3.桶排序
思想:計數排序和基數排序中,都用到了桶排序的思想。桶排序是先根據資料中的最大值和最小值將資料劃分區間,然後每個區間對應乙個桶,每個桶中的資料可以通過歸併排序、快排等方法再次進行排序。但是當資料的分布極其不均勻時,他的時間複雜度退化較厲害,用的較少。
時間複雜度:o(n + k)
空間複雜度:o(n + k)
排序 各種排序的總結
1 氣泡排序 快速排序 可能很多人會奇怪為何會把這兩種排序方式放在一起,那是因為,氣泡排序恰好是快速排序的最壞情況,相應地快速排序則是氣泡排序的優化。氣泡排序的思想 每次比較相鄰的元素,共比較 n 1 輪。排序過程中,左邊是待排序序列,右邊是已排序序列。屬於穩定排序演算法。快速排序的思想 兩個關鍵指...
各種排序演算法總結
注 以下所講排序,以公升序排序為例!選擇排序 作者思路 在一組數中,選擇第乙個數標記為最小值,在剩下的數中找比它小的數,若找到則交換兩數,標記新的 最小值 然後繼續往下找,這樣一趟下來就可以找到一組數中第二小的值,第二次以第二個數作為最小值,如此迴圈下去。這是最簡單 最基礎的一種排序演算法。例子 1...
各種排序演算法總結
1 插入排序 void insertsort int a,int n a j 1 key 插入排序是穩定的排序,平均和最壞時間複雜度是o n 2 最好的時間複雜度是o n 對應於全部排好序的情況。2 氣泡排序 void bubblesort int a,intn 氣泡排序是穩定的排序,平均和最壞時間...