JavaDay10

学习来源:日撸 Java 三百行(41-50天,查找与排序)_闵帆的博客——CSDN博客

在前面的基础上加上一些常用的其他排序

1. 快速排序

        交换排序中最主要的就是冒泡排序和快速排序。

        快速排序的基本思想是居于分治法,在待排序表中任取一个元素作为基准pivot,通过一趟排序将待排序表划分为两个独立部分,其中一部分元素全都小于pivot,另一部分元素都大于pivot,此时作为基准的元素就处于其最终的位置上。然后分别对剩余的两个部分重复上述操作直到每个部分为空或仅有一个元素,此时所有元素都在其最终的位置上,整个表有序。

        快速排序是平均性能最优的算法,但在对基本有序的表进行排序时,快速排序的效率并不高。

/**
     *********************
     * 快速排序
     *
     * @param paraStart 开始下标
     * @param paraEnd   结束下标
     *********************
     */
    public void quickSortRecursive(int paraStart, int paraEnd) {
        //无需移动
        if (paraStart >= paraEnd) {
            return;
        }//Of if

        int tempPivot = data[paraEnd].key;
        DataNode tempNodeForSwap;

        int tempLeft = paraStart;
        int tempRight = paraEnd - 1;

        //寻找中间节点的位置,同时将小的元素移到左边,将大的元素移到右边
        while (true) {
            while ((data[tempLeft].key < tempPivot) && (tempLeft < tempRight)) {
                tempLeft++;
            }//Of while

            while ((data[tempRight].key >= tempPivot) && (tempLeft < tempRight)) {
                tempRight--;
            }//Of while

            if (tempLeft < tempRight) {
                //交换元素
                //System.out.println("Swapping " + tempLeft + " and " + tempRight);
                tempNodeForSwap = data[tempLeft];
                data[tempLeft] = data[tempRight];
                data[tempRight] = tempNodeForSwap;
            } else {
                break;
            }//Of if
        }//Of while

        if (data[tempLeft].key > tempPivot) {
            tempNodeForSwap = data[paraEnd];
            data[paraEnd] = data[tempLeft];
            data[tempLeft] = tempNodeForSwap;
        } else {
            tempLeft++;
        } // Of if

        System.out.print("From " + paraStart + " to " + paraEnd + ": ");
        System.out.println(this);

        quickSortRecursive(paraStart, tempLeft - 1);
        quickSortRecursive(tempLeft + 1, paraEnd);
    }//Of quickSortRecursive

    /**
     *********************
     * 快速排序
     *********************
     */
    public void quickSort() {
        quickSortRecursive(0, length - 1);
    }//Of quickSort

    /**
     *********************
     * 快排方法测试
     *********************
     */
    public static void quickSortTest() {
        int[] tempUnsortedKeys = { 1, 3, 12, 10, 5, 7, 9 };
        String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
        DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

        System.out.println(tempDataArray);

        tempDataArray.quickSort();
        System.out.println("Result\r\n" + tempDataArray);
    }//Of quickSortTest

运行结果

 

2. 选择排序

        选择排序的基本思想是每一趟(第i趟)在未排序的元素中选择关键字最小的元素作为有序序列的第i个元素,直到第n-1趟,所有元素有序。

/**
     *********************
     * 选择排序
     *********************
     */
    public void selectionSort() {
        DataNode tempNode;
        int tempIndexForSmallest;

        for (int i = 0; i < length - 1; i++) {
            //初始化
            tempNode = data[i];
            tempIndexForSmallest = i;
            for (int j = i + 1; j < length; j++) {
                if (data[j].key < tempNode.key) {
                    tempNode = data[j];
                    tempIndexForSmallest = j;
                }//Of if
            }//Of for j

            data[tempIndexForSmallest] = data[i];
            data[i] = tempNode;
        }//Of for i
    }//Of selectionSort

    /**
     *********************
     * 选择排序方法测试
     *********************
     */
    public static void selectionSortTest() {
        int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9 };
        String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
        DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

        System.out.println(tempDataArray);

        tempDataArray.selectionSort();
        System.out.println("Result\r\n" + tempDataArray);
    }//Of selectionSortTest

运行结果

3. 堆排序

        堆排序借助完全二叉树实现,关键在于建堆和调整堆的过程。

