首页 > 其他分享 >数据结构学习笔记-归并排序

数据结构学习笔记-归并排序

时间:2024-06-06 21:33:14浏览次数:13  
标签:归并 排序 int arr 数组 n1 n2 数据结构

归并排序算法的设计与分析

问题描述:设计并分析归并排序算法

【算法设计思想】

  1. 分割(Divide):
    • 从中间分割数组,使每个子数组包含一半的元素。
    • 这通过计算中点m来完成,通常是(l + r) / 2,但为了防止大数溢出,使用l + (r - l) / 2
  2. 解决(Conquer):
    • 递归地对两个子数组应用归并排序,直到子数组只有一个元素。
    • 单个元素被视为已排序,因为没有其他元素可以比较。
  3. 合并(Merge):
    • 合并两个已排序的子数组以产生一个新的有序数组。
    • 创建两个临时数组来存储这两个子数组的元素。
    • 对这两个临时数组进行遍历,选择较小的元素放入原数组中,直到一个临时数组被完全复制。
    • 如果有剩余的元素,将它们复制到原数组中以完成合并。

【算法描述】

// 合并两个子数组为一个有序数组
void merge(int arr[], int l, int m, int r) {
    int i, j, k;
    int n1 = m - l + 1;
    int n2 = r - m;

    // 创建临时数组
    int L[n1], R[n2];

    // 拷贝数据到临时数组L[]和R[]
    for (i = 0; i < n1; i++)
        L[i] = arr[l + i];
    for (j = 0; j < n2; j++)
        R[j] = arr[m + 1 + j];

    // 合并临时数组到原数组arr[]
    i = 0;
    j = 0;
    k = l;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }

    // 拷贝L[]的剩余元素
    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }

    // 拷贝R[]的剩余元素
    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }
}

// l是左索引,r是右索引的数组将要排序的一部分
void mergeSort(int arr[], int l, int r) {
    if (l < r) {
        // 与 (l+r)/2相同,但是用于避免溢出大的l和h
        int m = l + (r - l) / 2;

        // 对左右半边分别进行递归排序
        mergeSort(arr, l, m);
        mergeSort(arr, m + 1, r);

        // 合并两个半边
        merge(arr, l, m, r);
    }
}

【完整的测试程序】

#include <stdio.h>

// 合并两个子数组为一个有序数组
void merge(int arr[], int l, int m, int r) {
    int i, j, k;
    int n1 = m - l + 1;
    int n2 = r - m;

    // 创建临时数组
    int L[n1], R[n2];

    // 拷贝数据到临时数组L[]和R[]
    for (i = 0; i < n1; i++)
        L[i] = arr[l + i];
    for (j = 0; j < n2; j++)
        R[j] = arr[m + 1 + j];

    // 合并临时数组到原数组arr[]
    i = 0;
    j = 0;
    k = l;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }

    // 拷贝L[]的剩余元素
    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }

    // 拷贝R[]的剩余元素
    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }
}

// l是左索引,r是右索引的数组将要排序的一部分
void mergeSort(int arr[], int l, int r) {
    if (l < r) {
        // 与 (l+r)/2相同,但是用于避免溢出大的l和h
        int m = l + (r - l) / 2;

        // 对左右半边分别进行递归排序
        mergeSort(arr, l, m);
        mergeSort(arr, m + 1, r);

        // 合并两个半边
        merge(arr, l, m, r);
    }
}

/* 用于打印数组的实用函数 */
void printArray(int A[], int size) {
    for (int i = 0; i < size; i++)
        printf("%d ", A[i]);
    printf("\n");
}

/* 测试归并排序 */
int main() {
    int arr[] = {38, 27, 43, 3, 9, 82, 10};
    int arr_size = sizeof(arr) / sizeof(arr[0]);

    printf("原始数组: \n");
    printArray(arr, arr_size);

    mergeSort(arr, 0, arr_size - 1);

    printf("\n排序后的数组: \n");
    printArray(arr, arr_size);
    return 0;
}

标签:归并,排序,int,arr,数组,n1,n2,数据结构
From: https://www.cnblogs.com/zeta186012/p/18236063

