日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java排序算法总结_排序算法总结及Java实现

發布時間:2025/3/21 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java排序算法总结_排序算法总结及Java实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 整體介紹

分類

排序大的分類可以分為兩種,內排序和外排序。在排序過程中,全部記錄存放在內存,則稱為內排序,如果排序過程中需要使用外存,則稱為外排序。主要需要理解的都是內排序算法:

內排序可以分為以下幾類:

(1)、插入排序:直接插入排序、二分法插入排序、希爾排序。

(2)、選擇排序:簡單選擇排序、堆排序。

(3)、交換排序:冒泡排序、快速排序。

(4)、歸并排序

(5)、基數排序

性能對比

穩定性:就是能保證排序前兩個相等的數據其在序列中的先后位置順序與排序后它們兩個先后位置順序相同。即如果A?i == A?j,A?i原來在?A?j 位置前,排序后?Ai??仍然是在?Aj?位置前。

不穩定:簡單選擇排序、快速排序、希爾排序、堆排序不是穩定的排序算法

穩定:冒泡排序、直接插入排序、二分法插入排序,歸并排序和基數排序都是穩定的排序算法。

時間復雜度:一個算法執行所耗費的時間。

O(nlogn):快速排序,歸并排序,希爾排序,堆排序。

O(n^2):直接插入排序,簡單選擇排序,冒泡排序。

O(n): 桶、箱、基數排序

快速排序是目前基于比較的內部排序中最好的方法, 其次是歸并和希爾,堆排序在數據量很大時效果明顯。當數據是隨機分布時快速排序的平均時間最短。

空間復雜度:運行完一個程序所需內存的大小。

解釋:n: 數據規模;k:“桶”的個數;In-place: 占用常數內存,不占用額外內存;Out-place: 占用額外內存。

排序方法的選擇

1.數據規模很小(插入、簡單選擇、冒泡)

(1)數據基本有序的情況下,可選直接插入排序;

(2)數據無序時,對穩定性不作要求宜用簡單選擇排序,對穩定性有要求宜用插入或冒泡

2.數據規模一般(快速排序、歸并排序)

(1)完全可以用內存空間,序列雜亂無序,對穩定性沒有要求,快速排序,此時要付出log(N)的額外空間。

(2)序列本身可能有序,對穩定性有要求,空間允許下,宜用歸并排序

3.數據規模很大(歸并、桶)

(1)對穩定性有求,則可考慮歸并排序。

(2)對穩定性沒要求,宜用堆排序

4.待排序列初始基本有序(正序),宜用直接插入,冒泡

2. 插入排序(Insertion Sort)

基本思想:依次遍歷元素,在已排序的序列中找到合適的位置將當前遍歷的元素插入,直到所有元素都已排序。

方法:直接插入排序、二分插入排序、希爾排序

2.1 直接插入排序

算法思想:

<1>.從第一個元素開始,該元素可以認為已經被排序;

<2>.取出下一個元素,在已經排序的元素序列中從后向前掃描;

<3>.如果該元素(已排序)大于新元素,將該已排序元素移到下一位置;

<4>.重復步驟3,直到找到已排序的元素小于或者等于新元素的位置;

<5>.將新元素插入到該位置后;

<6>.重復步驟2~5。

時間復雜度:平均情況下:O(n-2)??????? 最好的情況下:正序有序(從小到大),這樣只需要比較n次,不需要移動。因此時間復雜度為O(n)

最壞的情況下:逆序有序,這樣每一個元素就需要比較n次,共有n個元素,因此實際復雜度為O(n-2)

穩定性:穩定。由算法思想易知,反向遍歷已排序元素,若已排序元素小于等于當前元素,則將當前元素插入該已排序元素后的位置,因此相對順序不變,插入排序是穩定的。

Java實現:

public int[] insertSort(int[] arr){//從前向后遍歷待排序列

for (int i = 1; i < arr.length; i++) {//當前正在遍歷的元素值

int key =arr[i];//從后向前掃描已排序序列,依次與當前元素對比

int j = i - 1;while(j >= 0 && arr[j] >key){

arr[j+1] =arr[j];

j--;

}

arr[j+1] =key;

}returnarr;

}

