久久精品日韩无码|61伊人久久绿帽|最新国产浮力网站|亚州aV无码国产|明星一二三区av|超碰人人在线成人|澳门无码福利av

排序算法?

時(shí)間:2024-12-06 18:36 人氣:0 編輯:招聘街

一、排序算法?

各種排序算法的分析及java實(shí)現(xiàn)

  排序一直以來(lái)都是讓我很頭疼的事,以前上《數(shù)據(jù)結(jié)構(gòu)》打醬油去了,整個(gè)學(xué)期下來(lái)才勉強(qiáng)能寫(xiě)出個(gè)冒泡排序。由于下半年要準(zhǔn)備工作了,也知道排序算法的重要性(據(jù)說(shuō)是面試必問(wèn)的知識(shí)點(diǎn)),所以又花了點(diǎn)時(shí)間重新研究了一下。

  排序大的分類(lèi)可以分為兩種:內(nèi)排序和外排序。在排序過(guò)程中,全部記錄存放在內(nèi)存,則稱(chēng)為內(nèi)排序,如果排序過(guò)程中需要使用外存,則稱(chēng)為外排序。下面講的排序都是屬于內(nèi)排序。

  內(nèi)排序有可以分為以下幾類(lèi):

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

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

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

  (4)、歸并排序

  (5)、基數(shù)排序

一、插入排序

?思想:每步將一個(gè)待排序的記錄,按其順序碼大小插入到前面已經(jīng)排序的字序列的合適位置,直到全部插入排序完為止。

?關(guān)鍵問(wèn)題:在前面已經(jīng)排好序的序列中找到合適的插入位置。

?方法:

–直接插入排序

–二分插入排序

–希爾排序

①直接插入排序(從后向前找到合適位置后插入)

  1、基本思想:每步將一個(gè)待排序的記錄,按其順序碼大小插入到前面已經(jīng)排序的字序列的合適位置(從后向前找到合適位置后),直到全部插入排序完為止。

2、實(shí)例

3、java實(shí)現(xiàn)

1 package com.sort;

2

3 public class 直接插入排序 {

4

5 public static void main(String[] args) {

6 int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1};

7 System.out.println("排序之前:");

8 for (int i = 0; i < a.length; i++) {

9 System.out.print(a[i]+" ");

10 }

11 //直接插入排序

12 for (int i = 1; i < a.length; i++) {

13 //待插入元素

14 int temp = a[i];

15 int j;

16 /*for (j = i-1; j>=0 && a[j]>temp; j--) {

17 //將大于temp的往后移動(dòng)一位

18 a[j+1] = a[j];

19 }*/

20 for (j = i-1; j>=0; j--) {

21 //將大于temp的往后移動(dòng)一位

22 if(a[j]>temp){

23 a[j+1] = a[j];

24 }else{

25 break;

26 }

27 }

28 a[j+1] = temp;

29 }

30 System.out.println();

31 System.out.println("排序之后:");

32 for (int i = 0; i < a.length; i++) {

33 System.out.print(a[i]+" ");

34 }

35 }

36

37 }

4、分析

  直接插入排序是穩(wěn)定的排序。

  文件初態(tài)不同時(shí),直接插入排序所耗費(fèi)的時(shí)間有很大差異。若文件初態(tài)為正序,則每個(gè)待插入的記錄只需要比較一次就能夠找到合適的位置插入,故算法的時(shí)間復(fù)雜度為O(n),這時(shí)最好的情況。若初態(tài)為反序,則第i個(gè)待插入記錄需要比較i+1次才能找到合適位置插入,故時(shí)間復(fù)雜度為O(n2),這時(shí)最壞的情況。

  直接插入排序的平均時(shí)間復(fù)雜度為O(n2)。

②二分法插入排序(按二分法找到合適位置插入)

  1、基本思想:二分法插入排序的思想和直接插入一樣,只是找合適的插入位置的方式不同,這里是按二分法找到合適的位置,可以減少比較的次數(shù)。

  2、實(shí)例

3、java實(shí)現(xiàn)

1 package com.sort;

2

3 public class 二分插入排序 {

4 public static void main(String[] args) {

5 int[] a={49,38,65,97,176,213,227,49,78,34,12,164,11,18,1};

6 System.out.println("排序之前:");

7 for (int i = 0; i < a.length; i++) {

8 System.out.print(a[i]+" ");

9 }

10 //二分插入排序

11 sort(a);

12 System.out.println();

13 System.out.println("排序之后:");

14 for (int i = 0; i < a.length; i++) {

15 System.out.print(a[i]+" ");

16 }

17 }

18

19 private static void sort(int[] a) {

20 for (int i = 0; i < a.length; i++) {

21 int temp = a[i];

22 int left = 0;

23 int right = i-1;

24 int mid = 0;

25 while(left<=right){

26 mid = (left+right)/2;

27 if(temp<a[mid]){

28 right = mid-1;

29 }else{

30 left = mid+1;

31 }

32 }

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

34 a[j+1] = a[j];

35 }

36 if(left != i){

37 a[left] = temp;

38 }

39 }

40 }

41 }

4、分析

  當(dāng)然,二分法插入排序也是穩(wěn)定的。

  二分插入排序的比較次數(shù)與待排序記錄的初始狀態(tài)無(wú)關(guān),僅依賴(lài)于記錄的個(gè)數(shù)。當(dāng)n較大時(shí),比直接插入排序的最大比較次數(shù)少得多。但大于直接插入排序的最小比較次數(shù)。算法的移動(dòng)次數(shù)與直接插入排序算法的相同,最壞的情況為n2/2,最好的情況為n,平均移動(dòng)次數(shù)為O(n2)。

