目录
连续结构的归并排序:
递归版:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
using namespace std;
template <typename T>
void merge(T *a , int first, int mid, int last)
{
T* temp = new T[last - first + 1];
int first1 = first, last1 = mid;
int first2 = mid + 1, last2 = last;
int index = 0;
while(first1 <= last1 && first2 <= last2){
if(a[first1 ] <= a[first2])
temp[index++] = a[first1++];
else
temp[index++] = a[first2++];
}
while(first1 <= last1){
temp[index++] = a[first1++];
}
while(first2 <= last2){
temp[index++] = a[first2++];
}
for(int i = first; i <= last; i++){
a[i] = temp[i - first];
}
delete [] temp;
return;
}
template<typename T>
void MergeSort(T *a, int first, int last){
if(last - first > 0){ //at least two element
int mid = (last + first) / 2;
MergeSort(a, first, mid);
MergeSort(a, mid + 1, last);
merge(a, first, mid, last);
}
return;
}
#define MAXN 100
int a[MAXN];
int main()
{
for(int i = 0; i < MAXN; i++){
a[i] = MAXN-i;
}
MergeSort(a, 0, MAXN-1);
for(int i = 0; i < MAXN; i++){
cout << a[i] << endl;
}
return 0;
}
迭代版本归并排序
#include <iostream>
#include <vector>
using namespace std;
// ref1: https://blog.csdn.net/chencangui/article/details/44680113/
// ref2: https://blog.csdn.net/Jacketinsysu/article/details/52472364
void merge_sort(vector<int>& arr){
int n = arr.size();
if(n <= 1) return;
vector<int> tmp(n);
int ls, le, rs, re, id;
for(int i = 1; i < n; i <<= 1){ // 归并排序的left与right的区间长度
for(int index = 0; index+i<n; index += (i<<1)){ // 根据 for(0, n, i) 来排序每个区间
id = 0, ls = index, le = index+i-1, rs = le+1, re = min(le+i, n-1);
while(ls <= le && rs <= re){
if(arr[ls] <= arr[rs]) tmp[id++] = arr[ls++];
else tmp[id++] = arr[rs++];
} while(ls <= le){ // enter this loop when rs = re+1
arr[--rs] = arr[le--];
} while(id > 0){ // end this loop when id == 0
arr[--rs] = tmp[--id];
}
}
}
}
void print(vector<int> v){
for(int i = 0; i < v.size(); ++i){
cout << v[i] << ' ';
} cout << endl;
}
void check(vector<int> v){
for(int i = 1; i < v.size(); ++i){
if(v[i-1] > v[i]){
cout << "sort failed" << endl;
return;
}
} cout << "sort succeed" << endl;
}
int main(){
int n = 100, a[] = {364,637,341,406,747,995,234,971,571,219,993,407,416,366,315,301,601,650,418,355,460,505,360,965,516,648,727,667,465,849,455,181,486,149,588,233,144,174,557,67,746,550,474,162,268,142,463,221,882,576,604,739,288,569,256,936,275,401,497,82,935,983,583,523,697,478,147,795,380,973,958,115,773,870,259,655,446,863,735,784,3,671,433,630,425,930,64,266,235,187,284,665,874,80,45,848,38,811,267,575};
vector<int> v(a, a+n);
merge_sort(v);
print(v);
check(v);
return 0;
}
迭代版归并排序, 短码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// ref1: https://blog.csdn.net/chencangui/article/details/44680113/
// ref2: https://blog.csdn.net/Jacketinsysu/article/details/52472364
void merge_sort(vector<int>& arr){
int n = arr.size();
if(n <= 1) return;
vector<int> tmp(n);
int ls, le, rs, re, id;
for(int i = 1; i < n; i <<= 1){ // 归并排序的left与right的区间长度
for(int index = 0; index+i<n; index += (i<<1)){ // 根据 for(0, n, i) 来排序每个区间
ls = index, rs = index+i, le = rs-1, re = min(rs+i-1, n-1);
id = ls;
while(ls <= le || rs <= re){
if(ls <= le && (rs > re || arr[ls] < arr[rs]) ){
tmp[id++] = arr[ls++];
} else tmp[id++] = arr[rs++];
}
for(int j = index; j < id; ++j){
arr[j] = tmp[j];
}
}
}
}
void print(vector<int> v){
for(int i = 0; i < v.size(); ++i){
cout << v[i] << ' ';
} cout << endl;
}
void check(vector<int> arr, void (*f)(vector<int>&) ){
vector<int> sorted_arr(arr.begin(), arr.end());
sort(sorted_arr.begin(), sorted_arr.end());
vector<int> v(arr.begin(), arr.end());
f(v);
if(sorted_arr.size() != v.size()){
cout << "sort failed: the element number is changed." << endl;
return;
}
for(int i = 1; i < v.size(); ++i){
if(v[i-1] > v[i]){
cout << "sort failed: not ordered." << endl;
return;
}
}
for(int i = 0; i < v.size(); ++i){
if(sorted_arr[i] != v[i]){
cout << "sort failed: element is change." << endl;
return;
}
}
cout << "sort succeed" << endl;
}
void test(){
int T = 100;
while(T--){
int n = 100, a[100];
for(int i = 0; i < n; ++i) a[i] = rand();
vector<int> v(a, a+n);
check(v, merge_sort);
}
return;
}
int main(){
//int n = 100, a[] = {364,637,341,406,747,995,234,971,571,219,993,407,416,366,315,301,601,650,418,355,460,505,360,965,516,648,727,667,465,849,455,181,486,149,588,233,144,174,557,67,746,550,474,162,268,142,463,221,882,576,604,739,288,569,256,936,275,401,497,82,935,983,583,523,697,478,147,795,380,973,958,115,773,870,259,655,446,863,735,784,3,671,433,630,425,930,64,266,235,187,284,665,874,80,45,848,38,811,267,575};
//vector<int> v(a, a+n);
test();
return 0;
}
链式结构的归并排序:
单链表版本
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
template <typename Node_entry>
struct Node{
Node_entry entry;
Node* next;
Node(){
next = NULL;
}
Node(const Node_entry& newEntry, Node* add_on = NULL){
entry = newEntry;
next = add_on;
}
};
template<typename T>
void PrintList(Node<T>* l){
if(l != NULL) cout << l->entry;
l = l->next;
while(l != NULL){
cout << "->" << l->entry;
l = l->next;
}
cout << "->NULL\n";
return;
}
template <typename T>
Node<T>* divide(Node<T>* list){
Node<T> *position = list->next,// traversed the entire list
*second, *end_of_first = list;
while(position != NULL){
position = position->next;
if(position != NULL){
position = position->next;
end_of_first = end_of_first->next;
}
}
second = end_of_first->next;
end_of_first->next = NULL; // add a NULL at the end of the first
/*
cout << "check divide\n";
cout << "first:\n"; PrintList(list);
cout << "second:\n"; PrintList(second);
*/
return second;
}
template <typename T>
Node<T>* merge(Node<T>* first, Node<T>* second){
Node<T> combined, *last_sorted = &combined;
while(first != NULL && second != NULL){
if(first->entry <= second->entry){
last_sorted->next = first;
last_sorted = first;
first = first->next;
}
else{
last_sorted->next = second;
last_sorted = second;
second = second->next;
}
}
if(first != NULL){
last_sorted->next = first; // there is a NULL at the end of the first, no need to add
}
else{ // second != NULL
last_sorted->next = second;// there is a NULL at the end of the second, no need to add
}
/*
cout << "check merge\n";
PrintList(combined.next);
*/
return combined.next;
}
template<typename T>
void MergeSort(Node<T>*& list){
if(list != NULL && list->next != NULL){ // at least two element
Node<T>* second_part = divide(list);// divide list into two parts
MergeSort(list);
MergeSort(second_part);
list = merge(list, second_part); // that why use parameter [Node<T>*& list]
}
return;
}
template <typename T>
void MergeSort(Node<T> *&list, int len)
{
if(len > 1){ //at least there are two elements
Node<T> * second , *end_of_the_first_sublist = list;
for(int i = 0; i < (len - 1) / 2; i++){ // discuss for odd and for even
end_of_the_first_sublist = end_of_the_first_sublist -> next;
}
second = end_of_the_first_sublist -> next;
end_of_the_first_sublist -> next = NULL; // add an end to the first part
int len_of_first_sublist = (len + 1)/ 2; // second part is [len-len_of_first_sublist]
MergeSort(list, len_of_first_sublist);
MergeSort(second, len-len_of_first_sublist);
list = merge(list, second);
}
return;
}
#define MAXN 20
int main()
{
Node<int> *list = new Node<int>(1);
for(int i = 2; i <= MAXN; i++){
list = new Node<int>(i, list);
}
cout << "before sort:\n"; PrintList(list);
//MergeSort(list);
MergeSort(list, MAXN);
cout << "after sorted\n"; PrintList(list);
return 0;
}