基礎排序算法研究小結


我們日常中接觸的數據大多都是經過排序的。如按學號順序在班級表里查詢每個學生信息,按字母順序在字典中查詢每個字的定義。同理,工作中也經常會用到排序,排序算法也是對思維的一個鍛煉!

結合自己所學,我將總結冒泡排序算法、插入排序算法、選擇排序算法,三種最基礎而又閃爍着程序員智慧之光的算法。這些算法的每一種都很容易理解和實現。可能對於大多情況而言,這些算法不是最好最全面的算法,但是對於少量數據而言,用這些算法絕對划算!

一  冒泡排序

 

原理:

1.比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。

2.對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最后一對。走完這一步,最后的元素將是最大的。

3.除最后元素外,針對剩下元素重復以上步驟。

4.持續每次對越來越少的元素重復上面的的步驟,直到沒有任何一對數字需要比較。

 

上代碼

public void bubbleSort(int []arr)
{
bool didSwap ;//元素是否進行過交換
int temps;
for (int i = 0; i < arr.Length-1; i++)//對越來越少的元素進行1.2.3步驟
{
didSwap = false;
for (int j = 0; j < arr.Length - 1 - i; j++)//循環比較任意相鄰的兩個元素
{
if (arr[j] > arr[j + 1])//如果前一個元素大於后一個元素,交換他們
{
temps = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temps;
didSwap = true;
}

}

if (didSwap == false)
{
return;
}
}



}

 

代碼分析:

上面的方法體分為兩層循環,內層循環與原理步驟1.2.3同理;外層循環中 i 的值越來越大,所以內層循環中要比較的元素越來越少,與步驟4.同理。

 

時間復雜度:

若數組的初始狀態是正序的(如數組{1.2.3.4.5....n}),一趟掃描既可完成排序。在第一次內循環完成后,didSwap值為false,程序會跳出外循環,整個方法進行了n-1次比較,0次交換。所以最優時間復雜度為O(n)

若數組的初始狀態是反序的,需要進行n-1趟排序。每趟排序需要進行n-i次關鍵字的比較(1<=i<=n-1),且每次比較滿足條件后都需要進行一次元素交換(交換一次需要三次賦值),整個方法進行了n(n-1)/2次比較,3n(n-1)/2次賦值操作,所以最壞時間復雜度為O(n^2)

平均時間復雜度為O(n^2)!

 

算法穩定性:

冒泡排序就是把小的元素往前調或者把大的元素往后調。比較是相鄰的兩個元素比較,交換也發生在這兩個元素之間。如果兩個元素相等,沒有必要交換;如果兩個相等的元素沒有相鄰,那么即使通過前面的兩兩交換把兩個相鄰起來,這時候也不必交換,所以相同元素的前后順序並沒有改變,所以冒泡排序是一種穩定排序算法

 

 ====================================================================================================================================================================

 

二、選擇排序

 

原理:

這種排序是從數組的第一個元素(位置為0)開始,把第一個元素與數組中其他元素進行比較。在比較完畢后,選出最小的元素放置在第0個位置上,接着再從第1個位置開始再次進行排序操作。這種操作會一直到除最后一個元素外的每一個元素都作為新循環的起始點操作后才會終止。

 

上代碼:

 

public void selectionSort(int[] arr)
        {
            int temps;
            int pos = 0;
       bool is
            for (int i = 0; i < arr.Length - 1; i++)
            {
                pos = i;
                for (int j = i + 1; j < arr.Length; j++)
                {
                    if (arr[j] < arr[pos])
                    {
                        pos = j;//獲得最小數的下標
                    }
                
                }
            if(pos != i)
                //第i個數與最小數arr[pos]交換
                temps = arr[i];
                arr[i] = arr[pos];
                arr[pos] = temps;
            }
        
        }

 

代碼分析:

上述代碼使用了兩層循環。外層循環從數組的第一個元素移動到數組最后一個元素之前的元素,而內層循環則從數組第二個元素移動到數組的最后一個元素,並且查找比當前外層循環所指元素更小的數值。在內循環完成一遍后,便為將得到的最小值賦值到數組中合適的位置。

 

 時間復雜度:

比較次數與數組的初始狀態無關,為n(n-1)/2次

交換次數,數組為正序時(pos 總是等於i)交換0次,反序交換n/2次,最壞情況交換n-1次交換次數比冒泡排序少多了,交換所需cpu時間比比較所需cpu時間多。冒泡排序與選擇排序的時間復雜度應根據情況而判斷

 

穩定性:

選擇排序是給每個位置選擇當前元素最小的,比如給第一個位置選擇最小的,在剩余元素里面給第二個元素選擇第二小的,依次類推,直到第n-1個元素,第n個元素不用選擇了,因為只剩下它一個最大的元素了。那么,在一趟選擇,如果一個元素比當前元素小,而該小的元素又出現在一個和當前元素相等的元素后面,那么交換后穩定性就被破壞了。比較拗口,舉個例子,序列5 8 5 2 9,我們知道第一遍選擇第1個元素5會和2交換,那么原序列中兩個5的相對前后順序就被破壞了,所以選擇排序是一個不穩定的排序算法

 

====================================================================================================================================================================

 

 三 插入排序

原理:

插入排序的基本操作就是將一個元素插入到已經排好序的有序數組中,從來得到一個新的、長度加一的數組。類似於我們平時玩撲克往手中插牌的操作:摸牌的時候,牌面朝下放在桌子上,左手為空。每一次摸牌后,將牌大小與手中的牌進行比較,然后插入適當位置,這樣手中的牌總是排好序的。

上代碼

public void insertSort(int[] arr)
        {
            int temps; //定義一個變量,存放要插入的元素

            for (int i = 1; i < arr.Length; i++)
            {
                temps = arr[i];
                int j = i - 1;//與要插入元素做比較的光標
                while (j >= 0 && arr[j] > temps)
                {
                    //做比較的元素大於要插入的元素,做比較的元素后移
                    arr[j + 1] = arr[j];
                    j--;
                
                }

                //將要插入的元素插入到適當位置

                  if (i != j + 1)
                  {
                    arr[j + 1] = temps;
                  }



            }
        
        
        }

 

代碼分析:

上述代碼有兩層循環。假設數組中的第一個元素為已排序的數組,后面(n-1)個元素為未排序的數組。外層循環會遍歷未排序數組元素。內層循環則會把外層循環選擇的元素與已排序數組元素從右向左依次比較。如果外層循環選擇的元素小於內層循環選擇的元素,那么內層循環選擇的元素向右移動,留下該處位置,外層循環的元素再跟上一個元素比較,直到退出內循環。然后再外層循環中將外層循環選擇的元素插入適當位置

 

時間復雜度

最好情況,數組原本是正序數組,比較次數n-1,移動次數0

最差情況,數組原本是倒序數組,比較次數2+3+.....+n-= (n+2)(n-1)/2,移動次數 1+2+3+....n-1 = n(n-1)/2.

穩定性:

不會改變同等大小元素的位置,是穩定的排序算法

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM