冒泡排序:
依次比較相鄰的兩個元素,如果前者大於後者,則交換順序。第一趟完成後最後的元素是最大的,然後針對所有的元素重複以上的步驟,除了最後一個。時間複雜度n^2
void bubblesort(vector<int>& arr)
{
for (int i = 0; i < arr.size()-1; i++)
{
for (int j = 0; j < arr.size()-1-i; j++)
{
if (arr[j]> arr[j+1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
選擇排序:
在序列中,找到最小元素,放到序列的起始位置作爲已排序序列;然後,再從剩餘未排序元素中繼續尋找最小元素,放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。
void selectionsort(vector<int>& arr)
{
for (int i = 0;i < arr.size()-2;i++)
{
int min = arr[i],index=i;
for (int j = i+1;j < arr.size()-1;j++)
{
if (min>arr[j])
{
min = arr[j];
index = j;
}
}
arr[index] = arr[i];
arr[i] = min;
}
}
插入排序:
1.從第一個元素開始,該元素可以認爲已經被排序
2.取出下一個元素,在已經排序的元素序列中從後向前掃描
3.如果該元素(已排序)大於新元素,將該元素移到下一位置
4.重複步驟3,直到找到已排序的元素小於或者等於新元素的位置
5.將新元素插入到該位置中
6.重複步驟2
void insertionsort (vector<int>& arr)
{
for (int i = 1;i < arr.size()-1;i++)
{
int temp = arr[i];
for (int j = i-1;j >= 0&& temp < arr[j];j--)
{
arr[j+1] = arr[j];
}
arr[j+1] = temp;
}
}
快速排序:
選定第一個數作爲基準,將設置左右兩個指針,目標是將比基準數大的數放在右邊,小的數放在左邊,如果有不滿足的條件的,則兩個指針交換,直到兩個指針重合,將此時所指的數和基準數交換。
void quicksort(vector<int>& arr, int left, int right)
{
if(left>right)
return;
int i = left, j = right, temp = arr[left];
while (i < j) //如果i==j,此時則爲正中心的位置,需要把基準數換過去
{
while(i < j && arr[j]>= temp) // 從右向左找第一個小於x的數
j--;
while(i < j && arr[i]<= temp) // 從左向右找第一個大於等於x的數
i++;
if(i < j)
{
int t = arr[i];
arr[i] = arr[j];
arr[j] =t;
}
}
arr[left] = arr[i];
arr[i] =temp;
quicksort(arr, left, i - 1); // 遞歸調用
quicksort(arr, i + 1, right);
}
堆排序:
堆是具有以下性質的完全二叉樹:每個結點的值都大於或等於其左右孩子結點的值,稱爲大頂堆;或者每個結點的值都小於或等於其左右孩子結點的值,稱爲小頂堆。
大頂堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
小頂堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
堆排序的基本思路:
a.將無序序列構建成一個堆,根據升序降序需求選擇大頂堆或小頂堆;
b.將堆頂元素與末尾元素交換,將最大元素"沉"到數組末端;
c.重新調整結構,使其滿足堆定義,然後繼續交換堆頂元素與當前末尾元素,反覆執行調整+交換步驟,直到整個序列有序。
class Solution {
public:
*/
void heapAdjust(vector<int>& arr, int start, int end) {
int temp = arr[start];
for(int i=2*start+1; i<=end; i*=2) {
//左右孩子的節點分別爲2*i+1,2*i+2
//選擇出左右孩子較小的下標
if(i < end && arr[i] < arr[i+1]) {
i ++;
}
if(temp >= arr[i]) {
break; //已經爲大頂堆,=保持穩定性。
}
arr[start] = arr[i]; //將子節點上移
start = i; //下一輪篩選
}
arr[start] = temp; //插入正確的位置
}
void heapSort(vector<int>& arr) {
if(arr == null || arr.length == 0)
return ;
//建立大頂堆
for(int i=arr.length/2; i>=0; i--) {
heapAdjust(arr, i, arr.length-1);
}
for(int i=arr.length-1; i>=0; i--) {
swap(arr, 0, i);
heapAdjust(arr, 0, i-1);
}
}
void swap(vector<int>& arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
排序算法的穩定性:如果Ai = Aj,排序前Ai在Aj之前,排序後Ai還在Aj之前,則稱這種排序算法是穩定的。通俗地講就是保證排序前後兩個相等的數的相對順序不變。