演算法與排序

2021-08-30 12:30:55 字數 3420 閱讀 9273

關鍵字: 演算法---排序

排序的關鍵字

時間複雜度:整個排序演算法執行所需要的時間。

空間複雜度:排序演算法執行過程彙總所需要額外空間

穩定性:若待排的序列中有大小相同的兩個數,若整個排序過程中不存在兩數次序交換的可能新內閣,則該排序演算法是穩定的。

in-place:演算法使用的額外儲存空間是常數級的

一,最基本的氣泡排序——bubble sort。

public

void swap(int data, int i, int j)

}二,氣泡排序(遞增)

氣泡排序,是所有排序中最簡單的一種,也是效率最低的一種,時間複雜度o(n2),空間複雜度o(n)。氣泡排序沒有改變原始元素的相對位置,因此是穩定的排序。

public

void bubble_sort(int data) }}

}三,插入排序(遞增)

插入排序也是一種比較簡單的排序方法,它的基本原理就好似我們打牌過程中摸牌理牌那一環,當你摸到一張牌後將其插入到合適的位置。

插入排序首先定位乙個數(一般從第二個開始),將這個數依次與位於它之前的數進行比較,經過一輪比較,找到它在這些數中適當的位置。然後定位下乙個數,再找到合適的為止,依次進行直到最後乙個數。

例如(5 2 1 4 3),黑體為進行交換的兩數。

public

void insertion_sort(int data) }}

排序插入在資料集較大的時候效率會變得恨低,但是它易於實現,處理小型資料集時效率較高,同時也是穩定的,in-place的,它的時間複雜度是o(n2),空間複雜度是o(n)。

四,選擇排序

選擇排序的工作原理

找到資料集中的最小元素

將最小元素與未排序聲譽元素的第乙個元素交換

對剩餘元素進行以上步驟

它的時間複雜度是o(n2),空間複雜度是o(n),同插入排序類似,它也不適用於大資料集。但是它易於實現,也是一種in-place的排序演算法。對於穩定性:簡易實現是不穩定的,例如(3 5 5 2),在第二輪中第二個五會被認為是最小的,然後同第乙個五進行交換。

public

void selection_sort(int data)

}swap(data, i, minimum);}}

五,elfhash

public int elfhash(string str, int number)

}int result = (hash & 0x7fffffff) % number;

return result;

}六,快速排序

快速排序的步驟:

從陣列中選出乙個中樞數(pivot)

重新排列該陣列,讓陣列中比該數小的數都排在該數的前面,比該數大的數都排在該數的後面。經過這次排序,該數處於其最終為止,並將原陣列分為兩個子陣列(大於它的陣列和小於它的陣列),這就是分段的過程。

遞迴的排列各個子陣列,直至最後整個陣列排序完成。

快速排序的平均時間複雜度為o(nlogn),空間複雜度依據各種實現方式有所不同。

public

int partition(int data, int left, int right, int pivotindex)

}swap(data, storeindex, right); // move pivot to its final place

return storeindex;

}public

void quick_sort(int data, int left, int right)

}七,歸併排序

歸併排序是一種基於比較的排序演算法,在多數的實現方法中它是穩定的。歸併排序可是由計算機祖師級人物——馮諾依曼提出的哦。

歸併排序的過程:

如果資料鏈表的長度為0或1,則返回

將原始資料鍊錶對半分成兩個子鍊錶

對每個子鍊錶遞迴的呼叫合併排序進行排序

合併兩個子煉表使其成為乙個排序完成的鍊錶

歸併排序的時間複雜度為o(nlogn),空間複雜度為o(n)。

public listmergesort(listdata)

int middle = data.size() / 2;

listleft = new arraylist();

listright = new arraylist();

for (int i = 0; i < middle; i++)

for (int i = middle; i < data.size(); i++)

left = mergesort(left);

right = mergesort(right);

listresult = merge(left, right);

return result;

}public listmerge(listleft, listright) else

}if (left.size() > 0)

}if (right.size() > 0)

}return result;

}八,堆排序

堆排序是一種基於比較的排序演算法,它比實現的較好的快速排序慢一些,但是它的平均時間複雜度為o(nlogn),空間複雜度為o(n),它是一種in-place的演算法,但是確實不穩定的排序演算法。

最大堆和最小堆的定義:

根結點(亦稱為堆頂)的關鍵字是堆裡所有節點關鍵字中最小者的堆成為最小堆。

根結點(亦稱為堆頂)的關鍵字是堆裡所有節點關鍵字中最大者的堆成為最大堆。

p.s.:

堆中任一子樹亦是堆。本文討論的堆實際上是二插堆(binary heap),類似地可以定義k叉堆。

堆排序的過程:

根據輸入的資料集建立乙個最大堆(最小堆)

進行堆排序,將root(最大值)與堆的最後乙個元素交換

堆調整,繼續維護成為最大堆

進行步驟2和3,直至排序完成

public

void siftdown(int data, int start, int end)

if (data[root] < data[child]) else }}

這段**是堆排序的核心,對堆中的元素進行調整。簡單來說做的工作就是,即針對乙個堆點,將其與它孩子中較大的那個進行比較,若大不變,若小與該孩子交換位置,若交換後該堆點(處於原先它孩子的位置)仍有孩子則繼續與孩子中較大的那個進行比較,若大不變,若下與該孩子交換位置,調整直至該堆點沒有孩子結束。

public

void heapify(int data, int count)

}這段**是建堆的過程,找到最後乙個有孩子的堆點,對該堆點進行調整,直至調整到root。

public

void heapsort(int data, int count)

}這段**解釋了堆排序的過程,首先建堆,然後將root與堆底元素交換,繼而調整現有堆中root(交換後的root)位置,不斷的調整直至遍歷完整個堆。

java 快速排序演算法與氣泡排序演算法

首先看下 氣泡排序演算法與快速排序演算法的效率 如下的是main方法 description author cuiyaonan2000 163.com date 2014年11月5日 下午1 02 10 public static void main string args long beforeq...

遞迴與排序演算法

程式 資料結構 演算法 遞迴是一種應用非常廣泛的演算法。很多資料結構和演算法的編碼實現都要用到遞迴。排序演算法最經典最常用的冒泡插入選擇,時間複雜度都為o 乙個問題的解可以分解為幾個子問題的解 這個問題與分解之後的子問題,除了資料規模不同,求解思路完全一樣 存在遞迴終止條件 分成遞和歸來看,我覺得和...

遞迴與排序演算法

自己呼叫自己呼叫方法時傳入不同的引數,使 更加簡潔 遞迴的呼叫機制 遞迴可以解決的問題 分類 內部排序 使用記憶體進行排序 外部排序 使用外部儲存排序 內部排序分類 插入排序 交換排序 選擇排序 歸併排序 基數排序 演算法規則 遍歷陣列如果遇到逆序則進行資料交換 public class bubbl...