归并排序

目录

 

连续结构的归并排序:

递归版:

迭代版本归并排序

链式结构的归并排序:

单链表版本


连续结构的归并排序:

递归版:

#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;
}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值