日撸 Java 三百行day49

说明

闵老师的文章链接: 日撸 Java 三百行(总述)_minfanphd的博客-优快云博客
自己也把手敲的代码放在了github上维护:https://github.com/fulisha-ok/sampledata

day49 归并排序

1.基本思路

归并是将两个或两个以上的有序表组合成一个新的有序表,归并排序是分治思想的应用(分而治之)。如下是手动模拟二路归并排序,如下有7个数:
进行两两排序,得⌈7/2⌉=4(向上取整)有4个长度为2或1的分组,对每个分组进行排序,再进行⌈7/4⌉=2 有2个长度为4或3的分组,进行分组排序后,⌈7/7⌉=1 长度为7的一个分组,对这个分组进行排序。如下图所示
在这里插入图片描述

-------mergeSortTest-------
I am a data array with 7 items.
(50, if)  (39, then)  (66, else)  (98, switch)  (77, case)  (14, for)  (28, while)  
(50, if) 
(39, then) 
(66, else) 
(98, switch) 
(77, case) 
(14, for) 
(28, while) 

Current row = 0
tempSize = 1, numGroups = 4
Trying to merge [0, 0] with [1, 1]
copying (39, then) 
Trying to merge [2, 2] with [3, 3]
copying (98, switch) 
Trying to merge [4, 4] with [5, 5]
copying (14, for) 
Round 0
(39, then)  (50, if)  (66, else)  (98, switch)  (14, for)  (77, case)  (28, while)  
Current row = 1
tempSize = 2, numGroups = 2
Trying to merge [0, 1] with [2, 3]
copying (50, if) 
copying (66, else) 
Trying to merge [4, 5] with [6, 6]
copying (77, case) 
copying (28, while) 
Round 1
(39, then)  (50, if)  (66, else)  (98, switch)  (14, for)  (28, while)  (77, case)  
Current row = 2
tempSize = 4, numGroups = 1
Trying to merge [0, 3] with [4, 6]
copying (14, for) 
copying (28, while) 
copying (50, if) 
copying (66, else) 
copying (98, switch) 
copying (77, case) 
Round 2
(14, for)  (28, while)  (39, then)  (50, if)  (66, else)  (77, case)  (98, switch)  
I am a data array with 7 items.
(14, for)  (28, while)  (39, then)  (50, if)  (66, else)  (77, case)  (98, switch)  

2.代码实现