相关文章

  • 八大排序(使用C语言)
    完整代码链接:诶嘿/DataStructure-码云-开源中国(gitee.com)目录一、排序的概念及应用:1.排序的概念:2.排序应用:二、常见排序算法的实现: 1 插入排序:1.1基本思想:1.2直接插入排序:1.2.1代码实现: 1.2.2测试:1.2.3时空复杂度:1.3希尔排序(缩小增量排序):1.3.1......
  • 快速排序(排序中篇)
    1.快速排序的概念及实现2.快速排序的时间复杂度3.优化快速排序4.关于快速排序的细节5.总代码1.快速排序的概念及实现1.1快速排序的概念快速排序的单趟是选一个基准值,然后遍历数组的内容把比基准值大的放右边,比基准值小的放在左边,下面的动图可以简单了解是这么排序的。......
  • 一文带你搞定八大排序算法
    目录前言排序的时间复杂度、稳定性插入排序直接插入排序 时间复杂度希尔排序 时间复杂度选择排序选择排序 时间复杂度堆排序交换排序冒泡排序 时间复杂度快速排序左右指针法 优化:三数取中 优化:小区间优化挖坑法前后指针法快速排序非递归法 时间复......
  • 冒泡排序、插入排序、快速排序
    三种排序:冒泡排序、插入排序、快速排序规则:冒泡排序:每一轮循环后,最大的一个数被交换到末尾,因此,下一轮循环就可以“刨除”最后的数,每一轮循环都比上一轮循环的结束位置靠前一位。插入排序:将待排序数组分为已排序和未排序两部分,初始已排序部分只包含第一个元素。然后,从第二个元素......
  • 三种常见的排序方法
    一.比较交换排序法方法:将第一个元素的数据与其后的每个数据进行比较。如果不符合比较类型,则交换数据。例如:将一组数据15,8,4,13,6,10,17,1按照由小到大的顺序递增排列     分析:第一轮arr[0]分别与后面的数据比较,互换数值,将最小的数安排在下标是0的数组元素中。 ......
  • 八(汇编程序设计):输入5个同学成绩(有学号提示),然后排序,最后显示出名次表(学号,成绩)。要求:应
    代码DSEG SEGMENTGRADEDB5DUP(0)XUEHAODB'1','2','3','4','5'BUFDB4DUP(0)INFDB"Student",'$'NEWLINEDB0DH,0AHDSEGENDSSSEGSEGMENTSTACKSKTOPDB50DUP(0)S......
  • 快速排序——AcWing785.快速排序
    AcWing785.快速排序题目描述785.快速排序-AcWing题库运行代码#include<iostream>#include<algorithm>usingnamespacestd;constintN=1e6+6;intq[N];voidquick_sort(intq[],intl,intr){if(l>=r)return;intm=l+r>>1;//>......
  • Hive3.1.2分区与排序(内置函数)
    1、Hive分区(十分重要!!)分区的目的:避免全表扫描,加快查询速度!在大数据中,最常见的一种思想就是分治,我们可以把大的文件切割划分成一个个的小的文件,这样每次操作一个个小的文件就会很容易了,同样的道理,在hive当中也是支持这种思想的,就是我们可以把大的数据,按照每天或者每小时切分......
  • 递归在多级数据结构中的简单应用
    哈喽,我是小码,半年多没更新了,这段时间换了新工作,工作也很忙。后续会尽量多写点,坚持确实是一件很难,很酷的事情。最近在公司负责开发商品有关的开发,商品包含类型、款式等属性,而类型可能有一级类型、二级类型甚至是三级类型,针对这种多级分类,这就就不好使用简单的查询了。之前也写了一......
  • 数据结构基础篇(6)
    二十三、队列的表示和操作的实现相关术语队列是仅在表尾进行插入操作,在表头进行删除操作的线性表表尾既a~n段,称对尾;表头a~1段,称队头它是一种先进先出(FIFO)的线性表入队:插入元素出队:删除元素队列的存储结构为链对或顺序对(常用循环顺序队)队列的常见应用脱机打印输......