2.2 二分排序(折半插入排序)

二分法查找基本思想:對于一個有序的待查序列,定義三個指針low、high、mid,分別指向待查序列所在范圍的下界、上界及區間中間位置,即mid=(low+high)/2。對比待查數據與mid所指的值,若相等則查找成功并返回mid,若待查數小于mid值,則令high=mid-1,否則令low=mid+1,得到新的需要查找的區間,如此循環直到找出或找不到。如下示例:

二分排序:從第二個數開始往后遍歷,用二分法查找合適的插入位置。當low

時間復雜度:二分插入排序的比較次數與待排序記錄的初始狀態無關,僅依賴于記錄的個數。當n較大時,比直接插入排序的最大比較次數少得多。但大于直接插入排序的最小比較次數。算法的移動次數與直接插入排序算法的相同,最壞的情況為n2/2,最好的情況為n,平均移動次數為O(n2)。

穩定性:穩定。

Java實現:

public int[] binaryInsertSort(int[] arr) {intlow, high, mid;intkey;for (int i = 1; i < arr.length; i++) {

key=arr[i];

low= 0;

high= i - 1;//執行二分查找,注意符號(

while(low <=high){

mid= (low + high)/2;if (key

high= mid -1;

}else{

low= mid + 1;

}

}//二分查找終止,說明找到合適的位置low//將low位置及之后的所有元素右移一位,再將當前遍歷元素插入到low處

for (int j = i - 1; j >= low; j--) {

arr[j+1] =arr[j];

}

arr[low]=key;

}returnarr;

}

2.3 希爾排序(Shell Sort)

