當前位置:成語大全網 - 書法字典 - 數據結構java開發中常用的排序算法有哪些?

數據結構java開發中常用的排序算法有哪些?

排序算法有很多種,因此在特定情況下使用哪種算法很重要。為了選擇合適的算法,可以按照建議的順序考慮以下標準:

(1)執行時間

②存儲空間

⑶編程工作

對於少量數據,(1)(2)差別不大,主要考慮(3);對於大數據量,(1)是第壹個。

主要的排序方法有:

第壹,冒泡排序-相鄰交換

第二,選擇排序-最小/最大的行每次都在相應的位置。

第三,插入排序——將下壹個插入到排列好的序列中。

第四,外殼分類-減少增量

動詞 (verb的縮寫)合並和排序

第六,快速分類

七、堆排序

八、拓撲排序

首先,冒泡排序

-

void BubbleSortArray()

{

for(int I = 1;我& ltn;i++)

{

for(int j = 0;我& ltn-I;j++)

{

if(a【j】》;a【j+1】)//比較並交換相鄰元素。

{

int temp

temp = a【j】;a【j】= a【j+1】;a【j+1】= temp;

}

}

}

}

-代碼-

效率O(n?),適合整理小列表。

第二,選擇排序

-

void SelectSortArray()

{

int min _ index

for(int I = 0;我& ltn-1;i++)

{

min _ index = I;

for(int j = I+1;j & ltn;j++)//為每次掃描選擇最小的項目。

if(arr【j】& lt;arr【min _ index】)min _ index = j;

if(min _ index!= I)//找到最小的項目交換,即把這個項目移動到列表中的正確位置。

{

int temp

temp = arr【I】;arr【I】= arr【min _ index】;arr【min _ index】= temp;

}

}

}

-代碼-

效率O(n?),適用於小排序的列表。

第三,插入排序

-

void InsertSortArray()

{

for(int I = 1;我& ltn;i++)//循環從第二個數組元素開始,因為arr【0】是原始排序部分。

{

int temp = arr【I】;//temp將第壹個元素標記為無序。

int j = I-1;

while(j & gt;= 0 & amp& amparr【j】》;Temp)/*將temp與從小到大排序的元素進行比較,並找出應該在何處插入temp */

{

arr【j+1】= arr【j】;

j-;

}

arr【j+1】= temp;

}

}

-代碼-

最優效率o(n);最差效率O(n?)與冒泡和選擇相同,適用於對小列表進行排序。

如果列表基本有序,插入排序比冒泡和選擇更高效。

第四,外殼排序-減少增量排序

-

void ShellSortArray()

{

for(int incr = 3;incr<0;incr-)///增量減少,以增量3,2,1為例。

{

for(int L = 0;L & lt(n-1)/incr;l++)//重復每個子列表。

{

for(int I = L+incr;我& ltn;I+= incr)//對每個子列表應用插入排序。

{

int temp = arr【I】;

int j = I-incr;

while(j & gt;= 0 & amp& amparr【j】》;溫度)

{

arr【j+incr】= arr【j】;

j-= incr;

}

arr【j+incr】= temp;

}

}

}

}

-代碼-

適合對小列表進行排序。

效率估計值o(nlog 2n)~ o(n 1.5)取決於增量值的初始大小。建議使用質數作為增量值,因為如果增量值是2的冪,則相同的元素將在下壹個通道中再次進行比較。

外殼排序改進了插入排序並減少了比較次數。是壹種不穩定的排序,因為元素可能會在排序過程中來回跳轉。

動詞 (verb的縮寫)合並和排序

-

void合並排序(int low,int high)

{

if(low & gt;=高)返回;//當每個子列表中還剩壹個元素時停止。

else int mid=(低+高)/2;/*將列表分成兩個相等的子列表。如果有奇數個元素,左邊的子列表比右邊的子列表大*/

MergeSort(低、中);//子列表被進壹步劃分。

merge sort(mid+1,high);

int【】B = new int【高-低+1】;//創建壹個新數組來存儲合並的元素。

for(int I =低,j=mid+1,k =低;我& lt=中期和中期。& ampj & lt=高;k++)/*對兩個子列表進行排序和合並,直到其中壹個子列表結束為止*/

{

if(arr【I】& lt;= arr【j】;)

{

b【k】= arr【I】;

i++;

}

其他

{ B【k】= arr【j】;j++;}

}

for(;j & lt=高;J++,k++)//如果第二個子列表中仍有元素,則追加到新列表中。

b【k】= arr【j】;

for(;我& lt= midI++,k++)//如果第壹個子列表中仍有元素,則將它們追加到新列表中。

b【k】= arr【I】;

for(int z = 0;z & lt高低位+1;z++)//將排序後的數組B的所有元素復制到原始數組arr中。

arr【z】= B【z】;

}

-代碼-

效率O(nlogn),合並的最佳、平均和最差用例效率之間沒有區別。

適合對大型列表進行排序,基於分治法。

第六,快速分類

-代碼-

/*快速排序的算法思想:選擇壹個hub元素,將待排序的序列進行分割,分割後的序列壹部分小於hub元素,另壹部分大於hub元素,然後對分割後的兩個子序列進行上述過程。*/void swap(int a,int b){ int t;t = a;a = b;b = t;}