③希爾排序

  1、基本思想:先取一個(gè)小于n的整數(shù)d1作為第一個(gè)增量,把文件的全部記錄分成d1個(gè)組。所有距離為d1的倍數(shù)的記錄放在同一個(gè)組中。先在各組內(nèi)進(jìn)行直接插入排序;然后,取第二個(gè)增量d2<d1重復(fù)上述的分組和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有記錄放在同一組中進(jìn)行直接插入排序?yàn)橹埂T摲椒▽?shí)質(zhì)上是一種分組插入方法。

  2、實(shí)例

3、java實(shí)現(xiàn)

1 package com.sort;

2

3 //不穩(wěn)定

4 public class 希爾排序 {

5

6

7 public static void main(String[] args) {

8 int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1};

9 System.out.println("排序之前:");

10 for (int i = 0; i < a.length; i++) {

11 System.out.print(a[i]+" ");

12 }

13 //希爾排序

14 int d = a.length;

15 while(true){

16 d = d / 2;

17 for(int x=0;x<d;x++){

18 for(int i=x+d;i<a.length;i=i+d){

19 int temp = a[i];

20 int j;

21 for(j=i-d;j>=0&&a[j]>temp;j=j-d){

22 a[j+d] = a[j];

23 }

24 a[j+d] = temp;

25 }

26 }

27 if(d == 1){

28 break;

29 }

30 }

31 System.out.println();

32 System.out.println("排序之后:");

33 for (int i = 0; i < a.length; i++) {

34 System.out.print(a[i]+" ");

35 }

36 }

37

38 }

4、分析

  我們知道一次插入排序是穩(wěn)定的,但在不同的插入排序過(guò)程中,相同的元素可能在各自的插入排序中移動(dòng),最后其穩(wěn)定性就會(huì)被打亂,所以希爾排序是不穩(wěn)定的。

  希爾排序的時(shí)間性能優(yōu)于直接插入排序,原因如下:

  (1)當(dāng)文件初態(tài)基本有序時(shí)直接插入排序所需的比較和移動(dòng)次數(shù)均較少。

 ?。?)當(dāng)n值較小時(shí),n和n2的差別也較小,即直接插入排序的最好時(shí)間復(fù)雜度O(n)和最壞時(shí)間復(fù)雜度0(n2)差別不大。

 ?。?)在希爾排序開(kāi)始時(shí)增量較大,分組較多,每組的記錄數(shù)目少,故各組內(nèi)直接插入較快,后來(lái)增量di逐漸縮小,分組數(shù)逐漸減少,而各組的記錄數(shù)目逐漸增多,但由于已經(jīng)按di-1作為距離排過(guò)序,使文件較接近于有序狀態(tài),所以新的一趟排序過(guò)程也較快。

  因此,希爾排序在效率上較直接插人排序有較大的改進(jìn)。

  希爾排序的平均時(shí)間復(fù)雜度為O(nlogn)。

二、選擇排序

?思想:每趟從待排序的記錄序列中選擇關(guān)鍵字最小的記錄放置到已排序表的最前位置,直到全部排完。

?關(guān)鍵問(wèn)題:在剩余的待排序記錄序列中找到最小關(guān)鍵碼記錄。

?方法:

–直接選擇排序

–堆排序

①簡(jiǎn)單的選擇排序

  1、基本思想:在要排序的一組數(shù)中,選出最小的一個(gè)數(shù)與第一個(gè)位置的數(shù)交換;然后在剩下的數(shù)當(dāng)中再找最小的與第二個(gè)位置的數(shù)交換,如此循環(huán)到倒數(shù)第二個(gè)數(shù)和最后一個(gè)數(shù)比較為止。

 2、實(shí)例

3、java實(shí)現(xiàn)

1 package com.sort;

2

3 //不穩(wěn)定

4 public class 簡(jiǎn)單的選擇排序 {

5

6 public static void main(String[] args) {

7 int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1,8};

8 System.out.println("排序之前:");

9 for (int i = 0; i < a.length; i++) {

10 System.out.print(a[i]+" ");

11 }

12 //簡(jiǎn)單的選擇排序

13 for (int i = 0; i < a.length; i++) {

14 int min = a[i];

15 int n=i; //最小數(shù)的索引

16 for(int j=i+1;j<a.length;j++){

17 if(a[j]<min){ //找出最小的數(shù)

18 min = a[j];

19 n = j;

20 }

21 }

22 a[n] = a[i];

23 a[i] = min;

24

25 }

26 System.out.println();

27 System.out.println("排序之后:");

28 for (int i = 0; i < a.length; i++) {

29 System.out.print(a[i]+" ");

30 }

31 }

32

33 }

4、分析

  簡(jiǎn)單選擇排序是不穩(wěn)定的排序。

  時(shí)間復(fù)雜度:T(n)=O(n2)。