这段代码是非递归实现归并排序,我觉得读起来还是挺有难度的,首先是他的变量太多,其次在为每一次排序时,分多少组,分组长度不一致怎么解决以及分好组后如何进行排序等一些比较细节的东西。所以在段代码是需要结合图形来看才能更好的吸收内容

  /**
     * merge sort. Results are stored in the member variable data;
     */
    public void mergeSort() {
        //step1. Allocate space
        int tempRow; // the current row
        int tempGroups; // Number of groups
        int tempActualRow; // only 0 or 1
        int tempNextRow = 0;
        int tempGroupNumber;
        int tempFirstStart, tempSecondStart, tempSecondEnd;
        int tempFirstIndex, tempSecondIndex;
        int tempNumCopied;
        for (int i = 0; i < length; i++) {
            System.out.println(data[i]);
        }
        System.out.println();
        DataNode[][] tempMatrix = new DataNode[2][length];

        //step2 copy data
        for (int i = 0; i < length; i++) {
            tempMatrix[0][i] = data[i];
        }

        //step3.Merge log n rounds
        tempRow = -1;
        //进行几趟归并排序 tempSize:一个小组的大小
        for (int tempSize = 1; tempSize <= length; tempSize *= 2) {
            // Reuse the space of the two rows.
            tempRow++;
            System.out.println("Current row = " + tempRow);
            tempActualRow = tempRow % 2;
            tempNextRow = (tempRow + 1) % 2;

            // 在每趟排序中需要分为几组 乘以2是因为是2路归并
            tempGroups = length / (tempSize * 2);
            if (length % (tempSize * 2) != 0) {
                tempGroups++;
            }
            System.out.println("tempSize = " + tempSize + ", numGroups = " + tempGroups);

            //对两两分组进行排序
            for (tempGroupNumber = 0; tempGroupNumber < tempGroups; tempGroupNumber++) {
                //两组的起始位置
                tempFirstStart = tempGroupNumber * tempSize * 2;
                tempSecondStart = tempGroupNumber * tempSize * 2 + tempSize;
                
                if (tempSecondStart > length - 1) {
                    // Copy the first part.
                    for (int i = tempFirstStart; i < length; i++) {
                        tempMatrix[tempNextRow][i] = tempMatrix[tempActualRow][i];
                    }
                    continue;
                }
                //判断第二个分组与第一个是否等长 不等长则需要调整结尾是长度
                tempSecondEnd = tempGroupNumber * tempSize * 2 + tempSize * 2 - 1;
                if (tempSecondEnd > length - 1) {
                    tempSecondEnd = length - 1;
                }

                System.out
                        .println("Trying to merge [" + tempFirstStart + ", " + (tempSecondStart - 1)
                                + "] with [" + tempSecondStart + ", " + tempSecondEnd + "]");

                tempFirstIndex = tempFirstStart;
                tempSecondIndex = tempSecondStart;
                tempNumCopied = 0;
                while ((tempFirstIndex <= tempSecondStart - 1)
                        && (tempSecondIndex <= tempSecondEnd)) {
                    if (tempMatrix[tempActualRow][tempFirstIndex].key <= tempMatrix[tempActualRow][tempSecondIndex].key) {

                        tempMatrix[tempNextRow][tempFirstStart + tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
                        tempFirstIndex++;
                        System.out.println("copying " + tempMatrix[tempActualRow][tempFirstIndex]);
                    } else {
                        tempMatrix[tempNextRow][tempFirstStart
                                + tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
                        System.out.println("copying " + tempMatrix[tempActualRow][tempSecondIndex]);
                        tempSecondIndex++;
                    } 
                    tempNumCopied++;
                } 

                while (tempFirstIndex <= tempSecondStart - 1) {
                    tempMatrix[tempNextRow][tempFirstStart + tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
                    tempFirstIndex++;
                    tempNumCopied++;
                } // Of while

                while (tempSecondIndex <= tempSecondEnd) {
                    tempMatrix[tempNextRow][tempFirstStart + tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
                    tempSecondIndex++;
                    tempNumCopied++;
                } 
            } 

            System.out.println("Round " + tempRow);
            for (int i = 0; i < length; i++) {
                System.out.print(tempMatrix[tempNextRow][i] + " ");
            } 
            System.out.println();
        } 

        data = tempMatrix[tempNextRow];
    }

    public static void mergeSortTest() {
        //int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9 };
        int[] tempUnsortedKeys = { 50, 39, 66, 98, 77, 14, 28 };
        String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
        DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

        System.out.println(tempDataArray);

        tempDataArray.mergeSort();
        System.out.println(tempDataArray);
    }
-------mergeSortTest-------
I am a data array with 7 items.
(5, if)  (3, then)  (6, else)  (10, switch)  (7, case)  (1, for)  (9, while)  
(5, if) 
(3, then) 
(6, else) 
(10, switch) 
(7, case) 
(1, for) 
(9, while) 

Current row = 0
tempSize = 1, numGroups = 4
Trying to merge [0, 0] with [1, 1]
copying (3, then) 
Trying to merge [2, 2] with [3, 3]
copying (10, switch) 
Trying to merge [4, 4] with [5, 5]
copying (1, for) 
Round 0
(3, then)  (5, if)  (6, else)  (10, switch)  (1, for)  (7, case)  (9, while)  
Current row = 1
tempSize = 2, numGroups = 2
Trying to merge [0, 1] with [2, 3]
copying (5, if) 
copying (6, else) 
Trying to merge [4, 5] with [6, 6]
copying (7, case) 
copying (9, while) 
Round 1
(3, then)  (5, if)  (6, else)  (10, switch)  (1, for)  (7, case)  (9, while)  
Current row = 2
tempSize = 4, numGroups = 1
Trying to merge [0, 3] with [4, 6]
copying (1, for) 
copying (5, if) 
copying (6, else) 
copying (10, switch) 
copying (7, case) 
copying (9, while) 
Round 2
(1, for)  (3, then)  (5, if)  (6, else)  (7, case)  (9, while)  (10, switch)  
I am a data array with 7 items.
(1, for)  (3, then)  (5, if)  (6, else)  (7, case)  (9, while)  (10, switch)  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值