int分區(int【】arr,int low,int high)

{

int pivot = arr【low】;//使用子序列的第壹個元素作為透視元素。

while(low & lt;高)

{

//從後半部分和前半部分中查找第壹個小於pivot元素的元素。

while(low & lt;高& amp& amparr【high】》;=樞軸)

{

-高;

}

//將小於pivot元素的此元素交換到前半部分。

swap(arr【低】,arr【高】);

//在轉到後,在前半部分中查找第壹個大於pivot元素的元素。

while(low & lt;高& amp& amparr【low】& lt;=樞軸)

{

++低電平;

}

swap(arr【低】,arr【高】);//將此pivot元素的大元素切換到後半部分。

}

返回低位;//返回透視元素的位置。

}

void快速排序(int【】a,int low,int high)

{

if(low & lt;高)

{

int n = Partition(a,低,高);

quick sort(a,low,n);

快速排序(a,n +1,高);

}

}

-代碼-

平均效率O(nlogn),適合對大型列表進行排序。

該算法的總時間取決於主元值的位置;選擇第壹個元素作為軸心可能會導致O(n?)最差情況效率。如果人數基本有序,效率最差。以期權的中間值作為中樞,效率為O(nlogn)。

基於各個擊破。

七、堆排序

最大堆:後者任意非終結節點的關鍵字大於或等於其左右子節點的關鍵字,堆頂部節點的關鍵字在整個序列中最大。

心想:

(1)設i=l,temp = kl

(2)計算I j=2i+1的左子;

如果J

(4)比較kj和kj+1,如果kj+1》Kj,則設j = j+1,否則j保持不變;

(5)如果kj》則比較temp和kj;Temp,然後使ki等於kj,並且i=j,j=2i+1,並轉到(3),否則轉到(6)。

(6)使ki等於temp並結束。

-代碼-

void堆排序

{//用於R【1的堆排序...n】,我們不妨用R【0】作為臨時存儲單元int I;build heap(R)//將R【1-n】構建到for(I = n;我& gt1;I-)//堆排序當前無序區域R【1..I】,* * *做n-1次。{ R【0】= R【1】;R【1】= R【I】;R【I】= R【0】;//在堆的頂部和堆中的最後壹條記錄之間交換heap ify(R,1,I-1);//重新調整R【1...I-1】作為堆,只有R【1】可能違反堆的性質}} -。

堆排序的時間主要由建立初始堆和重復重建堆的時間開銷組成,這兩者都是通過調用Heapify來實現的。

堆排序的最壞時間復雜度為O(nlgn)。堆排序的平均性能接近最差性能。因為初始堆需要更多的比較,所以堆排序不適合記錄較少的文件。堆排序是局部排序,輔助空間為O(1),這是壹種不穩定的排序方法。

堆排序和直接插入排序的區別;

在直接選擇排序中,為了從R【1】中選擇關鍵字最小的記錄...n】,需要進行n-1次比較,然後從R【2】中選擇關鍵字最小的記錄...n】,並且有必要進行n-2次比較。事實上,在接下來的n-2次比較中,許多比較可能是在之前的n-1次比較中進行的,但由於這些比較結果在之前的排序中沒有保留,因此在下壹次排序中重復了這些比較操作。

堆排序可以通過樹結構保存壹些比較結果,這樣可以減少比較的次數。

八、拓撲排序

示例:學生選修課的安排順序

拓撲排序:根據優先級關系將有向圖中的頂點排列成線性序列的過程。

方法:

在有向圖中選擇壹個沒有前身的頂點並輸出。

從圖中刪除頂點和所有以該頂點結束的弧。

重復上述兩個步驟,直到所有頂點都已輸出(拓撲排序成功),或者當圖中沒有沒有前輩的頂點時(圖中存在循環)。

-代碼-

void topological sort()/*輸出拓撲排序函數。如果G沒有回路,則輸出G的頂點拓撲序列並返回OK,否則返回ERROR*/

{

int in degree【M】;

int i,k,j;

char n;

int count = 0;

堆疊堆棧;

FindInDegree(G,in degree);//查找每個頂點的度數【0...num】

init stack(the stack);//初始化堆棧

for(I = 0;我& ltG.numi++)

控制臺。WriteLine(“node“+g . vertices【I】。data+”有“+degree【I】”的程度);

for(I = 0;我& ltG.numi++)

{

if(in degree【I】= = 0)

push(the stack . vertices【I】);

}

控制臺。Write(“拓撲排序輸出順序為:“);

while(the stack。Peek()!=null)

{

彈出(堆棧。peek());

j = locate vex(G,n);

如果(j==-2)

{

控制臺。WriteLine(“出現錯誤,程序結束。”);

exit();

}

控制臺。寫(g . vertices【j】。數據);

count++;

for(p = g . vertices【j】。firstarcp!= NULLp=p.nextarc)

{

k = p . adj vex;

如果(!(-in degree【k】))

push(g . vertices【k】);

}

}

if(count & lt;數字)

科索爾。WriteLine(“該圖形有壹個環,並且存在錯誤,因此無法對其進行排序。”);

其他

控制臺。WriteLine(“排序成功。);

}

-代碼-

算法的時間復雜度O(n+e)。