自然合併排序

2021-10-09 23:01:33 字數 1901 閱讀 4801

我們知道歸併排序是將乙個無序的陣列兩兩劃分,最終劃分成每個組內有序的子元素,組後再將若干個組內有序的元素合併成乙個完整有序的陣列。這個思路可以使用遞迴和非遞迴演算法來實現,我在此主要講自然合併排序

自然合併排序當然也是合併排序,所謂的自然只不過就是指:所劃分的子陣列不在是兩兩劃分,而是每乙個子陣列都是已經有序的,且每個子陣列的長度不在確定。這就是自然合併排序與合併排序的區別。

如陣列

將此陣列可以自然劃分為三個有序的子陣列

由於自然劃分的不確定性,所以此演算法無法由遞迴實現,具體**如下:

#include

// 記錄初始自然排好序的子陣列段的起始下標及個數

intgetindex

(int

*list,

int*index,

int n)

}return count;

}//將乙個陣列內的兩個子陣列合併

// left是第乙個有序子陣列段的起始下標

// middle是第乙個有序子陣列段的末尾下標

// right是第二個有序子陣列段的末尾下標

void

mergesublist

(int

*list_1,

int*list_2,

int left,

int middle,

int right)

else

}// 合併兩段中的剩餘部分

while

(i <= middle)

while

(j <= right)

}//合併過程函式

//將組內有序的陣列合併,具體合併由merge()實現

/* 每合次s增加,就合併一段子陣列

每個子陣列的起始位置記錄在t陣列中

index[i] 表示要合併第乙個子陣列的起始元素在原陣列的下標 即每次合併的left

index[i+s]-1 表示要合併的第乙個子陣列的最後乙個元素在原陣列的下標 即每次合併的middle

index[i+2*s]-1 表示每次要合併的第二個子陣列的最後乙個元素 即每次合併的right

*/void

mergepass

(int

*list_1,

int*list_2,

int*index,

int s,

int count,

int n)

//當前陣列內含有兩個子陣列段

if(i + s < count)

//當前陣列內只有乙個子陣列段

else

if(i < count)}}

void

mergesort

(int

*list_1,

int*index,

int count,

int n)

}int

main

(void

)int count =

getindex

(list, index, n)

;/*//輸出標記陣列

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

printf("\n");

*/mergesort

(list, index, count, n)

;for

(int i =

0; i < n; i++

)return0;

}

測試結果

輸入:

7

1 5 3 6 7 2 4

輸出:

1 2 3 4 5 6 7

自然合併排序

自然合併排序演算法是對合併排序演算法的一種改進。設 a 0 n 1 是無序陣列,用一次對陣列a的掃瞄可以找出其中 自然排好序的子陣列,然後將相鄰的排好序的子陣列段兩 兩合併,繼續合併相鄰排好序的子陣列段,直至將整個數 組排好序。code include include using namespace...

分治 合併排序 自然合併排序(C )

演算法步驟 引用自 菜鳥教程 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列 設定兩個指標,最初位置分別為兩個已經排序序列的起始位置 比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置 重複步驟 3 直到某一指標達到序列尾 將另一串行剩下的所有元素直...

自然合併排序演算法

合併排序基本思想 將待排序元素分成大小大致相同 可以不等長 的兩個子集和,分別對兩個子集合進行排序,最終將排好序的子集合合併成所要求的排好序的集合。遞迴版 void mergesort int a,int left,int right void mergepass int x,int y,int s...