C++归并排序

归并排序

最近面试的时候被问到了归并排序,之前学数据结构的时候了解过,但是并没有手动实现过它的原理,今天实现一下。
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
其实也就是利用了递归的思想,把我们的整个序列不断的划分,直到划分到元素为1的N个子序列,然后开始合并。

算法思想

首先我们得将我们的序列转化成一个个子队列,直到分离到最小的单位,然后开始合并,分离很简单,那么如何合并呢?先上一张经典图:

在这里插入图片描述

红色的代表左右指针当前指向的元素,左指针是左边序列的开始,右指针是右边序列的开始,也是mid指针(他俩的中间位置)右边的元素,对比他们的大小,决定插入的顺序,如果左边的元素小于右边的元素,那么就往新空间插入这个元素,然后把左 指针往后移动一位,继续比较,如果小于则同上,直到我们的左指针大于等于我们的mid指针,或者右指针大于等于最右的位置,说明其中的一个序列已经对比完毕了,上图演示的是一种理想情况,其实我们有可能遇见一方序列全部小于一方序列的情况,那么这种情况我们需要手动将剩余序列填入合并序列的后面,然后我们重复这个过程,就可以完成一次归并排序了。

但是上面又个问题,我们合并的序列放在哪里?如果放在原队列的话可能会改变一些值,所以我们需要再开辟一片空间去记录中间状态的序列,下次合并还需要用到它,加上这个,代码思路就完整了。
下面看看代码:

代码实现:

// 归并排序
// 分离函数,参数x 和 y分别代表要分离数列的开头和结尾
int n;
int a[10], b[10];
void Merge(int low, int mid, int high);
void mergeSort(int x, int y) {
    if (x >= y) {
        return;
    }
    int mid = (x + y) / 2;
    // 递归继续合并
    mergeSort(x, mid);
    mergeSort(mid + 1, y);
    Merge(x, mid, y);
    
}
void Merge(int low, int mid, int high) {
    int i = low, j = mid + 1, k = low;
    while (i <= mid && j <= high) {
        if (a[i] < a[j]) {
            b[k++] = a[i++];
        } else {
            b[k++] = a[j++];
        }
    }
    while (i <= mid) {
        b[k++] = a[i++];
    }
    while (j <= high) {
        b[k++] = a[j++];
    }
    for (int i = low; i <= high; i++) {
        a[i] = b[i];
    }
 
}

int main(int argc, const char * argv[]) {
    // insert code here...
    cout << "请输入数组个数n:";
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    mergeSort(0, n - 1);
    for (int i = 0; i < n; i++) {
        cout << a[i] << endl;
    }
    return 0;
}

测试一下:
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值