②堆排序

  1、基本思想:

  堆排序是一種樹(shù)形選擇排序,是對(duì)直接選擇排序的有效改進(jìn)。

  堆的定義下:具有n個(gè)元素的序列 (h1,h2,...,hn),當(dāng)且僅當(dāng)滿(mǎn)足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1) (i=1,2,...,n/2)時(shí)稱(chēng)之為堆。在這里只討論滿(mǎn)足前者條件的堆。由堆的定義可以看出,堆頂元素(即第一個(gè)元素)必為最大項(xiàng)(大頂堆)。完全二 叉樹(shù)可以很直觀地表示堆的結(jié)構(gòu)。堆頂為根,其它為左子樹(shù)、右子樹(shù)。

  思想:初始時(shí)把要排序的數(shù)的序列看作是一棵順序存儲(chǔ)的二叉樹(shù),調(diào)整它們的存儲(chǔ)序,使之成為一個(gè) 堆,這時(shí)堆的根節(jié)點(diǎn)的數(shù)最大。然后將根節(jié)點(diǎn)與堆的最后一個(gè)節(jié)點(diǎn)交換。然后對(duì)前面(n-1)個(gè)數(shù)重新調(diào)整使之成為堆。依此類(lèi)推,直到只有兩個(gè)節(jié)點(diǎn)的堆,并對(duì) 它們作交換,最后得到有n個(gè)節(jié)點(diǎn)的有序序列。從算法描述來(lái)看,堆排序需要兩個(gè)過(guò)程,一是建立堆,二是堆頂與堆的最后一個(gè)元素交換位置。所以堆排序有兩個(gè)函數(shù)組成。一是建堆的滲透函數(shù),二是反復(fù)調(diào)用滲透函數(shù)實(shí)現(xiàn)排序的函數(shù)。

  2、實(shí)例

初始序列:46,79,56,38,40,84

  建堆:

 交換,從堆中踢出最大數(shù)

依次類(lèi)推:最后堆中剩余的最后兩個(gè)結(jié)點(diǎn)交換,踢出一個(gè),排序完成。

3、java實(shí)現(xiàn)

1 package com.sort;

2 //不穩(wěn)定

3 import java.util.Arrays;

4

5 public class HeapSort {

6 public static void main(String[] args) {

7 int[] a={49,38,65,97,76,13,27,49,78,34,12,64};

8 int arrayLength=a.length;

9 //循環(huán)建堆

10 for(int i=0;i<arrayLength-1;i++){

11 //建堆

12 buildMaxHeap(a,arrayLength-1-i);

13 //交換堆頂和最后一個(gè)元素

14 swap(a,0,arrayLength-1-i);

15 System.out.println(Arrays.toString(a));

16 }

17 }

18 //對(duì)data數(shù)組從0到lastIndex建大頂堆

19 public static void buildMaxHeap(int[] data, int lastIndex){

20 //從lastIndex處節(jié)點(diǎn)(最后一個(gè)節(jié)點(diǎn))的父節(jié)點(diǎn)開(kāi)始

21 for(int i=(lastIndex-1)/2;i>=0;i--){

22 //k保存正在判斷的節(jié)點(diǎn)

23 int k=i;

24 //如果當(dāng)前k節(jié)點(diǎn)的子節(jié)點(diǎn)存在

25 while(k*2+1<=lastIndex){

26 //k節(jié)點(diǎn)的左子節(jié)點(diǎn)的索引

27 int biggerIndex=2*k+1;

28 //如果biggerIndex小于lastIndex,即biggerIndex+1代表的k節(jié)點(diǎn)的右子節(jié)點(diǎn)存在

29 if(biggerIndex<lastIndex){

30 //若果右子節(jié)點(diǎn)的值較大

31 if(data[biggerIndex]<data[biggerIndex+1]){

32 //biggerIndex總是記錄較大子節(jié)點(diǎn)的索引

33 biggerIndex++;

34 }

35 }

36 //如果k節(jié)點(diǎn)的值小于其較大的子節(jié)點(diǎn)的值

37 if(data[k]<data[biggerIndex]){

38 //交換他們

39 swap(data,k,biggerIndex);

40 //將biggerIndex賦予k,開(kāi)始while循環(huán)的下一次循環(huán),重新保證k節(jié)點(diǎn)的值大于其左右子節(jié)點(diǎn)的值

41 k=biggerIndex;

42 }else{

43 break;

44 }

45 }

46 }

47 }

48 //交換

49 private static void swap(int[] data, int i, int j) {

50 int tmp=data[i];

51 data[i]=data[j];

52 data[j]=tmp;

53 }

54 }

4、分析

  堆排序也是一種不穩(wěn)定的排序算法。

  堆排序優(yōu)于簡(jiǎn)單選擇排序的原因:

  直接選擇排序中,為了從R[1..n]中選出關(guān)鍵字最小的記錄,必須進(jìn)行n-1次比較,然后在R[2..n]中選出關(guān)鍵字最小的記錄,又需要做n-2次比較。事實(shí)上,后面的n-2次比較中,有許多比較可能在前面的n-1次比較中已經(jīng)做過(guò),但由于前一趟排序時(shí)未保留這些比較結(jié)果,所以后一趟排序時(shí)又重復(fù)執(zhí)行了這些比較操作。

  堆排序可通過(guò)樹(shù)形結(jié)構(gòu)保存部分比較結(jié)果,可減少比較次數(shù)。

  堆排序的最壞時(shí)間復(fù)雜度O(nlogn)。堆序的平均性能較接近于最壞性能。由于建初始堆所需的比較次數(shù)較多,所以堆排序不適宜于記錄數(shù)較少的文件。

三、交換排序

