我們知道歸併排序是將乙個無序的陣列兩兩劃分,最終劃分成每個組內有序的子元素,組後再將若干個組內有序的元素合併成乙個完整有序的陣列。這個思路可以使用遞迴和非遞迴演算法來實現,我在此主要講自然合併排序
自然合併排序當然也是合併排序,所謂的自然只不過就是指:所劃分的子陣列不在是兩兩劃分,而是每乙個子陣列都是已經有序的,且每個子陣列的長度不在確定。這就是自然合併排序與合併排序的區別。
如陣列
將此陣列可以自然劃分為三個有序的子陣列
由於自然劃分的不確定性,所以此演算法無法由遞迴實現,具體**如下:
#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...