經典排序算法C++

冒泡排序:

依次比較相鄰的兩個元素,如果前者大於後者,則交換順序。第一趟完成後最後的元素是最大的,然後針對所有的元素重複以上的步驟,除了最後一個。時間複雜度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之前,則稱這種排序算法是穩定的。通俗地講就是保證排序前後兩個相等的數的相對順序不變。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章