①冒泡排序

  1、基本思想:在要排序的一組數(shù)中,對(duì)當(dāng)前還未排好序的范圍內(nèi)的全部數(shù),自上而下對(duì)相鄰的兩個(gè)數(shù)依次進(jìn)行比較和調(diào)整,讓較大的數(shù)往下沉,較小的往上冒。即:每當(dāng)兩相鄰的數(shù)比較后發(fā)現(xiàn)它們的排序與排序要求相反時(shí),就將它們互換。

  2、實(shí)例

3、java實(shí)現(xiàn)

1 package com.sort;

2

3 //穩(wěn)定

4 public class 冒泡排序 {

5 public static void main(String[] args) {

6 int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1,8};

7 System.out.println("排序之前:");

8 for (int i = 0; i < a.length; i++) {

9 System.out.print(a[i]+" ");

10 }

11 //冒泡排序

12 for (int i = 0; i < a.length; i++) {

13 for(int j = 0; j<a.length-i-1; j++){

14 //這里-i主要是每遍歷一次都把最大的i個(gè)數(shù)沉到最底下去了,沒(méi)有必要再替換了

15 if(a[j]>a[j+1]){

16 int temp = a[j];

17 a[j] = a[j+1];

18 a[j+1] = temp;

19 }

20 }

21 }

22 System.out.println();

23 System.out.println("排序之后:");

24 for (int i = 0; i < a.length; i++) {

25 System.out.print(a[i]+" ");

26 }

27 }

28 }

4、分析

  冒泡排序是一種穩(wěn)定的排序方法?!?/p>

?若文件初狀為正序,則一趟起泡就可完成排序,排序碼的比較次數(shù)為n-1,且沒(méi)有記錄移動(dòng),時(shí)間復(fù)雜度是O(n)

?若文件初態(tài)為逆序,則需要n-1趟起泡,每趟進(jìn)行n-i次排序碼的比較,且每次比較都移動(dòng)三次,比較和移動(dòng)次數(shù)均達(dá)到最大值∶O(n2)

?起泡排序平均時(shí)間復(fù)雜度為O(n2)

②快速排序

  1、基本思想:選擇一個(gè)基準(zhǔn)元素,通常選擇第一個(gè)元素或者最后一個(gè)元素,通過(guò)一趟掃描,將待排序列分成兩部分,一部分比基準(zhǔn)元素小,一部分大于等于基準(zhǔn)元素,此時(shí)基準(zhǔn)元素在其排好序后的正確位置,然后再用同樣的方法遞歸地排序劃分的兩部分?!?/p>

  2、實(shí)例

3、java實(shí)現(xiàn)

package com.sort;

//不穩(wěn)定public class 快速排序 {

public static void main(String[] args) {

int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1,8};

System.out.println("排序之前:");

for (int i = 0; i < a.length; i++) {

System.out.print(a[i]+" ");

}

//快速排序 quick(a);

System.out.println();

System.out.println("排序之后:");

for (int i = 0; i < a.length; i++) {

System.out.print(a[i]+" ");

}

}

private static void quick(int[] a) {

if(a.length>0){

quickSort(a,0,a.length-1);

}

}

private static void quickSort(int[] a, int low, int high) {

if(low<high){ //如果不加這個(gè)判斷遞歸會(huì)無(wú)法退出導(dǎo)致堆棧溢出異常

int middle = getMiddle(a,low,high);

quickSort(a, 0, middle-1);

quickSort(a, middle+1, high);

}

}

private static int getMiddle(int[] a, int low, int high) {

int temp = a[low];//基準(zhǔn)元素

while(low<high){

//找到比基準(zhǔn)元素小的元素位置

while(low<high && a[high]>=temp){

high--;

}

a[low] = a[high];

while(low<high && a[low]<=temp){

low++;

}

a[high] = a[low];

}

a[low] = temp;

return low;

}

}

 4、分析

  快速排序是不穩(wěn)定的排序。

  快速排序的時(shí)間復(fù)雜度為O(nlogn)。

  當(dāng)n較大時(shí)使用快排比較好,當(dāng)序列基本有序時(shí)用快排反而不好。

四、歸并排序

  1、基本思想:歸并(Merge)排序法是將兩個(gè)(或兩個(gè)以上)有序表合并成一個(gè)新的有序表,即把待排序序列分為若干個(gè)子序列,每個(gè)子序列是有序的。然后再把有序子序列合并為整體有序序列。

  2、實(shí)例

3、java實(shí)現(xiàn)

1 package com.sort;

2

3 //穩(wěn)定

4 public class 歸并排序 {

5 public static void main(String[] args) {

6 int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1,8};

7 System.out.println("排序之前:");

8 for (int i = 0; i < a.length; i++) {

9 System.out.print(a[i]+" ");

10 }

11 //歸并排序

12 mergeSort(a,0,a.length-1);

13 System.out.println();

14 System.out.println("排序之后:");

15 for (int i = 0; i < a.length; i++) {

16 System.out.print(a[i]+" ");

17 }

18 }

19

20 private static void mergeSort(int[] a, int left, int right) {

21 if(left<right){

22 int middle = (left+right)/2;

23 //對(duì)左邊進(jìn)行遞歸

24 mergeSort(a, left, middle);

25 //對(duì)右邊進(jìn)行遞歸

26 mergeSort(a, middle+1, right);

27 //合并

28 merge(a,left,middle,right);

29 }

30 }

