Android 算法排序面試——七大基礎算法

導語

在計算機軟件專業中,算法分析與設計是一門非常重要的課程,很多人爲它如癡如醉。很多問題的解決,程序的編寫都要依賴它,在軟件還是面向過程的階段,就有‘程序=算法+數據結構’這個公式。算法的學習對於培養一個人的邏輯思維能力是有極大幫助的,它可以培養 我們養成思考分析問題,解決問題的能力。    如果一個算法有缺陷,或不適合某個問題,執行這個算法將不會解決這個問題。不同的算法可能用不同的時間、空間或效率來完成同樣的任務。一個算法的優劣可以用空間複雜性和時間複雜度來衡量。算法可以使用自然語言、僞代碼、流程圖等多種不同的方法來描述。計算機系統中的操作系統、語言編譯系統、數據庫管理系統以及各種各樣的計算機應用系統中的軟件,都必須使用具體的算法來實現。算法設計與分析是計算機科學與技術的一個核心問題。因此,學習算法無疑會增強自己的競爭力,提高自己的修爲,爲自己增彩。


算法概念:算法簡單來說就是指解題方案的準確而完整的描述,是一系列解決問題的清晰指令,也就是說算法告訴計算機怎麼做,以此來解決問題。同一個問題存在多種算法來解決它,但是這些算法存在着優劣之分,好的算法速度快,效率高,佔用空間小,差的算法不僅複雜難懂,而且效率低,對機器要求還高,當然,有時候算法之間存在一種互補關係,有些算法效率高,節省時間,但浪費空間,另外一些算法可能速度上慢些,但是空間比較節約,這時候 我們就應該根據實際要求,和具體情況來採取相應的算法來解決問題。


案例demo下載:http://download.csdn.net/download/csdn_aiyang/9943795 


一、快速排序


介紹:

快速排序是由東尼·霍爾所發展的一種排序算法。在平均狀況下,排序 n 個項目要Ο(n log n)次比較。在最壞狀況下則需要Ο(n2)次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他Ο(n log n) 算法更快,因爲它的內部循環(inner loop)可以在大部分的架構上很有效率地被實現出來,且在大部分真實世界的數據,可以決定設計的選擇,減少所需時間的二次方項之可能性。

步驟:

從數列中挑出一個元素,稱爲 "基準"(pivot),重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分區退出之後,該基準就處於數列的中間位置。這個稱爲分區(partition)操作。遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。

排序效果:

代碼:

[java] view plain copy
  1. //快速排序  
  2.     private void quickSort(int[]  a ,int left,int right) {  
  3.         if(left < right){  
  4.             int i,j,t,temp;  
  5.             temp=a[left]; //temp中存的就是基準數  
  6.             i=left;  
  7.             j=right;  
  8.             while(i!=j)  
  9.             {  
  10.                 //順序很重要,要先從右邊開始找  
  11.                 while(a[j]>=temp && i<j)  
  12.                     j--;  
  13.                 //再找右邊的  
  14.                 while(a[i]<=temp && i<j)  
  15.                     i++;  
  16.                 //交換兩個數在數組中的位置  
  17.                 if(i<j)  
  18.                 {  
  19.                     t=a[i];  
  20.                     a[i]=a[j];  
  21.                     a[j]=t;  
  22.                 }  
  23.             }  
  24.             //最終將基準數歸位  
  25.             a[left]=a[i];  
  26.             a[i]=temp;  
  27.             quickSort(a,left,i-1);//繼續處理左邊的,這裏是一個遞歸的過程  
  28.             quickSort(a,i+1,right);//繼續處理右邊的 ,這裏是一個遞歸的過程  
  29.         }  
  30.     }  
[java] view plain copy
  1. quickSort(a,0,a.length-1);  
(參考)同一手機效率跑分:20573

二、歸併排序


介紹:

歸併排序(Merge sort,臺灣譯作:合併排序)是建立在歸併操作上的一種有效的排序算法。該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。

步驟:

申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列;

設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置;

比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置;

重複步驟3直到某一指針達到序列尾;

將另一序列剩下的所有元素直接複製到合併序列尾。

排序效果:

三、堆排序


介紹:

堆積排序(Heapsort)是指利用堆這種數據結構所設計的一種排序算法。堆是一個近似完全二叉樹的結構,並同時滿足堆性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。

步驟:

比較複雜,自己上網查一下吧~

排序效果:

四、選擇排序

介紹:

選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小元素,然後放到排序序列末尾。以此類推,直到所有元素均排序完畢。

排序效果:


代碼:

[java] view plain copy
  1. //選擇排序  
  2.     public void selectSort(int[] array) {  
  3.         int min;  
  4.         int tmp = 0;  
  5.         for (int i = 0; i < array.length; i++) {  
  6.             min = array[i];  
  7.             for (int j = i; j < array.length; j++) {  
  8.                 if (array[j] < min) {  
  9.                     min = array[j];//最小值  
  10.                     tmp = array[i];  
  11.                     array[i] = min;  
  12.                     array[j] = tmp;  
  13.                 }  
  14.             }  
  15.         }  
  16.     }  
(參考)同一手機效率跑分:16927



五、冒泡排序

介紹:

冒泡排序(Bubble Sort,臺灣譯爲:泡沫排序或氣泡排序)非常簡單的排序算法。它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個算法的名字由來是因爲越小的元素會經由交換慢慢“浮”到數列的頂端。


步驟:

  • 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
  • 對每一對相鄰元素作同樣操作,從開始第一對到結尾的最後一對。在這一點,最後的元素會是最大的數。
  • 針對所有的元素重複以上的步驟,除了最後一個。
  • 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。

代碼:

[java] view plain copy
  1. //冒泡  
  2.    private void pubbleSort(int[] numbers) {  
  3.        int temp;//記錄臨時變量  
  4.        int size = numbers.length;//數組大小  
  5.        for (int i = 0; i < size - 1; i++) {  
  6.            for (int j = i + 1; j < size; j++) {//索引不同的兩層for循環  
  7.                if (numbers[i] < numbers[j]) {//交互數據從大到小排列順序  大的放前面  
  8.                    temp = numbers[i];  
  9.                    numbers[i] = numbers[j];  
  10.                    numbers[j] = temp;  
  11.                }  
  12.            }  
  13.        }  
  14.    }  
(參考)同一手機效率跑分:11927

排序效果:


六、插入排序


介紹:

插入排序(Insertion Sort)的算法描述是一種簡單直觀的排序算法。它的工作原理是通過構建有序序列,對於未排序數據,在已排序序列中從後向前掃描,找到相應位置並插入。插入排序在實現上,通常採用in-place排序(即只需用到O(1)的額外空間的排序),因而在從後向前掃描過程中,需要反覆把已排序元素逐步向後挪位,爲最新元素提供插入空間。

步驟:

  • 從第一個元素開始,該元素可以認爲已經被排序;
  • 取出下一個元素,在已經排序的元素序列中從後向前掃描;
  • 如果該元素(已排序)大於新元素,將該元素移到下一位置;
  • 重複步驟3,直到找到已排序的元素小於或者等於新元素的位置;
  • 將新元素插入到該位置中,重複步驟2。

排序代碼:

[java] view plain copy
  1. //直接插入  
  2.     private void InsertSort(int[] a) {  
  3.         long t1 = System.nanoTime();  
  4.         //直接插入排序  
  5.         for (int i = 1; i < a.length; i++) {  
  6.             //待插入元素  
  7.             int temp = a[i];  
  8.             int j;  
  9.             for (j = i - 1; j >= 0; j--) {  
  10.                 //將大於temp的往後移動一位  
  11.                 if (a[j] > temp) {  
  12.                     a[j + 1] = a[j];  
  13.                 } else {  
  14.                     break;  
  15.                 }  
  16.             }  
  17.             a[j + 1] = temp;//插入進來  
  18.         }  
  19.     }  
(參考)同一手機效率跑分:10000

七、希爾排序

介紹:

希爾排序,也稱遞減增量排序算法,是插入排序的一種高速而穩定的改進版本。基於插入排序的以下兩點性質而提出改進方法的:

    • 插入排序在對幾乎已經排好序的數據操作時,效率高,即可以達到線性排序的效率;
    • 但插入排序一般來說是低效的, 因爲插入排序每次只能將數據移動一位。

代碼:

[java] view plain copy
  1. //希爾排序  
  2.     private void HeerSort(int[] a) {  
  3.         int d = a.length / 2;  
  4.         while (true) {  
  5.             for (int i = 0; i < d; i++) {  
  6.                 for (int j = i; j + d < a.length; j += d) {  
  7.                     int temp;  
  8.                     if (a[j] > a[j + d]) {  
  9.                         temp = a[j];  
  10.                         a[j] = a[j + d];  
  11.                         a[j + d] = temp;  
  12.                     }  
  13.                 }  
  14.             }  
  15.             if (d == 1) {  
  16.                 break;  
  17.             }  
  18.             d--;  
  19.         }  
  20.     }  

(參考)同一手機效率跑分:15052

排序效果:

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