1. 程式人生 > >資料結構--排序演算法(氣泡排序&&快速排序&&鴿巢排序)

資料結構--排序演算法(氣泡排序&&快速排序&&鴿巢排序)

氣泡排序:

思想:兩兩交換,大的放到後面。重複size-1次


程式碼實現:

  1. //氣泡排序
  2. void Bubble_Sort(int array[],int size)  
  3. {  
  4.     for(int idx= 0; idx < size;++idx)  
  5.     {  
  6.        for(int index= 0; index < size-1-idx;++index)  
  7.        {  
  8.            if(array[index]> array[index+1])  
  9.            {  
  10.               std::swap(array[index],array[index+1]);  
  11.            }  
  12.        }  
  13.     }  
  14. }  


氣泡排序的優化:

思想:對氣泡排序常見的改進方法是加入一標誌性變數flag,用於標誌某一趟排序過程中是否有資料交換,如果進行某一趟排序時並沒有進行資料交換,則說明資料已經按要求排列好,可立即結束排序,避免不必要的比較過程。

程式碼實現:

  1. //氣泡排序優化
  2. void Bubble_Sort2(int array[], int size)  
  3. {  
  4.     bool flag = true;  
  5.     while (flag)  
  6.     {  
  7.         flag = false;  
  8.         for
     (int index = 0; index < size - 1; ++index)  
  9.         {  
  10.             if (array[index] > array[index + 1])  
  11.             {  
  12.                 std::swap(array[index], array[index + 1]);  
  13.                 flag = true;  
  14.             }  
  15.         }  
  16.     }  
  17. }  

快速排序:

遞迴:

快速排序第一種方法:

思想:選取一個數字為比較值,用右值和他比較,如果右值比他小就將他給左邊,左邊加一。

若左邊比他大,就將他給右邊,右邊減一。如此當left==right時,說明此比較值的地方就應該在此,然後遞迴,先排此地點的左邊再排此地點的右邊。

優化:可以寫一個函式為查詢最左邊下標,最右邊下標以及中間下標的中間值,在陣列範圍內比較陣列下標第一個,最後一個,和中間值得元素,儘可能將值為中間的元素當成key值,這樣可以提高效率。(因為遞迴時左和右都有將近一半的資料)

程式碼:

  1. //三數取中法
  2. int FindMidIndex(int array[],int left,int right)  
  3. {  
  4.     int mid= right - ((right- left) >> 1);  
  5.     if(array[left]<= array[mid])  
  6.     {  
  7.        if(array[right]< array[left])  
  8.            return left;  
  9.        if(array[right]> array[mid])  
  10.            return mid;  
  11.        else
  12.            return right;  
  13.     }  
  14.     if(array[left]> array[mid])  
  15.     {  
  16.        if(array[right]> array[mid])  
  17.            return mid;  
  18.        if(array[right]> array[left])  
  19.            return left;  
  20.        else
  21.            return right;  
  22.     }  
  23.     return 0;  
  24. }  


全過程


時間複雜度:O(NlogN)

空間複雜度:O(1)

穩定性:不穩定

程式碼實現:

  1. int Quick_Pass1(int array[],int left,int right)  
  2. {  
  3.     //設定一個比較的值儘量讓比較值為較為中間的值
  4.     int keyIdx= FindMidIndex(array,left,right);  
  5.     std::swap(array[keyIdx],array[right]);  
  6.     int temp= array[right];  
  7.     while(left < right)  
  8.     {  
  9.        //如果這時左邊比比較值大左邊給右邊右邊前移
  10.        while(left < right&& array[left]< temp)  
  11.            left++;  
  12.        if(left < right)  
  13.        {  
  14.            array[right]= array[left];  
  15.            right--;  
  16.        }  
  17.        //如果右邊比比較值小則右邊的數值給左邊,左邊後移
  18.        while(left < right&& array[right]>= temp)  
  19.            right--;  
  20.        if(left < right)  
  21.        {  
  22.            array[left]= array[right];  
  23.            left++;  
  24.        }  
  25.     }  
  26.     //最後一個他倆相等的時候把中間比較值給過來返回中間的下標
  27.     array[left]= temp;  
  28.     returnleft;  
  29. }  

快速排序第二種方法:

思路:給兩個指標,第一個為Cur,第二個為prev,比較值為key,當Cur小於等於right時就一直迴圈。(這裡如果沒有等於就會少比較一次)當cur下標的元素小於比較值得時候,並且++prev!=cur ,就讓array[cur]和array[prev]交換。當走完了之後,最後一個數據array[right]應該和array[++prev]交換,因為沒有比較最後一個(cur下標的元素小於比較值,這裡沒有等於),也就少換了一個。

一趟之後:


程式碼實現:

  1. //設定一個Pre與Cur 當Cur<=right的時候,就迴圈
  2. //當遇到Cur<key且Pre下一個不為Cur時,就讓array[Cur]與array[Pre]交換
  3. //找小於key的數與大於key的數字交換
  4. int Quick_Pass2(intarray[],intleft,intright)  
  5. {  
  6.     int cur= left;  
  7.     int prev= cur - 1;  
  8.     int keyIdx= FindMidIndex(array,left,right);  
  9.     std::swap(array[keyIdx],array[right]);  
  10.     int key= array[right];  
  11.     while(cur <= right)  
  12.     {  
  13.        //這裡不用<=是因為防止重複資料若出現重複複數據會交換很多次
  14.        if(array[cur]< key && ++prev!= cur)  
  15.            std::swap(array[cur],array[prev]);  
  16.        ++cur;  
  17.     }  
  18.     std::swap(array[++prev],array[right]);  
  19.     return prev;  
  20. }  

遞迴優化:

我們可知,當資料量較小的時候直接插入排序比較高效,所以當資料量較小的時候我們可以選擇插入排序,當資料量較大的時候我們選擇快速排序。

程式碼實現:

  1. //遞迴快速排序
  2. void Quick_Sort(intarray[],intleft,intright)  
  3. {  
  4.     if(right - left<16)  
  5.     {  
  6.        Insert_Sort(array,right-left+1);  
  7.     }  
  8.     else
  9.     {  
  10.        //先找到第一個數字應該放的點
  11.        intpos= Quick_Pass1(array,left,right);  
  12.        //排這個數的左邊的範圍
  13.        Quick_Sort(array,left,pos-1);  
  14.        //排這個數右邊的範圍
  15.        Quick_Sort(array, pos+ 1,right);  
  16.     }  
  17. }  

快速排序非遞迴:

思路:遞迴轉換為非遞迴一般用棧。我們向棧中儲存陣列下標,通過迴圈來進行排序。

程式碼實現:

  1. //非遞迴快速排序
  2. void Quick_Sort_Nor(intarray[],intleft,intright)  
  3. {  
  4.     stack<int> s;  
  5.     s.push(right);  
  6.     s.push(left);  
  7.     while(!s.empty())  
  8.     {  
  9.        left= s.top();  
  10.        s.pop();  
  11.        right= s.top();  
  12.        s.pop();  
  13.        intdiv= Quick_Pass2(array,left,right);  
  14.        //此時可能會出現越界的問題如果最後一個就為最大值或者第一個就為最小值
  15.        if(div - 1 > left)  
  16.        {  
  17.            //因為上面是先讀取左再讀取右  所以這裡為先壓右再壓左
  18.            s.push(div - 1);  
  19.            s.push(left);  
  20.        }  
  21.        if(div + 1 < right)  
  22.        {  
  23.            s.push(right);  
  24.            s.push(div + 1);  
  25.        }  
  26.     }  
  27. }  

鴿巢排序:

思路:如果遇見資料量大,資料雜亂度較高的一組資料。我們可以通過重新建立一個數組,此陣列中儲存數字出現的次數,下標加上最小的一個數字,此數字就為存入的數字。

最終只需要在新陣列中存放儲存數字即可。

時間複雜度:O(M+N)(M為存元素數目的區間,N為原陣列區間)

相關推薦

資料結構演算法C++之快速排序(續)

上一篇部落格資料結構與演算法C++之快速排序介紹了快速排序演算法。 但是上面實現的快速排序有兩個缺點: (一)對於近乎有序的陣列,演算法的計算複雜度由O(nlogn)退化到O(n2) (二)如果陣列中存在大量重複的元素,那麼演算法的計算複雜度也會退化到O(n2) (一)對於近乎有序的

資料結構演算法C++之快速排序

快速排序是一種比歸併排序還要快的排序演算法,具體原理如下圖所示 對上圖所示的陣列,首先隨機選取一個參照元素,一般選取最左邊的元素4為參照元素,然後將陣列排序成以4為分界點,左邊都是小於4的元素,右邊都是大於4的元素,按照這種方式進行不斷遞迴,就可實現整個陣列的排序。 上圖顯示的是程式

java版資料結構演算法氣泡排序

/** * 氣泡排序規則: * 1.比較兩個相鄰物件 * 2.如果左邊的大於右邊的,則調換位置 * 3.向右移動一個位置,比較接下來的兩個物件 * 時間複雜度:O(log n^2) */ class ArrayBubble { public static void bub

資料結構演算法-氣泡排序

概覽 基本概念 java程式碼實現 圖示執行過程 進一步優化 時間複雜度分析 基本概念 氣泡排序(Bubble Sort)

演算法)學習JavaScript資料結構演算法——氣泡排序