基本思想:希爾排序也是一種插入排序方法,實際上是一種分組插入方法。先取定一個小于n的整數d1作為第一個增量,這樣可以把表的全部記錄分成d1個組:所有距離為d1的倍數的記錄放在同一個組中,在各組內進行直接插入排序;然后,取第二個增量d2(<d1),重復上述的分組和排序,直至所取的增量dt=1(dt

希爾排序的核心在于間隔序列的設定。既可以提前設定好間隔序列,也可以動態的定義間隔序列。

時間復雜度: ?平均情況下:O(N*logN)? ? ? ?最好情況:由于希爾排序的好壞和步長d的選擇(di到di+1的選擇策略)有很多關系,因此,目前還沒有得出最好的步長如何選擇(現在有些比較好的選擇了,但不確定是否是最好的)。所以,不知道最好的情況下的算法時間復雜度。

最壞情況:O(N*logN),最壞的情況下和平均情況下差不多。

穩定性:由于多次插入排序,我們知道一次插入排序是穩定的,不會改變相同元素的相對順序,但在不同趟的插入排序過程中,相同的元素可能在各自的插入排序中移動,最后其穩定性就會被打亂,所以shell排序是不穩定的。(有個猜測,方便記憶:一般來說,若存在不相鄰元素間交換,則很可能是不穩定的排序。)

Java實現:

public int[] shellSort(int[] arr) {//分組

int d = arr.length/2; //初始增量

while(d > 0){for (int i = d; i < arr.length; i++) { //i是當前等待插入的元素的本來位置

int key =arr[i];int j = i - d; //j用來循環,i位置之前待比較的元素序列

while(j >= 0 && arr[j] > arr[i]){ //待插入元素小了

arr[j+d] = arr[j]; //比待插入元素大的都往后移,類似于直接插入排序,但是增量由1改為d

j = j - d; //比較已排序序列的前一位置元素

}

arr[j+d] = key; //跳出循環說明找到當前a[j]

}

d= d / 2; //步長算法,可以優化

}returnarr;

}

解釋:就是將增量(d)為1的直接插入排序,增量改為從d到1的遞減。不再是相鄰元素間的對比,而是以d為間隔的對比插入。

3. 交換排序

3.1 冒泡排序(Bubble Sort)

基本思想:通過無序區中相鄰記錄關鍵字間的比較和位置的交換,使關鍵字最小的記錄如氣泡一般逐漸往上“漂浮”直至“水面”。

時間復雜度:平均O(n2)

最好情況:正序有序,則只需要比較n次。故,為O(n)

最壞情況:逆序有序,則需要比較(n-1)+(n-2)+……+1,故,為O(N2)

穩定性:穩定。排序過程中只交換相鄰兩個元素的位置。因此,當兩個數相等時,是沒必要交換兩個數的位置的。所以相對位置并沒有改變,冒泡排序算法是穩定的!

算法描述:

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

<2>.對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最后一對,這樣在最后的元素應該會是最大的數;

<3>.針對所有的元素重復以上的步驟,除了最后一個;

<4>.重復步驟1~3,直到排序完成。

Java實現:

public int[] bubbleSort(int[] arr) {for (int i = arr.length - 1; i >= 0; i--) {for (int j = 0; j < i; j++) {if (arr[j]>arr[j+1]) {

swap(arr[j], arr[j+1]);

}

}

}returnarr;

}/*** 交換兩個數*/

public void swap(int a, intb) {int temp =a;

a=b;

b=temp;

}

冒泡排序改進1:設置一標志性變量pos,用于記錄每趟排序中最后一次進行交換的位置。由于pos位置之后的記錄均已交換到位,故在進行下一趟排序時只要掃描到pos位置即可。因為上一輪冒泡的最后一次交換說明該交換的元素是其位置以前的所有元素中最大的(畢竟是自己冒上來的)。下一趟找最大元素的冒泡從該位置開始即可,不必從頭開始兩兩交換

Java實現:

public int[] bubbleSort2(int[] arr){for (int i = arr.length - 1; i >= 0; i--) {int pos = 0; //每趟開始,無交換記錄

for (int j = 0; j < i; j++) {if (arr[j]>arr[j+1]) {

swap(arr[j], arr[j+1]);

pos= j; //記錄交換位置

}

i= pos; //從上輪交換最后一次交換的位置開始兩兩對比

}

}returnarr;

}

3.2?快速排序(Quick Sort)

基本思想:由冒泡排序改進而來的。在待排序的n個記錄中任取一個記錄(通常取第一個記錄),把該記錄放入適當位置后,數據序列被此記錄劃分成兩部分。所有關鍵字比該記錄關鍵字小的記錄放置在前一部分,所有比它大的記錄放置在后一部分,并把該記錄排在這兩部分的中間(稱為該記錄歸位)。

核心思想:通過一趟排序將待排記錄分隔成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。

時間復雜度:O(N*logN)

最好的情況:因為每次都將序列分為兩個部分(一般二分都復雜度都和logN相關),故為 O(N*logN)

最壞的情況:基本有序時,退化為冒泡排序,幾乎要比較N*N次,故為O(N*N)

穩定性:不穩定。由于每次都需要和中軸元素(不一定相鄰)交換,因此原來的順序就可能被打亂。快速排序是不穩定的。

算法描述:

快速排序使用分治法來把一個串(list)分為兩個子串(sub-lists)。具體算法描述如下:

<1>.從數列中挑出一個元素,稱為 "基準"(pivot);

<2>.重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的后面(相同的數可以到任一邊)。在這個分區退出之后,該基準就處于數列的中間位置。這個稱為分區(partition)操作;

<3>.遞歸地(recursive)把小于基準值元素的子數列和大于基準值元素的子數列排序。

Java實現:

public int[] quickSort(int[] arr,int low,inthigh){int i =low;int j =high;//if ((arr == null) || (arr.length == 0)){//return null;//}

while (i < j) { //查找基準點下標

while (i < j && arr[i] <= arr[j]) //以數組start下標的數據為key,右側掃描

j--;

swap(arr[i], arr[j]);//從右往左掃描,找出第一個比key小的,交換位置

while (i < j && arr[i] < arr[j]) //從左往右掃描(此時a[j]中存儲著key值)

i++;

swap(arr[i], arr[j]);//找出第一個比key大的,交換位置

}if (i - low > 1) { //遞歸調用,把key前面的完成排序

quickSort(arr, 0, i - 1);

}if (high - j > 1) {

quickSort(arr, j+ 1, high); //遞歸調用,把key后面的完成排序

}returnarr;

}

4. 選擇排序

4.1 簡單選擇排序(Selection Sort)

基本思想:首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再從剩余未排序元素中繼續尋找最小元素,然后放到排序序列末尾。以此類推,直到所有元素均排序完畢。具體做法是:選擇最小的元素與未排序部分的首部交換,使得序列的前面為有序。

時間復雜度:平均情況下:O(N2)

最好情況:交換0次,但是每次都要找到最小的元素,因此大約必須遍歷N*N次,因此為O(N*N)。減少了交換次數!

最壞情況:平均情況下:O(N*N)

穩定性:不穩定。?由于每次都是選取未排序序列A中的最小元素x與A中的第一個元素交換,因此跨距離了,很可能破壞了元素間的相對位置,因此選擇排序是不穩定的!

算法描述:n個記錄的直接選擇排序可經過n-1趟直接選擇排序得到有序結果。

<1>.初始狀態:無序區為R[1..n],有序區為空;

<2>.第i趟排序(i=1,2,3...n-1)開始時,當前有序區和無序區分別為R[1..i-1]和R(i..n)。該趟排序從當前無序區中-選出關鍵字最小的記錄 R[k],將它與無序區的第1個記錄R交換,使R[1..i]和R[i+1..n)分別變為記錄個數增加1個的新有序區和記錄個數減少1個的新無序區;

<3>.n-1趟結束,數組有序化了。

Java實現:

public int[] selectionSort(int[] arr) {intminIndex;inttemp;//一趟找出一個最小值

for (int i = 0; i < arr.length - 1; i++) {

minIndex=i;for (int j = i + 1; j < arr.length ; j++) {if (arr[j]

minIndex=j;

}

}//將找到的最小值放到已排序序列的末尾

temp =arr[minIndex];

arr[minIndex]=arr[i];

arr[i]=temp;

}returnarr;

}

4.2 堆排序(Heap Sort)

基本思想:堆排序(Heapsort)是指利用堆這種數據結構所設計的一種排序算法。堆積是一個近似完全二叉樹的結構,并同時滿足堆積的性質:即子結點的鍵值或索引總是小于(或者大于)它的父節點。用完全二叉樹中雙親節點和孩子節點之間的內在關系,在當前無序區中選擇關鍵字最大(或者最小)的記錄。也就是說,以最小堆為例,根節點為最小元素,較大的節點偏向于分布在堆底附近。

時間復雜度:O(nlogn)。最壞情況下,接近于最差情況下:O(N*logN),因此它是一種效果不錯的排序算法。

穩定性:不穩定。需要不斷地調整堆。

算法描述:

<1>.將初始待排序關鍵字序列(R1,R2....Rn)構建成大頂堆,此堆為初始的無序區;

<2>.將堆頂元素R[1]與最后一個元素R[n]交換,此時得到新的無序區(R1,R2,......Rn-1)和新的有序區(Rn),且滿足R[1,2...n-1]<=R[n];

<3>.由于交換后新的堆頂R[1]可能違反堆的性質,因此需要對當前無序區(R1,R2,......Rn-1)調整為新堆,然后再次將R[1]與無序區最后一個元素交換,得到新的無序區(R1,R2....Rn-2)和新的有序區(Rn-1,Rn)。不斷重復此過程直到有序區的元素個數為n-1,則整個排序過程完成。

Java實現:

5. 歸并排序

基本思想:多次將兩個或兩個以上的有序表合并成一個新的有序表。

時間復雜度:O(nlogn)

最好情況:一趟歸并需要n次,總共需要logN次,因此為O(N*logN)

最壞情況:接近于平均情況下,為O(N*logN)

穩定性:歸并排序最大的特色就是它是一種穩定的排序算法。歸并過程中是不會改變元素的相對位置的。

缺點:它需要O(n)的額外空間。但是很適合于多鏈表排序。

6. 基數排序

基本思想:它是一種非比較排序。它是根據位的高低進行排序的,也就是先按個位排序,然后依據十位排序……以此類推。示例如下:

時間復雜度:分配需要O(n),收集為O(r),其中r為分配后鏈表的個數,以r=10為例,則有0~9這樣10個鏈表來將原來的序列分類。而d,也就是位數(如最大的數是1234,位數是4,則d=4),即"分配-收集"的趟數。因此時間復雜度為O(d*(n+r))

穩定性:穩定。

適用情況:如果有一個序列,知道數的范圍(比如1~1000),用快速排序或者堆排序,需要O(N*logN),但是如果采用基數排序,則可以達到O(4*(n+10))=O(n)的時間復雜度。算是這種情況下排序最快的!!

基數排序 vs 計數排序 vs 桶排序

這三種排序算法都利用了桶的概念,但對桶的使用方法上有明顯差異:

基數排序:根據鍵值的每位數字來分配桶

計數排序:每個桶只存儲單一鍵值

桶排序:每個桶存儲一定范圍的數值

參考鏈接:

http://www.cnblogs.com/jztan/p/5878630.html

http://blog.chinaunix.net/uid-25906157-id-3318529.html

http://www.cnblogs.com/leeplogs/p/5863846.html

總結

以上是生活随笔為你收集整理的java排序算法总结_排序算法总结及Java实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲人和日本人hd | 欧性猛交ⅹxxx乱大交 | 日产毛片 | 秋霞三区 | 男女扒开双腿猛进入爽爽免费 | 日韩在线视频免费看 | 日韩h在线 | 欧美资源 | 男人的天堂国产 | 另类中文字幕 | 国产拍拍视频 | 无码精品在线视频 | 在线观看免费高清视频 | 成人免费看黄 | 午夜精品一区二区三区在线 | 国产精品视频在线观看 | 日本中文字幕在线视频 | 91av影视 | 日韩一区二区视频在线播放 | 爱爱福利社| 欧美精品性生活 | 91视频一区二区 | 亚洲成人黄 | 国产又粗又黄视频 | 不卡影院av | 天天干中文字幕 | 中文字幕av影院 | 国产精视频 | 成人性生活免费看 | 亚州av在线 | 亚洲自拍另类 | 一区二区三区在线观看av | 影音先锋中文字幕资源 | 免费美女视频网站 | 2019中文字幕在线 | 亚洲国产情侣 | 靠逼网站在线观看 | 天堂网视频在线 | 国产高清片 | 麻豆成人av| 99精品视频在线观看 | 亚洲成人高清在线 | 99热久久这里只有精品 | 国产精品毛片一区二区在线看舒淇 | 日本成人社区 | 精品国产乱码一区二区 | 精品亚洲国产成av人片传媒 | 久久香蕉影视 | 天天干,天天操 | av一区二区三区在线观看 | 欧美另类videosbestsex | 成人福利在线观看 | 在线国产中文字幕 | 胸网站| 看黄色小视频 | 红色假期黑色婚礼2 | 国产欧美综合在线 | 国产一级精品视频 | 美女扒开尿口让男人捅爽 | 久久99九九 | 森泽佳奈作品在线观看 | 就爱av | 打屁股疼的撕心裂肺的视频 | 国产成人精品在线 | 男人的天堂免费视频 | 欧美激情午夜 | 国产大屁股喷水视频在线观看 | 色视频在线观看 | 成人黄色电影网址 | 亚洲一区二区三区四区在线观看 | 99资源站| 久久久久久国产免费a片 | 国产调教在线 | 成人在线直播 | 亚洲综合站 | www毛片| 日韩精品1区2区 | 国产91精品看黄网站在线观看 | 两个女人互添下身爱爱 | 成人激情电影在线观看 | 亚洲第一狼人区 | 激情偷乱人成视频在线观看 | 久操av | 中文字幕精品久久久久人妻红杏ⅰ | 大色av| 欧美在线国产 | 日屁视频| 一区二区三区四区亚洲 | 综合九九 | 天天狠天天插天天透 | av在线不卡免费观看 | 欧美综合在线视频 | 日韩jizz | 亚洲成人免费 | 色诱av | 在线视频免费观看一区 | 97爱爱视频 | 三浦理惠子av在线播放 | 欧美日韩一卡二卡三卡 |