常見的面試中的排序算法

首先放上對比圖,這圖總結的很到位。html

1.直接插入排序

1.1基本思想:

假設有一個數組a[1..n],首先咱們能夠認爲在剛開始時a[1]是有序的,而後咱們從a[2]開始,到增個數組結束,依次將a[i]插入當前的有序區域中,就像整理撲克牌同樣,直到遍歷到數組的最後一位。java

1.2實現代碼

public static void sis(String[] original, int from, int length) throws Exception {
        if (from < 0 || length < 0 || from + length > original.length) {
            throw new IllegalArgumentException("Array out of bound .");
        }
        for (int i = from + 1; i < from + length; i++) {
            String temp = original[i];
            int j = i - 1;
            while (j >= 0) {
                if (temp.compareTo(original[j]) < 0) {
                    original[j + 1] = original[j];
                } else {
                    break;
                }
                j--;
            }
            original[j + 1] = temp;
        }
    }

1.3算法分析

  1. 時間複雜度:O(N*N)
  2. 空間複雜度:O(1)
  3. 穩定性:穩定

2.shell排序

2.1 基本思想

shell排序對直接插入排序進行了簡單的改進,他經過加大插入排序中元素之間的間隔,並在這些有間隔的元素中進行插入排序,從而使數據想大跨度地移動,當這些數據排過一趟以後,shell排序減少數據項之間的間隔再進行排序,依次進行下去,直到間隔爲1。算法

2.2實現代碼

public void shellSort(int[] array)
    {
        int increment = array.length;
        do
        {
            increment = increment / 2;  // 增量序列
            for (int i = increment; i < array.length; i++)
            {
                if (array[i] < array[i - increment])
                {
                    Integer guard = array[i];
                    int j;
                    for (j = i - increment; (j >= 0) && (guard < array[j]); j -= increment)     //  記錄後移,查找插入位置
                    {
                        array[j + increment] = array[j];
                    }
                    array[j + increment] = guard;  // 插入
                }
            }
        } while (increment > 1);
    }

2.3算法分析

  1. 時間複雜度:O(N*logN)
  2. 空間複雜度:O(1)
  3. 穩定性:不穩定(通常來講,若存在不相鄰元素間交換,則極可能是不穩定的排序。)

3.直接選擇排序

3.1 算法思想

首先在未排序的區域中找到最小的元素,放到已經排序的最後一位(剛開始的時候放在第一位),依次類推,直到最後一位。shell

3.2 實現代碼

public static void select_sort(int[] a) {

        for (int i = 0; i < a.length; i++) {
            for (int j = i + 1; j < a.length; j++) {
                if (a[i] > a[j]) {
                    swap(a, i, j);
                }
            }
        }
}

    public static void swap(int[] a, int b, int c) {
        if (b == c)
            return;
        a[b] = a[b] ^ a[c];
        a[c] = a[b] ^ a[c];
        a[b] = a[b] ^ a[c];
    }

3.3 算法分析

  1. 時間複雜度:O(N*N)
  2. 空間複雜度:O(1)
  3. 穩定性:不穩定

4.堆排序

4.1 算法思想

利用徹底二叉樹中雙親節點和孩子節點之間的的內在關係,在當前無序區中選擇關鍵字最大(最小)的記錄。也就是說,以最小堆爲例,根節點爲最小元素,較大的節點偏向分佈於堆底部。windows

4.2  代碼實現

//  從i節點開始調整,n爲節點總數 從0開始計算 i節點的子節點爲 2*i+1, 2*i+2  
void MinHeapFixdown(int a[], int i, int n)  
{  
    int j, temp;  
  
    temp = a[i];  
    j = 2 * i + 1;  
    while (j < n)  
    {  
        if (j + 1 < n && a[j + 1] < a[j]) //在左右孩子中找最小的  
            j++;  
  
        if (a[j] >= temp)  
            break;  
  
        a[i] = a[j];     //把較小的子結點往上移動,替換它的父結點  
        i = j;  
        j = 2 * i + 1;  
    }  
    a[i] = temp;  
}  
//在最小堆中刪除數  
void MinHeapDeleteNumber(int a[], int n)  
{  
    Swap(a[0], a[n - 1]);  
    MinHeapFixdown(a, 0, n - 1);  
}

4.3 算法分析

  1. 時間複雜度:O(N*logN)
  2. 空間複雜度:O(1)
  3. 穩定性:不穩定
  4. 此外,創建堆的時間複雜度爲O(N)

5. 冒泡排序

5.1 算法思想

經過無序區中相鄰記錄關鍵字間的比較和位置的交換,使關鍵字最小的記錄如氣泡通常逐漸往上「漂浮」直至「水面」。數組

5.2 實現代碼

for (int i = 0; i < score.length -1; i++){    //最多作n-1趟排序  
            for(int j = 0 ;j < score.length - i - 1; j++){    //對當前無序區間score[0......length-i-1]進行排序(j的範圍很關鍵,這個範圍是在逐步縮小的)  
                if(score[j] > score[j + 1]){    //把大的值交換到後面  
                    int temp = score[j];  
                    score[j] = score[j + 1];  
                    score[j + 1] = temp;  
                }  
            }      
}

5.3 算法分析

  1. 時間複雜度:O(N*N)
  2. 空間複雜度:O(1)
  3. 穩定性:穩定

6.快速排序

6.1 算法思想

它是由冒泡排序改進而來的。在待排序的n個記錄中任取一個記錄(一般取第一個記錄),把該記錄放入適當位置後,數據序列被此記錄劃分紅兩部分。全部關鍵字比該記錄關鍵字小的記錄放置在前一部分,全部比它大的記錄放置在後一部分,並把該記錄排在這兩部分的中間(稱爲該記錄歸位),這個過程稱做一趟快速排序。ui

6.2 實現代碼

public int getMiddle(Integer[] list, int low, int high) {  
        int tmp = list[low];    //數組的第一個做爲中軸  
        while (low < high) {  
            while (low < high && list[high] > tmp) {  
                high--;  
            }  
            list[low] = list[high];   //比中軸小的記錄移到低端  
            while (low < high && list[low] < tmp) {  
                low++;  
            }  
            list[high] = list[low];   //比中軸大的記錄移到高端  
        }  
        list[low] = tmp;              //中軸記錄到尾  
        return low;                   //返回中軸的位置  
    }
public void _quickSort(Integer[] list, int low, int high) {  
        if (low < high) {  
            int middle = getMiddle(list, low, high);  //將list數組進行一分爲二  
            _quickSort(list, low, middle - 1);        //對低字表進行遞歸排序  
            _quickSort(list, middle + 1, high);       //對高字表進行遞歸排序  
        }  
    }

6.3 算法分析

  1. 時間複雜度:O(N*logN)
  2. 空間複雜度:O(N*logN)
  3. 穩定性:不穩定

(未完待續。。)spa

 

參考文獻:

http://blog.csdn.net/wisgood/article/details/19702035.net

http://www.cnblogs.com/vanezkw/archive/2012/06/25/2561167.htmlcode

http://blog.csdn.net/gulianchao/article/details/8581210

http://www.cnblogs.com/e241138/archive/2012/10/17/2728633.html

http://blog.csdn.net/morewindows/article/details/6709644

http://blog.csdn.net/wangkuifeng0118/article/details/7286332

相關文章
相關標籤/搜索