導語
在計算機軟件專業中,算法分析與設計是一門非常重要的課程,很多人爲它如癡如醉。很多問題的解決,程序的編寫都要依賴它,在軟件還是面向過程的階段,就有‘程序=算法+數據結構’這個公式。算法的學習對於培養一個人的邏輯思維能力是有極大幫助的,它可以培養 我們養成思考分析問題,解決問題的能力。 如果一個算法有缺陷,或不適合某個問題,執行這個算法將不會解決這個問題。不同的算法可能用不同的時間、空間或效率來完成同樣的任務。一個算法的優劣可以用空間複雜性和時間複雜度來衡量。算法可以使用自然語言、僞代碼、流程圖等多種不同的方法來描述。計算機系統中的操作系統、語言編譯系統、數據庫管理系統以及各種各樣的計算機應用系統中的軟件,都必須使用具體的算法來實現。算法設計與分析是計算機科學與技術的一個核心問題。因此,學習算法無疑會增強自己的競爭力,提高自己的修爲,爲自己增彩。
算法概念:算法簡單來說就是指解題方案的準確而完整的描述,是一系列解決問題的清晰指令,也就是說算法告訴計算機怎麼做,以此來解決問題。同一個問題存在多種算法來解決它,但是這些算法存在着優劣之分,好的算法速度快,效率高,佔用空間小,差的算法不僅複雜難懂,而且效率低,對機器要求還高,當然,有時候算法之間存在一種互補關係,有些算法效率高,節省時間,但浪費空間,另外一些算法可能速度上慢些,但是空間比較節約,這時候 我們就應該根據實際要求,和具體情況來採取相應的算法來解決問題。
案例demo下載:http://download.csdn.net/download/csdn_aiyang/9943795
一、快速排序
快速排序是由東尼·霍爾所發展的一種排序算法。在平均狀況下,排序 n 個項目要Ο(n log n)次比較。在最壞狀況下則需要Ο(n2)次比較,但這種狀況並不常見。事實上,快速排序通常明顯比其他Ο(n log n) 算法更快,因爲它的內部循環(inner loop)可以在大部分的架構上很有效率地被實現出來,且在大部分真實世界的數據,可以決定設計的選擇,減少所需時間的二次方項之可能性。
步驟:
從數列中挑出一個元素,稱爲 "基準"(pivot),重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分區退出之後,該基準就處於數列的中間位置。這個稱爲分區(partition)操作。遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。
排序效果:
代碼:
- //快速排序
- private void quickSort(int[] a ,int left,int right) {
- if(left < right){
- int i,j,t,temp;
- temp=a[left]; //temp中存的就是基準數
- i=left;
- j=right;
- while(i!=j)
- {
- //順序很重要,要先從右邊開始找
- while(a[j]>=temp && i<j)
- j--;
- //再找右邊的
- while(a[i]<=temp && i<j)
- i++;
- //交換兩個數在數組中的位置
- if(i<j)
- {
- t=a[i];
- a[i]=a[j];
- a[j]=t;
- }
- }
- //最終將基準數歸位
- a[left]=a[i];
- a[i]=temp;
- quickSort(a,left,i-1);//繼續處理左邊的,這裏是一個遞歸的過程
- quickSort(a,i+1,right);//繼續處理右邊的 ,這裏是一個遞歸的過程
- }
- }
- quickSort(a,0,a.length-1);
二、歸併排序
介紹:
歸併排序(Merge sort,臺灣譯作:合併排序)是建立在歸併操作上的一種有效的排序算法。該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。
步驟:
申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列;
設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置;
比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置;
重複步驟3直到某一指針達到序列尾;
將另一序列剩下的所有元素直接複製到合併序列尾。
排序效果:
三、堆排序
介紹:
堆積排序(Heapsort)是指利用堆這種數據結構所設計的一種排序算法。堆是一個近似完全二叉樹的結構,並同時滿足堆性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。
步驟:
比較複雜,自己上網查一下吧~
排序效果:
四、選擇排序
介紹:
選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小元素,然後放到排序序列末尾。以此類推,直到所有元素均排序完畢。
排序效果:
代碼:
- //選擇排序
- public void selectSort(int[] array) {
- int min;
- int tmp = 0;
- for (int i = 0; i < array.length; i++) {
- min = array[i];
- for (int j = i; j < array.length; j++) {
- if (array[j] < min) {
- min = array[j];//最小值
- tmp = array[i];
- array[i] = min;
- array[j] = tmp;
- }
- }
- }
- }
五、冒泡排序
介紹:
冒泡排序(Bubble Sort,臺灣譯爲:泡沫排序或氣泡排序)非常簡單的排序算法。它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個算法的名字由來是因爲越小的元素會經由交換慢慢“浮”到數列的頂端。
步驟:
- 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
- 對每一對相鄰元素作同樣操作,從開始第一對到結尾的最後一對。在這一點,最後的元素會是最大的數。
- 針對所有的元素重複以上的步驟,除了最後一個。
- 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
代碼:
- //冒泡
- private void pubbleSort(int[] numbers) {
- int temp;//記錄臨時變量
- int size = numbers.length;//數組大小
- for (int i = 0; i < size - 1; i++) {
- for (int j = i + 1; j < size; j++) {//索引不同的兩層for循環
- if (numbers[i] < numbers[j]) {//交互數據從大到小排列順序 大的放前面
- temp = numbers[i];
- numbers[i] = numbers[j];
- numbers[j] = temp;
- }
- }
- }
- }
排序效果:
六、插入排序
介紹:
插入排序(Insertion Sort)的算法描述是一種簡單直觀的排序算法。它的工作原理是通過構建有序序列,對於未排序數據,在已排序序列中從後向前掃描,找到相應位置並插入。插入排序在實現上,通常採用in-place排序(即只需用到O(1)的額外空間的排序),因而在從後向前掃描過程中,需要反覆把已排序元素逐步向後挪位,爲最新元素提供插入空間。
步驟:
- 從第一個元素開始,該元素可以認爲已經被排序;
- 取出下一個元素,在已經排序的元素序列中從後向前掃描;
- 如果該元素(已排序)大於新元素,將該元素移到下一位置;
- 重複步驟3,直到找到已排序的元素小於或者等於新元素的位置;
- 將新元素插入到該位置中,重複步驟2。
排序代碼:
- //直接插入
- private void InsertSort(int[] a) {
- long t1 = System.nanoTime();
- //直接插入排序
- for (int i = 1; i < a.length; i++) {
- //待插入元素
- int temp = a[i];
- int j;
- for (j = i - 1; j >= 0; j--) {
- //將大於temp的往後移動一位
- if (a[j] > temp) {
- a[j + 1] = a[j];
- } else {
- break;
- }
- }
- a[j + 1] = temp;//插入進來
- }
- }
七、希爾排序
介紹:
希爾排序,也稱遞減增量排序算法,是插入排序的一種高速而穩定的改進版本。基於插入排序的以下兩點性質而提出改進方法的:
- 插入排序在對幾乎已經排好序的數據操作時,效率高,即可以達到線性排序的效率;
- 但插入排序一般來說是低效的, 因爲插入排序每次只能將數據移動一位。
代碼:
- //希爾排序
- private void HeerSort(int[] a) {
- int d = a.length / 2;
- while (true) {
- for (int i = 0; i < d; i++) {
- for (int j = i; j + d < a.length; j += d) {
- int temp;
- if (a[j] > a[j + d]) {
- temp = a[j];
- a[j] = a[j + d];
- a[j + d] = temp;
- }
- }
- }
- if (d == 1) {
- break;
- }
- d--;
- }
- }
(參考)同一手機效率跑分:15052