31

32 private static void merge(int[] a, int left, int middle, int right) {

33 int[] tmpArr = new int[a.length];

34 int mid = middle+1; //右邊的起始位置

35 int tmp = left;

36 int third = left;

37 while(left<=middle && mid<=right){

38 //從兩個(gè)數(shù)組中選取較小的數(shù)放入中間數(shù)組

39 if(a[left]<=a[mid]){

40 tmpArr[third++] = a[left++];

41 }else{

42 tmpArr[third++] = a[mid++];

43 }

44 }

45 //將剩余的部分放入中間數(shù)組

46 while(left<=middle){

47 tmpArr[third++] = a[left++];

48 }

49 while(mid<=right){

50 tmpArr[third++] = a[mid++];

51 }

52 //將中間數(shù)組復(fù)制回原數(shù)組

53 while(tmp<=right){

54 a[tmp] = tmpArr[tmp++];

55 }

56 }

57 }

4、分析

  歸并排序是穩(wěn)定的排序方法。

  歸并排序的時(shí)間復(fù)雜度為O(nlogn)。

  速度僅次于快速排序,為穩(wěn)定排序算法,一般用于對(duì)總體無(wú)序,但是各子項(xiàng)相對(duì)有序的數(shù)列。

五、基數(shù)排序

  1、基本思想:將所有待比較數(shù)值(正整數(shù))統(tǒng)一為同樣的數(shù)位長(zhǎng)度,數(shù)位較短的數(shù)前面補(bǔ)零。然后,從最低位開(kāi)始,依次進(jìn)行一次排序。這樣從最低位排序一直到最高位排序完成以后,數(shù)列就變成一個(gè)有序序列。

  2、實(shí)例

3、java實(shí)現(xiàn)

1 package com.sort;

2

3 import java.util.ArrayList;

4 import java.util.List;

5 //穩(wěn)定

6 public class 基數(shù)排序 {

7 public static void main(String[] args) {

8 int[] a={49,38,65,97,176,213,227,49,78,34,12,164,11,18,1};

9 System.out.println("排序之前:");

10 for (int i = 0; i < a.length; i++) {

11 System.out.print(a[i]+" ");

12 }

13 //基數(shù)排序

14 sort(a);

15 System.out.println();

16 System.out.println("排序之后:");

17 for (int i = 0; i < a.length; i++) {

18 System.out.print(a[i]+" ");

19 }

20 }

21

22 private static void sort(int[] array) {

23 //找到最大數(shù),確定要排序幾趟

24 int max = 0;

25 for (int i = 0; i < array.length; i++) {

26 if(max<array[i]){

27 max = array[i];

28 }

29 }

30 //判斷位數(shù)

31 int times = 0;

32 while(max>0){

33 max = max/10;

34 times++;

35 }

36 //建立十個(gè)隊(duì)列

37 List<ArrayList> queue = new ArrayList<ArrayList>();

38 for (int i = 0; i < 10; i++) {

39 ArrayList queue1 = new ArrayList();

40 queue.add(queue1);

41 }

42 //進(jìn)行times次分配和收集

43 for (int i = 0; i < times; i++) {

44 //分配

45 for (int j = 0; j < array.length; j++) {

46 int x = array[j]%(int)Math.pow(10, i+1)/(int)Math.pow(10, i);

47 ArrayList queue2 = queue.get(x);

48 queue2.add(array[j]);

49 queue.set(x,queue2);

50 }

51 //收集

52 int count = 0;

53 for (int j = 0; j < 10; j++) {

54 while(queue.get(j).size()>0){

55 ArrayList<Integer> queue3 = queue.get(j);

56 array[count] = queue3.get(0);

57 queue3.remove(0);

58 count++;

59 }

60 }

61 }

62 }

63 }

4、分析

  基數(shù)排序是穩(wěn)定的排序算法。

  基數(shù)排序的時(shí)間復(fù)雜度為O(d(n+r)),d為位數(shù),r為基數(shù)。

總結(jié):

一、穩(wěn)定性:

  穩(wěn)定:冒泡排序、插入排序、歸并排序和基數(shù)排序

  不穩(wěn)定:選擇排序、快速排序、希爾排序、堆排序

二、平均時(shí)間復(fù)雜度

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

  在數(shù)據(jù)規(guī)模較小時(shí)(9W內(nèi)),直接插入排序,簡(jiǎn)單選擇排序差不多。當(dāng)數(shù)據(jù)較大時(shí),冒泡排序算法的時(shí)間代價(jià)最高。性能為O(n^2)的算法基本上是相鄰元素進(jìn)行比較,基本上都是穩(wěn)定的。

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

  其中,快排是最好的, 其次是歸并和希爾,堆排序在數(shù)據(jù)量很大時(shí)效果明顯。

三、排序算法的選擇

  1.數(shù)據(jù)規(guī)模較小

  (1)待排序列基本序的情況下,可以選擇直接插入排序;

  (2)對(duì)穩(wěn)定性不作要求宜用簡(jiǎn)單選擇排序,對(duì)穩(wěn)定性有要求宜用插入或冒泡

  2.數(shù)據(jù)規(guī)模不是很大

 ?。?)完全可以用內(nèi)存空間,序列雜亂無(wú)序,對(duì)穩(wěn)定性沒(méi)有要求,快速排序,此時(shí)要付出log(N)的額外空間。

 ?。?)序列本身可能有序,對(duì)穩(wěn)定性有要求,空間允許下,宜用歸并排序

  3.數(shù)據(jù)規(guī)模很大

 ?。?)對(duì)穩(wěn)定性有求,則可考慮歸并排序。

 ?。?)對(duì)穩(wěn)定性沒(méi)要求,宜用堆排序

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

