归并排序算法 java 实现

归并排序算法 java 实现

可视化对比十多种排序算法(C#版)

[直观学习排序算法] 视觉直观感受若干常用排序算法

算法概念

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

算法思想

从概念上讲,归并排序的工作原理如下:

  • 如果列表的长度是0或1,那么它已经有序。否则:
  • 未排序的部分平均划分为两个子序列。
  • 每个子序列,递归使用归并排序。
  • 合并两个子列表,使之整体有序。

归并排序包含两个主要观点,以改善其运行时:

  • 一个小列表排序的花费少于大列表。
  • 把两个有序表合并,要比直接排列一个无序表花费更少的步骤。例如,您只需要遍历每个有序列表一次即可(见下面的合并功能)。

归并操作的过程如下:

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
  4. 重复步骤3直到某一指针到达序列尾
  5. 将另一序列剩下的所有元素直接复制到合并序列尾

算法实现

package com.lygedi.sort;

public class MergeSort {

    public void sort(int[] list, int iStart, int iStop) {
        if (iStop > iStart) {
            int iMiddle = (iStart + iStart) / 2;
            sort(list, iStart, iMiddle);
            sort(list, iMiddle + 1, iStop);
            merge(list, iStart, iMiddle, iStop);
        }
    }

    public void merge(int[] a, int iStart, int iMiddle, int iStop) {
        int lt = iStop - iStart + 1;

        int[] list = new int[lt];
        int pa = iStart;
        int pb = iMiddle + 1;

        for(int i = 0; i < lt; i++) {
            //利用两个指针对两个数组做对比,将小的放到临时数组
            if (a[pa] < a[pb]) {
                list[i] = a[pa];
                pa++;
            } else if (a[pa] == a[pb]) {
                list[i] = a[pa];
                i++;
                list[i] = a[pb];

                pa++;
                pb++;
            } else {
                list[i] = a[pb];
                pb++;
            }
            //一个指针到底后,将另一数组全部放到临时数组
            if (pa > iMiddle) {
                for (int j = i + 1; j < lt; j++) {
                    list[j] = a[pb];
                    pb++;
                }
                break;
            }

            if (pb > iStop ) {
                for (int j = i + 1; j < lt; j++) {
                    list[j] = a[pa];
                    pa++;
                }
                break;
            }
        }
        //将临时数组复制回原数组
        int j = iStart;
        for(int i = 0; i<lt; i++){
            a[j] = list[i];
            j++;
        }
    }

    public static void main(String[] args) {
        int a[] = { 49, 38, 65, 9, 76, 13, 27, 49, 8, 34, 12, 64, 49, 56, 2, 51, 13, 5, 4, 62, 99, 98, 54, 56, 17, 17,
                18, 23, 34, 56, 15, 35, 25, 53, 51 };

        MergeSort qs = new MergeSort();
        qs.sort(a, 0, a.length - 1);

        System.out.println(a.length);
        for (int i = 0; i < a.length; i++)
            System.out.println(Integer.toString(i) + "-" + a[i]);
    }
}

转载于:https://www.cnblogs.com/lygbzhu/p/5453803.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值