歸併排序(mergesort)是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(divide and conquer)的乙個非常典型的應用。簡單來說歸併排序類似於對兩個有序序列的合併。
也就是說,將待排序的序列分成 n 組,然後對這 n 個組兩兩合併成乙個新的有序序列,接著繼續兩兩合併,直至最終只有乙個有序序列結束。這個過程就是先將待排序序列分組,直至每個組內只有乙個元素,這個 時候任意乙個組都是有序的,接著將這些兩兩合併,最後得到乙個有序序列。
在這樣分組完畢之後,每個組內元素都只剩乙個,那麼乙個元素一定是有序的。這時候對相鄰的兩個元素進行歸併排序。兩兩排序完畢後再與其相鄰組繼續歸併,直至結束。
遞迴版本
void mergearray(int
array, int beg, int mid, int end, int* tmp)
else
} while (cur1 < mid)
while (cur2 < end)
memcpy(array + beg, tmp + beg, (end - beg)*sizeof(int)); // 將臨時區域內有序資料拷貝至原陣列
return;
}void _mergesort(int
array, int beg, int end, int* tmp) // 分組
int mid = beg + (end - beg) / 2;
_mergesort(array, beg, mid, tmp);
_mergesort(array, mid , end, tmp);
mergearray(array, beg, mid, end, tmp); // 歸併函式
}void mergesort(int
array, int size)
int* tmp = (int*)malloc(sizeof(int) * size); // 建立臨時區域存放歸併後的陣列
_mergesort(array, 0, size, tmp);
free(tmp);
tmp = null;
}
非遞迴版本void mergesortbyloop(int array, int
size)
int size_bound = 1;
int* tmp = (int
*)malloc(sizeof(int) * size);
for (; size_bound < size; size_bound *=
2) // 這裡同理,如果 end 超過了 size
// 那麼就是第二段的區域的元素個數低於第一段
// 也需要將 end 置為 size
if (end >= size)
mergearray(array, beg, mid, end, tmp);
} // end for (; i < size; i += 2 * size_bound)
} return;
}
歸併排序的速度是非常快的,它的速度僅僅次於快速排序。是乙個穩定的排序演算法,時間複雜度為 o (n * log n)。在用於排序乙個整體無序但各個元素之間相對有序的序列時效率很高。 排序演算法 歸併排序
歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第乙個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再進行比較,如果有數列為空,那直接將另...
排序演算法 歸併排序
include include define status int define max 20 typedef struct elemtype typedef struct sqlist void inital sqlist l 初始化 bool lt int i,int j void merge ...
排序演算法 歸併排序
歸併排序的思想其實完全是分治法的思想的體現,它完全遵循分治法的模式。這裡有必要再重提下分治法的思想 將原有的問題分解為幾個規模較小的但類似於原問題的子問題,遞迴的求解這些子問題,然後再合併這些子問題的解來求得原問題的解。現在來看看歸併排序的操作 1 將等待排序的含有 n 個元素的序列分解成各具有 n...