二、Java 排序算法:常用排序算法詳解及實(shí)例

1. 引言

排序算法是計(jì)算機(jī)科學(xué)中的經(jīng)典問(wèn)題之一。在Java程序開(kāi)發(fā)中,我們經(jīng)常遇到需要對(duì)數(shù)據(jù)進(jìn)行排序的情況。本文將詳細(xì)介紹Java中常用的排序算法,并提供相應(yīng)的實(shí)例代碼。

2. 冒泡排序

冒泡排序是一種簡(jiǎn)單但效率較低的排序算法。它的基本思想是將待排序的元素逐個(gè)地與相鄰元素進(jìn)行比較和交換,以便將大的元素逐漸"浮"到數(shù)組的右側(cè)。通過(guò)多次遍歷整個(gè)數(shù)組,最終得到有序序列。

3. 插入排序

插入排序是一種簡(jiǎn)單且高效的排序算法。它的基本思想是將待排序的元素逐個(gè)插入已經(jīng)有序的部分,直到全部元素都被插入完畢。插入排序的時(shí)間復(fù)雜度為O(n^2),但在某些特殊情況下可以達(dá)到O(n)。

4. 選擇排序

選擇排序是一種簡(jiǎn)單但較低效的排序算法。它的基本思想是將待排序的元素中的最小值逐個(gè)放到序列的起始位置。通過(guò)多次遍歷整個(gè)數(shù)組,每次都選擇一個(gè)最小值,最終得到有序序列。

5. 快速排序

快速排序是一種高效的排序算法,它的基本思想是通過(guò)一趟排序?qū)⒋庞涗浄指畛瑟?dú)立的兩部分,其中一部分的元素小于另一部分的元素,然后對(duì)這兩部分繼續(xù)進(jìn)行排序,最終得到有序序列。

6. 歸并排序

歸并排序是一種高效的排序算法。它的基本思想是將待排序序列分成若干個(gè)子序列,對(duì)每個(gè)子序列進(jìn)行排序,然后再將排好序的子序列歸并成最終的有序序列。

7. 堆排序

堆排序是一種高效的排序算法。它的基本思想是利用堆這種數(shù)據(jù)結(jié)構(gòu),通過(guò)不斷調(diào)整堆的結(jié)構(gòu)來(lái)實(shí)現(xiàn)排序。堆排序的時(shí)間復(fù)雜度為O(nlogn)。

8. 計(jì)數(shù)排序

計(jì)數(shù)排序是一種高效的線性時(shí)間復(fù)雜度排序算法。它的基本思想是先統(tǒng)計(jì)序列中每個(gè)元素的出現(xiàn)次數(shù),然后根據(jù)次數(shù)重復(fù)輸出元素,從而得到有序序列。

9. 桶排序

桶排序是一種高效的排序算法,它的基本思想是將待排序的元素劃分為若干個(gè)桶,然后對(duì)每個(gè)桶進(jìn)行排序,最后依次將桶中的元素輸出。桶排序適用于待排序元素服從均勻分布的場(chǎng)景。

10. 基數(shù)排序

基數(shù)排序是一種高效的排序算法。它的基本思想是將待排序的元素按照低位到高位的順序依次進(jìn)行排序,最終得到有序序列?;鶖?shù)排序適用于待排序元素的位數(shù)較小的場(chǎng)景。

11. 總結(jié)

本文詳細(xì)介紹了Java中常用的排序算法,并提供了相應(yīng)的實(shí)例代碼。不同的排序算法適用于不同的場(chǎng)景,開(kāi)發(fā)人員可以根據(jù)實(shí)際情況選擇合適的算法。通過(guò)學(xué)習(xí)排序算法,我們可以更好地理解算法的設(shè)計(jì)思想和時(shí)間復(fù)雜度分析方法,提高我們?cè)诰幋a過(guò)程中的思維和技巧。

感謝您的閱讀

感謝您看完本文,希望本文對(duì)您了解Java排序算法有所幫助。如果您有任何問(wèn)題或建議,請(qǐng)隨時(shí)聯(lián)系我們。

三、Java排序算法詳解:常用排序算法及其應(yīng)用

介紹

在計(jì)算機(jī)編程領(lǐng)域中,排序算法是一種常見(jiàn)的基礎(chǔ)性算法,它能夠幫助程序員對(duì)一組數(shù)據(jù)按照一定規(guī)則進(jìn)行有序排列。Java作為一種流行的編程語(yǔ)言,提供了豐富的排序算法實(shí)現(xiàn),本文將詳細(xì)介紹常用的排序算法及其應(yīng)用。

常用排序算法

排序算法根據(jù)實(shí)現(xiàn)原理和時(shí)間復(fù)雜度的不同,可以分為多種類(lèi)型,其中常用的排序算法包括:冒泡排序、選擇排序、插入排序、快速排序、歸并排序等。

冒泡排序是一種簡(jiǎn)單直觀的排序算法,重復(fù)地走訪過(guò)要排序的數(shù)列,一次比較兩個(gè)元素,如果它們的順序錯(cuò)誤就把它們交換過(guò)來(lái)。

