归并排序总结(JAVA实现)

为什么要写这篇

1.前段什么时间复习了一下数据结构,学习了一遍,又有了进一步的认识。说排序之前,先简单的总结一下数据结构。

数据目前分为线性结构和非线性结构;

线性结构

线性结构是最常用的数据结构,其特点是数据元素之间存在一对一的线性关系。按照存储结构又分为2种,一种是顺序存储(地址是连续的),一种是链式存储结构(地址不连续,但是每一块存储下一块的首地址)。

具体的就不在阐述,这篇文章写得很详细了

https://www.cnblogs.com/mr-wuxiansheng/p/8688946.html

非线性结构

一个典型结构就是树结构,开始我还不是很深刻的理解,最后我发现其实这些基本的东西都是有关联的,树结构相当于是链式结构的进化体了,他让线成了树,将结构变得有规律并且复杂了起来,最简单的就是二叉树,复杂的树就需要链表来搭建。

这里我们就简单说一下树的遍历,只有遍历了,你才能更好的对二叉树进行插入,删除,修改。

D代表根结点 ,L代表左子树,R代表右子树

有6遍历方案:DLR、LDR、LRD、RDL、RLD、LRD,

用的最多是前三种及先序遍历(DRL)、中序遍历(LDR)、后序遍历(LRD)

以先序遍历为例,后面其实都可以照搬方法

1先“访问”根结点   
2先序遍历左子树 
3先序遍历右子树

伪代码 (其实用c或者c++ 更能体现底层)

//二叉树结构
public class TreeNode{

    TreeNode left;

    String data;

    TreeNode right;
}

//递归算法
dlr(TreeNode tree){
    if(tree){
        print(tree.data);
        dlr(tree.left);
        dlr(tree.right);
    }
}

后面2种无非就是递归里面方法换个位置。

前面写了这么多也是为了给归并排序做个铺垫,看似没联系,其实我觉得还是有关联。

归并排序字面上就是说先分在合,先一个个划分,排序,在进行合并,很神奇的是最后排序成功了。

具体操作步骤

我们以最简单的数组为例吧  3,5,6,4,2,1

首先将数组拆分2组 left 3,5,6  right 4,2,1

拆分2组我们继续拆

1.left 3,5  right 6

2.left4,2 right 1

按照上述步骤继续拆下去,拆到只剩一个为止,然后就是合并,思路图如下

合并时候进行比较,较小的放到一个空数组,如果左右有剩余,现将左边放到之前空数组,然后放右边

最后上java代码

public class Test{

   private Integer[] nums = {3,8,9,10,7,6,5,2,4,1,11,12};

    @Test
    public void test() {

       devideSortArray(0,nums.length-1);
       

    }


    public void devideSortArray(Integer begin,Integer end){
        if (begin<end){
            Integer mid = (Integer)(begin+end)/2;
            System.out.print("获得"+begin+"---"+mid+"---"+end+"\n");
            devideSortArray(begin,mid);
            devideSortArray(mid+1,end);
            caculate(begin,mid,end,nums);
        }
    }

    
    public Integer[] caculate(Integer begin,Integer mid,Integer end,Integer[] showNum){
        Integer[] tempNum =new Integer[end+1];
        int k = begin;
        int left = begin;
        int right = mid+1;
        int cur = showNum[k];

        while (left <= mid && right <=end){
            if (showNum[left]>showNum[right]){
                tempNum[k] = showNum[right];
                right++;
                k++;
            }else {
                tempNum[k] = showNum[left];
                left++;
                k++;
            }
        }
        //左边有剩余 加入数组中
        while (left<=mid){
            tempNum[k] = showNum[left];
            left++;
            k++;
        }
        
        //右边有剩余 加入数组中
        while (right<=end){
            tempNum[k] = showNum[right];
            k++;
            right++;
        }

        int b = begin;
        int e = end;

        System.out.print("排列数--->>>>>>>\n");
        for (int i = 0; i < tempNum.length; i++) {
            if (tempNum[i] != null){
                System.out.print("---"+tempNum[i]);
                showNum[b] = tempNum[i];
                b++;
            }

        }
        System.out.print("<<<<<<<<<<\n");
        return tempNum;
    }

}

打印效果如下

获得0---5---11
获得0---2---5
获得0---1---2
获得0---0---1
排列数--->>>>>>>
---3---8<<<<<<<<<<
排列数--->>>>>>>
---3---8---9<<<<<<<<<<
获得3---4---5
获得3---3---4
排列数--->>>>>>>
---7---10<<<<<<<<<<
排列数--->>>>>>>
---6---7---10<<<<<<<<<<
排列数--->>>>>>>
---3---6---7---8---9---10<<<<<<<<<<
获得6---8---11
获得6---7---8
获得6---6---7
排列数--->>>>>>>
---2---5<<<<<<<<<<
排列数--->>>>>>>
---2---4---5<<<<<<<<<<
获得9---10---11
获得9---9---10
排列数--->>>>>>>
---1---11<<<<<<<<<<
排列数--->>>>>>>
---1---11---12<<<<<<<<<<
排列数--->>>>>>>
---1---2---4---5---11---12<<<<<<<<<<
排列数--->>>>>>>
---1---2---3---4---5---6---7---8---9---10---11---12<<<<<<<<<<

大功告成,发现跟二叉树算法遍历还是有很多相似之处。

最后总结,学好基础很重要,关联着学习,更加受益。

 

             

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值