排序算法总结(下)

4.堆排序

  • 思路:堆就是一个完全二叉树(小顶堆),
  • 主要解决两个问题:
    • 如何将n个待排序的数构建成堆
    • 输出堆顶元素之后如何调整剩下的n-1个元素,使之成为新的堆
  • 时间复杂度:O(nlogn)

代码实现:

private static class HeapSort {
        public HeapSort(int a[]) {
            buildMaxHeapify(a);
            heapSort(a);
            System.out.println("");
            System.out.println("****4.堆排序之后:****");
            for (int i = 0; i < a.length; i++) {
                System.out.print(a[i] + ",");
            }
        }
        // 构建初始最大堆
        // 假设长度为8 那么
        // 第一个父节点就是a[3] 左结点为:a[7]
        // 第二个父节点为:a[1] 左节点为:a[3] 右结点为:a[4]
        // 第三份父节点为:a[2] 左节点为:a[5] 右结点为:a[6]

        public static void buildMaxHeapify(int a[]) {
            System.out.println("字符串的长度为:" + a.length);
            int startIndex = getParentIndex(a.length - 1);
            for (int i = startIndex; i >= 0; i--) {
                maxHeapify(a, a.length, i);
            }
        }

        /**
         * 
         * @param a
         *            数组
         * @param length
         *            数据长度
         * @param index
         *            当前的父节点
         */
        private static void maxHeapify(int[] a, int length, int index) {
            // 与当前左右结点进行比较
            int left = getChildLeftIndex(index);
            int right = getChildRightIndex(index);

            // 进行左右节点值的对比
            int largest = index;
            if (left < length && a[left] > a[index]) {
                largest = left;
            }
            if (right < length && a[right] > a[largest]) {
                largest = right;
            }
            if (largest != index) {
                int temp = a[index];
                a[index] = a[largest];
                a[largest] = temp;
                // 整理节点
                maxHeapify(a, length, largest);
            }
        }

        // 父节点的位置
        private static int getParentIndex(int i) {
            return i / 2;
        }

        // 左孩子的位置
        private static int getChildLeftIndex(int index) {
            return index * 2 + 1;
        }

        // 右孩子的位置
        private static int getChildRightIndex(int index) {
            return index * 2 + 2;
        }

        /**
         * 这个函数的含义就是: 将排好的最大堆的堆顶和最后一个交换再进行最大堆排序 排序:最大值放在末尾,再次进行排序
         * 
         * @param a
         */
        public static void heapSort(int a[]) {
            for (int i = a.length - 1; i > 0; i--) {
                int temp = a[0];
                a[0] = a[i];
                a[i] = temp;
                maxHeapify(a, i, 0);
            }
        }
    }

5.冒泡排序

  • 思路:就是不断的两两比较
  • 时间复杂度:O(n^2)

代码实现

private static class BubbleSort {

        //简单的冒泡排序
        public static void bubbleSort_A(int a[]) {
            for (int i = 0; i < a.length; i++) {
                for (int j = 0; j < a.length-i- 1; j++) {
                    if (a[j] > a[j + 1]) {
                        Swap(a, j, j + 1);
                    }
                }
            }
        }

        //改进的冒泡,添加了标记
        public static void bubbleSort_B(int a[]){
            int n = a.length-1;
            while(n>0){
                int pos = 0;
                for (int i = 0; i < n; i++) {
                    if(a[i]>a[i+1]){
                        pos = i;
                        Swap(a, i, i+1);
                    }
                }
                n = pos;
            }
        }
    }

6.快速排序

  • 思路:
    • 选择一个基准元素
    • 通过一次快排序将待排序数分为两个部分,一部分比基准数小,一部分比基准数大
    • 然后接着对这两部分进行相同的操作,直到序列有序
  • 时间复杂度:O(nlogn)
  • 空间复杂度: O(nlogn)

快速排序代码

private static class QuickSort{
        public static void quickSort(int a[],int low,int high){
            if(low<high){
                int privotLoc = partition(a,low,high);
                quickSort(a, low, privotLoc-1);
                quickSort(a, privotLoc+1, high);
            }
        }

        private static int partition(int[] a, int low, int high) {
            int privotKey = a[low];
            while(low<high){
                while(low<high && a[high]>=privotKey)--high;//从后半部分向前扫描
                a[low] = a[high];
                while(low<high && a[low]<=privotKey)++low; //从前部分扫描
                a[high] = a[low];
            }
            a[high] = privotKey;
            return low;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值