選擇排序是一種簡(jiǎn)單直觀的排序算法,每次從待排序的數(shù)據(jù)元素中選出最小(或最大)的一個(gè)元素,存放在序列的起始位置。

插入排序是一種簡(jiǎn)單且高效的排序算法,類(lèi)似于整理?yè)淇伺茣r(shí)的方法,將未排序的元素插入到已排序序列的合適位置。

快速排序是一種高效的排序算法,通過(guò)選定一個(gè)基準(zhǔn)值,將小于基準(zhǔn)值的放在左邊,大于基準(zhǔn)值的放在右邊,然后對(duì)左右兩側(cè)分別遞歸進(jìn)行排序。

歸并排序是一種分治算法,將原始序列分成若干子序列,分別進(jìn)行排序后再合并。

排序算法應(yīng)用

在實(shí)際開(kāi)發(fā)過(guò)程中,對(duì)數(shù)據(jù)進(jìn)行排序是非常常見(jiàn)的需求。排序算法廣泛應(yīng)用于各種領(lǐng)域,包括數(shù)據(jù)庫(kù)查詢(xún)優(yōu)化、算法競(jìng)賽、數(shù)據(jù)分析、日程安排等,通過(guò)合適選擇和應(yīng)用排序算法,可以提高程序的效率。

總結(jié)

排序算法作為計(jì)算機(jī)程序設(shè)計(jì)中的重要基礎(chǔ)知識(shí),掌握不同類(lèi)型的排序算法及其應(yīng)用場(chǎng)景對(duì)于提高編程水平至關(guān)重要。通過(guò)本文的介紹,相信讀者對(duì)Java中常用的排序算法有了更深入的了解,希望能夠在實(shí)際項(xiàng)目中靈活應(yīng)用,提升自己的編程能力。

感謝您看完這篇文章,希望通過(guò)本文能夠幫助您更好地理解Java排序算法,為您的編程實(shí)踐帶來(lái)指導(dǎo)和啟迪。

四、python 排序算法?

1、冒泡排序

它反復(fù)訪問(wèn)要排序的元素列,并依次比較兩個(gè)相鄰的元素。

2、選擇排序

首次從待排序的數(shù)據(jù)元素中選擇最小(或最大)的元素,存儲(chǔ)在序列的開(kāi)始位置。

3、插入排序

對(duì)于未排序的數(shù)據(jù),通過(guò)構(gòu)建有序的序列,在已排序的序列中從后向前掃描,找到相應(yīng)的位置并插入。插入式排序在實(shí)現(xiàn)上。

4、快速排序

將要排序的數(shù)據(jù)通過(guò)一次排序分成兩個(gè)獨(dú)立的部分。

5、希爾排序(插入排序改進(jìn)版)

將要排序的一組數(shù)量按某個(gè)增量d分為幾個(gè)組,

6、歸并排序,首先遞歸分解組,然后合并組。

基本思路是比較兩個(gè)數(shù)組的面的數(shù)字,誰(shuí)小就先取誰(shuí),取后相應(yīng)的指針向后移動(dòng)一個(gè)。然后再比較,直到一個(gè)數(shù)組是空的,最后復(fù)制另一個(gè)數(shù)組的剩余部分。

五、猴子排序算法?

猴子排序是一種什么樣子的排序呢?

猴子代表亂的意思,猴子排序的意思就是亂排序,直到有序?yàn)橹埂?/p>

這個(gè)真實(shí)的含義就是把一個(gè)無(wú)序的數(shù)組進(jìn)行亂排序,然后看其是否會(huì)有序,這是個(gè)概率性事件,有可能一次之后就有序了,也有可能很多次后依然無(wú)序。

實(shí)現(xiàn)方法如下:

1,定義數(shù)組

2,數(shù)組隨機(jī)

3,檢驗(yàn)數(shù)組是否有序,無(wú)序繼續(xù),有序了就停止

就是如此簡(jiǎn)單的實(shí)現(xiàn)思路,但是卻要用到隨機(jī)化的知識(shí)和標(biāo)志變量的實(shí)現(xiàn)技巧

代碼如下: //得到的數(shù)據(jù)是說(shuō)明了排序多少次之后才有序

#include <iostream>

using namespace std;

int source[10],flag[10],res[10];

int sort(){

memset(flag,1,sizeof(flag));

int num = 10,count=0;

while(num){

int t =rand()%10; //生成0-9之間的數(shù)

if(flag[t]){

res[count++] = source[t];

num--;

}

}

for(int i=0;i<9;i++){

if(res[i]>res[i+1]){ //只有是從小到大的排列才行

return 0;

}

}

return 1;

}

int main(){

int count = 0;

for(int i=0;i<10;i++){

cin>>source[i];

}

while(sort()!=1){

count++;

}

cout<<"共運(yùn)行了"<<count<<"次"<<endl;

return 0;

}

六、路徑排序算法?

1 public class SelectSort {

2 public static int[] selectSort(int[] a) {

3 int n = a.length;

4 for (int i = 0; i < n - 1; i++) {

5 int min = i;

6 for (int j = i + 1; j < n; j++) {

7 if(a[min] > a[j]) min = j;

8 }

9 //交換

10 int temp = a[i];

11 a[i] = a[min];

12 a[min] = temp;

13 }

14 return a;

15 }

16 }

