归并法排序

4 篇文章 0 订阅
1 篇文章 0 订阅

c语言实现

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


void merge(int a[],int p,int q,int r);
void merge_sort(int a[],int p,int r);
int main()
{
    int n,i;
    printf("请输入n\n");
    scanf("%d",&n);
    int num[n];
    printf("排序之前的数组:\n");
    for(i=0;i<n;i++) {
        num[i] = rand()%10+1;//产生从1-10的随机整数
        printf("%d ",num[i]);
    }
    printf("\n");
    merge_sort(num,0,n-1);
    printf("排序之后的数组:\n");
    for(i=0;i<n;i++) {
        printf("%d ",num[i]);
    }


    return 0;
}


//归并排序
void merge_sort(int a[],int p,int r) {
    int q;
    if(p<r) {
        q = (p+r+1)/2-1;
        merge_sort(a,p,q);
        merge_sort(a,q+1,r);
        merge(a,p,q,r);
    }


}


void merge(int a[],int p,int q,int r) {
    int n1,n2,i,j,k;


    //将数组分成两半
    n1 = q-p+1;
    n2 = r-q;


    //定义两个新的数组
    int m[n1+1],n[n2+1];


    //将新定义的两个数组的最后一个元素值设置成无穷大
    m[n1] = 9999;
    n[n2] = 9999;


    //进行两个新数组的赋值
    for(i=0; i<n1; i++) {
        m[i] = a[p+i];
    }
    for(j=0; j<n2; j++) {
        n[j] = a[q+j+1];
    }


    //进行排序
    i=0;
    j=0;
    for(k=p;k<=r;k++) {
        if(m[i] <= n[j]) {
            a[k] = m[i];
            i++;
        } else {
            a[k] = n[j];
            j++;
        }
    }


}


Java实现

package com.test;


import java.util.Random;
import java.util.Scanner;


public class MergeSort {


/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
long starttime = System.currentTimeMillis();
Scanner fin = new Scanner(System.in);
System.out.println("请输入n:");
int n = fin.nextInt();
int[] a = new int[n];
for(int i=0; i<n; i++) {
a[i] = new Random().nextInt(10)+1;
}
//排序前数组输出
System.out.println("排序前:");
for(int i=0; i<n; i++) {
System.out.print(a[i]);
System.out.print(" ");
}
System.out.println();
//调用排序函数
merge_sort(a,0,n-1);
//输出结果
System.out.println("排序后:");
for(int i=0; i<n; i++) {
System.out.print(a[i]);
System.out.print(" ");
}
long endtime = System.currentTimeMillis();
System.out.println("程序运行时间:"+(endtime-starttime)+"ms");
}

public static void merge_sort(int[] a,int p,int r) {
if(p < r) {
int q = (p+r+1)/2-1;
merge_sort(a,p,q);
merge_sort(a,q+1,r);
merge(a,p,q,r);
}
}

public static void merge(int[] a,int p,int q,int r) {
//p=0,q=个数/2-1,r=数组最后一个下标值
//一共r-p+1个
int n1 = q-p+1;
int n2 = r-q;
//新定义两个数组
int[] m = new int[n1+1];
int[] n = new int[n2+1];
//将新数组的最后一个元素赋值成无穷大,此处设为9999
m[n1] = 9999;
n[n2] = 9999;
//给新数组的其他元素赋初值
for(int i=0; i<n1; i++) {
m[i] = a[p+i];
}
for(int j=0; j<n2; j++) {
n[j] = a[q+1+j];
}
//进行排序
int i=0;
int j=0;
for(int k=p;k<=r;k++) {
if(m[i] <= n[j]) {
a[k] = m[i];
i++;
} else {
a[k] = n[j];
j++;
}
}
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
归并排序是一种基础的排序,其基本思想是将待排序的序列递归地分成两个子序列,分别进行排序,然后再将两个已排序的子序列合并成一个有序序列。具体过程如下: 1. 将待排序的序列平均分成两个子序列,然后分别对这两个子序列进行排序(递归调用归并排序)。 2. 合并两个已排序的子序列,生成一个新的有序序列。 下面是用C语言实现归并排序的示例代码: ```c void merge(int arr[], int left, int mid, int right, int temp[]) { int i = left, j = mid + 1, k = 0; while (i <= mid && j <= right) { if (arr[i] <= arr[j]) { temp[k++] = arr[i++]; } else { temp[k++] = arr[j++]; } } while (i <= mid) { temp[k++] = arr[i++]; } while (j <= right) { temp[k++] = arr[j++]; } for (i = 0; i < k; i++) { arr[left + i] = temp[i]; } } void merge_sort(int arr[], int left, int right, int temp[]) { if (left < right) { int mid = (left + right) / 2; merge_sort(arr, left, mid, temp); merge_sort(arr, mid + 1, right, temp); merge(arr, left, mid, right, temp); } } void sort(int arr[], int len) { int temp[len]; merge_sort(arr, 0, len - 1, temp); } ``` 在这段代码中,我们使用了递归来实现归并排序。首先定义一个 `merge` 函数,用于将两个已排序的子序列合并成一个新的有序序列。在 `merge` 函数中,我们定义三个指针 `i`、`j` 和 `k`,分别指向左子序列、右子序列和临时数组的起始位置。然后依次比较左右两个子序列中的元素,将较小的元素放入临时数组中,直到一个子序列遍历结束。然后将另一个子序列中剩余的元素依次放入临时数组中。最后将临时数组中的元素复制回原数组中。 接着定义一个 `merge_sort` 函数,用于对序列进行递归排序。在 `merge_sort` 函数中,我们首先判断左右边界是否相等,如果不相等,则计算出序列的中间位置 `mid`,然后递归地将左右两部分进行排序,最后再将两个已排序的子序列合并起来。 最后,我们定义一个 `sort` 函数,用于调用 `merge_sort` 函数对整个序列进行排序归并排序的时间复杂度为 $O(n\log n)$,是一种稳定的排序

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值