演算法入手:演算法思想——實現方式——時間複雜度+空間複雜度 實現排序前的基本結構: function ArrrayList(){ var array=[]; this.insert=function(item){ array.push(

資料結構演算法 | 氣泡排序演算法原理及實現和優化

氣泡排序(Bubble Sort)是排序演算法裡面比較簡單的一個排序。它重複地走訪要排序的數列,一次比較兩個資料元素,如果順序不對則進行交換,並一直重複這樣的走訪操作,直到沒有要交換的資料元素為止。 氣泡排序的原理 為了更深入地理解氣泡排序的操作步驟,我們現在

資料結構演算法分析筆記與總結(java實現)--排序5:快速排序練習題

題目:對於一個int陣列,請編寫一個快速排序演算法,對陣列元素排序。給定一個int陣列A及陣列的大小n,請返回排序後的陣列。測試樣例:[1,2,3,5,2,3],6 [1,2,2,3,3,5] 思路: 快速排序是使用二分思想,通過遞迴來實現排序的。對於一個數組,它先隨機選

資料結構演算法JavaScript描述讀書筆記(高階排序演算法

希爾排序 在插入排序的基礎上,只不過比較的步長不一樣,插入排序比較步長一直是1(即一個一個的比較)。希爾排序的步長第一次一般設定為gap=Math.floor(arr.length/2),之後依次將步長設定為gap/2,直到步長變為1,這個時候徹底轉化成插入排 測試時間普通排序演算法1

資料結構演算法JavaScript描述讀書筆記(基本排序演算法

前提準備 //自動生成陣列的函式,n:整數個數,數字在l-r之間 function setData(n,l,r){ var dataStore = []; for(var i=0;i<n;i++){ dataStore[i] = Math.floor(

資料結構演算法之美專欄學習筆記-線性排序

線性排序 線性排序的概念 線性排序演算法包括桶排序、計數排序、基數排序。 線性排序演算法的時間複雜度為O(n)。 線性排序的特點 此3種排序演算法都不涉及元素之間的比較操作,是非基於比較的排序演算法。 對排序資料的要求很苛刻,重點掌握此3種排序演算法的適用場景。   桶排序 演算法

(Java資料結構演算法)堆---優先佇列、堆排序

堆主要用於實現優先佇列。 利用有序陣列可以實現優先佇列(從小到大或從大到小的陣列),刪除的時間複雜度是O(1),但是插入的時間複雜度是O(N)。用堆實現優先佇列,插入和刪除的時間複雜度都是O(logN)。 簡介 堆是一種完全二叉樹,且每個節點的值都大於等於子節點值(大根堆)。

資料結構演算法學習筆記之如何分析一個排序演算法

前言 現在IT這塊找工作,不會幾個演算法都不好意思出門,排序演算法恰巧是其中最簡單的,我接觸的第一個演算法就是它,但是你知道怎麼分析一個排序演算法麼?有很多時間複雜度相同的排序演算法,在實際編碼中,那又如何選擇呢?下面我們帶著問題一起學習一下。  正文 一、常見經典的排序方法 (圖片來自於一畫素)

資料結構演算法(C語言) | 二叉排序

二叉排序樹的定義—— 二叉排序樹 ( Binary Sort Tree) 或者為空;或者是具有如下特性的二叉樹: (1)若根的左子樹不空,則左子樹上所有結點的關鍵字均小於根結點的關鍵字; (2)若

資料結構演算法(Python)-Python快速入門篇3

寫在前面 對於簡單的任務,我們可以利用一些函式,按照任務處理的流程書寫程式碼來完成需求,這種方式稱之為程序式程式設計(procedural programming);但是對於複雜的系統,如何有條理的將每個模組的程式碼內聚起來,如何清晰和簡潔地表達各個模組之間的

【python資料結構演算法】幾種排序演算法氣泡排序快速排序

以下排序演算法,預設的排序結果是從小到大。 一.氣泡排序: 1.氣泡排序思想:越大的元素,就像越大的氣泡。最大的氣泡才能夠浮到最高的位置。 具體來說,即,氣泡排序有兩層迴圈,外層迴圈控制每一輪排序中操作元素的個數——氣泡排序每一輪都會找到遍歷到的元素的最大值,並把它放在最後,下一輪排序時

資料結構--排序演算法(氣泡排序&&快速排序&&鴿排序)

氣泡排序: 思想:兩兩交換,大的放到後面。重複size-1次 程式碼實現: //氣泡排序 void Bubble_Sort(int array[],int size)   {       for(int idx= 0; idx < size;+

排序演算法氣泡排序(關鍵詞:資料結構/演算法/排序演算法/氣泡排序

假定:有 1 個亂序的數列 nums ,其中有 n 個數。 要求:排好序之後是 從小到大 的順序。 氣泡排序演算法 程式碼 from swap import swap def bubble_sort(nums): n = len(nums) for i in rang

資料結構演算法》之排序演算法氣泡排序、選擇排序

排序(Sorting) 是計算機程式設計中的一種重要操作,它的功能是將一個數據元素(或記錄)的任意序列,重新排列成一個關鍵字有序的序列。 排序演算法分類: 一、非線性時間比較類排序 1、交換排序(氣泡排序、快速排序) 2、插入排序(簡單插入排序、布林排序) 3、選擇排序(簡單選擇

python 資料結構演算法 day04 氣泡排序

1. 氣泡排序 思路: 可以看做按對高低不一的一組學生按照大小個排隊,校長從每次從頭開始走,觀察當前站的位置與後一個位置元素大小進行比較,如果比當前元素大,就交換兩者的位置,然後往後走一步,接著比較當前元素與後一個位置元素大小,重複剛才的過程,,,校長一次從頭走到尾的遍歷過程最大位置的元素跟著走到了最後,

資料結構演算法C++之三路快速排序

前兩篇部落格介紹了快速排序演算法以及對快速排序演算法的兩種改進, 下面開始介紹三路快速排序演算法,之所以稱為三路快速排序演算法,是因為其考慮了三個部分(如下圖),分別為大於 v