性質(zhì):1、時(shí)間復(fù)雜度:O(n2) 2、空間復(fù)雜度:O(1) 3、非穩(wěn)定排序 4、原地排序

七、快遞排序算法?

算法原理:類(lèi)似于歸并排序,快速排序是基于分治模式。具體有以下三個(gè)步驟:

1分解:數(shù)組A[left..right]被劃分為兩個(gè)(可能為空)子數(shù)組A[left..q-1]和A[q+1..right],使得A[left..q-1]中的每一個(gè)元素都小于等于A[q],而且小于等于A[q+1..right]中的每一個(gè)元素。下標(biāo)q也在這個(gè)劃分過(guò)程中進(jìn)行計(jì)算。

2解決:通過(guò)遞歸調(diào)用快速排序,對(duì)子數(shù)組A[left..q-1]和A[q+1..right]排序。

3合并:因?yàn)閮蓚€(gè)子數(shù)組是就地排序的,將它們的合并不需要操作:整個(gè)數(shù)組A[left..right]已排序。

八、希爾排序算法?

希爾排序(Shell's Sort)算法是插入排序的一種又稱(chēng)“縮小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一種更高效的改進(jìn)版本。希爾排序是非穩(wěn)定排序算法。該方法因 D.L.Shell 于 1959 年提出而得名。

希爾排序是把記錄按下標(biāo)的一定增量分組,對(duì)每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關(guān)鍵詞越來(lái)越多,當(dāng)增量減至 1 時(shí),整個(gè)文件恰被分成一組,算法便終止。

九、msd排序算法?

MSD的算法思路如下:

1、MSD的方式與LSD相反,是由高位數(shù)為基底開(kāi)始進(jìn)行分配,但在分配之后并不馬上合并回一個(gè)數(shù)組中,而是在每個(gè)組中建立“子組”。

2、將每個(gè)桶子中的數(shù)值按照下一數(shù)位的值分配到“子組”中。在進(jìn)行完最低位數(shù)的分配后再合并回單一的數(shù)組中。即先按k1排序分組,同一組中記錄,關(guān)鍵碼k1相等,再對(duì)各組按k2排序分成子組,之后,對(duì)后面的關(guān)鍵碼繼續(xù)這樣的排序分組,直到按最次位關(guān)鍵碼kd對(duì)各子組排序后。再將各組連接起來(lái),便得到一個(gè)有序序列。所以,MSD方法用遞歸的思想實(shí)現(xiàn)最為直接。

十、Java排序算法大全:常見(jiàn)排序算法總結(jié)與實(shí)現(xiàn)

Java排序算法大全

排序在計(jì)算機(jī)科學(xué)中是一個(gè)基本且重要的問(wèn)題,對(duì)于Java開(kāi)發(fā)者來(lái)說(shuō),了解排序算法不僅可以提高代碼效率,還可以加深對(duì)數(shù)據(jù)結(jié)構(gòu)和算法的理解。本文將為您介紹常見(jiàn)的排序算法,并給出Java語(yǔ)言實(shí)現(xiàn)的示例代碼。

冒泡排序(Bubble Sort)

冒泡排序是一種簡(jiǎn)單直觀的排序算法。它會(huì)重復(fù)遍歷要排序的數(shù)列,一次比較兩個(gè)元素,如果它們的順序錯(cuò)誤就把它們交換過(guò)來(lái)。點(diǎn)擊查看Java冒泡排序示例代碼。

選擇排序(Selection Sort)

選擇排序是一種簡(jiǎn)單直觀的排序算法。它的工作原理是每一次從待排序的數(shù)據(jù)元素中選出最?。ɑ蜃畲螅┑囊粋€(gè)元素。點(diǎn)擊查看Java選擇排序示例代碼。

插入排序(Insertion Sort)

插入排序是一種簡(jiǎn)單直觀的排序算法。它的工作原理是通過(guò)構(gòu)建有序序列,對(duì)未排序數(shù)據(jù),在已排序序列中從后向前掃描,找到相應(yīng)位置并插入。點(diǎn)擊查看Java插入排序示例代碼

快速排序(Quick Sort)

快速排序是面試中經(jīng)常被問(wèn)及的高級(jí)排序算法。它通過(guò)一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨(dú)立的兩部分,其中一部分的所有數(shù)據(jù)都要比另外一部分的所有數(shù)據(jù)都要小,然后再按此方法對(duì)這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序。點(diǎn)擊查看Java快速排序示例代碼。

歸并排序(Merge Sort)

歸并排序是一種穩(wěn)定且高效的排序算法。它采用分治策略,將已有序的子序列合并,得到完全有序的序列。點(diǎn)擊查看Java歸并排序示例代碼。

堆排序(Heap Sort)

堆排序是一種選擇排序,它利用了堆這種數(shù)據(jù)結(jié)構(gòu)。運(yùn)用最大堆和最小堆,可以按照升序或降序的要求對(duì)記錄進(jìn)行調(diào)整。點(diǎn)擊查看Java堆排序示例代碼。

通過(guò)學(xué)習(xí)以上排序算法的實(shí)現(xiàn),相信您對(duì)Java中的排序算法有了更深入的理解,也能更加靈活地應(yīng)用到實(shí)際項(xiàng)目中。感謝您閱讀本文!

相關(guān)資訊
熱門(mén)頻道

Copyright © 2024 招聘街 滇ICP備2024020316號(hào)-38