/**
     *********************
     * 堆排序
     *********************
     */
    public void heapSort() {
        DataNode tempNode;
        //初始化堆
        for (int i = length / 2 - 1; i >= 0; i--) {
            adjustHeap(i, length);
        }//Of for i
        System.out.println("The initial heap: " + this + "\r\n");

        //调整堆
        for (int i = length - 1; i > 0; i--) {
            tempNode = data[0];
            data[0] = data[i];
            data[i] = tempNode;

            adjustHeap(0, i);
            System.out.println("Round " + (length - i) + ": " + this + '\n');
        }//Of for i
    }//Of heapSort

    /**
     *********************
     * 调整堆
     *
     * @param paraStart  开始下标
     * @param paraLength 要调整的序列长
     *********************
     */
    public void adjustHeap(int paraStart, int paraLength) {
        DataNode tempNode = data[paraStart];
        int tempParent = paraStart;
        int tempKey = data[paraStart].key;

        for (int tempChild = paraStart * 2 + 1; tempChild < paraLength; tempChild = tempChild * 2 + 1) {
            //右孩子更大
            if (tempChild + 1 < paraLength) {
                if (data[tempChild].key < data[tempChild + 1].key) {
                    tempChild++;
                }//Of if
            }//Of if

            System.out.println("The parent position is " + tempParent + " and the child is " + tempChild);
            if (tempKey < data[tempChild].key) {
                //孩子更大
                data[tempParent] = data[tempChild];
                System.out.println("Move " + data[tempChild].key + " to position " + tempParent);
                tempParent = tempChild;
            } else {
                break;
            }//Of if
        }//Of for tempChild

        data[tempParent] = tempNode;

        System.out.println("Adjust " + paraStart + " to " + paraLength + ": " + this);
    }//Of adjustHeap

    /**
     *********************
     * 堆排序方法测试
     *********************
     */
    public static void heapSortTest() {
        int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9 };
        String[] tempContents = { "if", "then", "else", "switch", "case", "for", "while" };
        DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

        System.out.println(tempDataArray);

        tempDataArray.heapSort();
        System.out.println("Result\r\n" + tempDataArray);
    }//Of heapSortTest

 运行结果

(建堆)

 (调整堆一趟)

 结果

4. 归并排序

         “归并”是将两个或两个以上的有序表组合成一个新的有序表。这里用的是二路归并。

/**
     *********************
     * 归并排序
     *********************
     */
    public void mergeSort() {
        //当前行
        int tempRow;
        //分组数
        int tempGroups;
        //0或者1
        int tempActualRow;
        int tempNextRow = 0;
        int tempGroupNumber;
        int tempFirstStart, tempSecondStart, tempSecondEnd;
        int tempFirstIndex, tempSecondIndex;
        int tempNumCopied;

        //输出表
        for (int i = 0; i < length; i++) {
            System.out.print(data[i]);
        }//Of for i
        System.out.println();

        DataNode[][] tempMatrix = new DataNode[2][length];

        //复制元素
        for (int i = 0; i < length; i++) {
            tempMatrix[0][i] = data[i];
        }//Of for i

        //排序
        tempRow = -1;
        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;

            tempGroups = length / (tempSize * 2);
            if (length % (tempSize * 2) != 0) {
                tempGroups++;
            }//Of if
            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) {
                    //复制前一个部分
                    for (int i = tempFirstStart; i < length; i++) {
                        tempMatrix[tempNextRow][i] = tempMatrix[tempActualRow][i];
                    }//Of for i
                    continue;
                }//Of if
                tempSecondEnd = tempGroupNumber * tempSize * 2 + tempSize * 2 - 1;
                if (tempSecondEnd > length - 1) {
                    tempSecondEnd = length - 1;
                }//Of if

                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++;
                    }//Of if
                    tempNumCopied++;
                }//Of while

                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++;
                }//Of while
            }//Of for groupNumber

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

        data = tempMatrix[tempNextRow];
    }//Of mergeSort

    /**
     *********************
     * 归并排序方法测试
     *********************
     */
    public static void mergeSortTest() {
        int[] tempUnsortedKeys = { 5, 3, 6, 10, 7, 1, 9 };
        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);
    }//Of mergeSortTest

运行结果

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值