美文网首页
快速排序的递归和非递归实现

快速排序的递归和非递归实现

作者: just_like_you | 来源:发表于2019-07-24 23:07 被阅读0次

排序算法中很重要的快速排序


递归实现方式

递归实现方式的不同在于分区函数的不同

    public static void quickSort(int[] arr, int startIndex, int endIndex) {
        if (startIndex >= endIndex) {
            return;
        }
        //分区函数获取基准元素位置
        int pivotIndex = singleParition(arr, startIndex, endIndex);

        //分治递归
        quickSort(arr, startIndex, pivotIndex - 1);
        quickSort(arr, pivotIndex + 1, endIndex);
    }
  • 双向循环指针式,原理是利用左右指针分别维护较大数以及较小数区间

    private static int partition(int[] arr, int startIndex, int endIndex) {
        int pivot = arr[startIndex]; //使用第一个值作为基准值
        int left = startIndex; //左指针
        int right = endIndex; //右指针
    
         //当两指针不重合时循环
        while (left != right) {
            //当右指针大于基准值的时候指针左移
            while (left < right && arr[right] > pivot) {
                right--;
            }
            //当左指针小于基准值的时候指针右移
            while (left < right && arr[left] <= pivot) {
                left++;
            }
            //交换左右指针
            if (left < right) {
                swap(arr, left, right);
            }
        }
      
        //交换基准元素值和左/右指针
        arr[startIndex] = arr[left];
        arr[left] = pivot;

        return left;
    }
  • 单项循环指针式,使用单指针来区分较大和较小区域
    //单边循环分边函数,从小到大依次遍历,若小于基准值,则mark指针向右移动,
    //并且让移动后的mark指针当前遍历值互换,最后遍历结束互换mark和基准指针值,并返回mark指针位置
    private static int singleParition(int[] arr, int startIndex, int endIndex) {
        int pivot = arr[startIndex];
        int mark = startIndex;
        for (int i = startIndex; i <= endIndex; i++) {
            //若值比基准指针小则mark指针左移然后和该值交换
            if (arr[i] < pivot) {
                swap(arr, i, ++mark);
            }
        }
          //交换mark指针的基准值
        arr[startIndex] = arr[mark];
        arr[mark] = pivot;
        return mark;
    }

非递归实现方式

非递归实现方式主要借用了栈的数据结构,来完成递归操作,这里的分区函数和递归的一致

    public static void nonRecursiveQuickSort(int[] arr, int startIndex, int endIndex) {
  //初始化栈
        Stack<Map<String, Integer>> quickSortStack = new Stack<>();
        HashMap<String, Integer> paramMap = Maps.newHashMap();
        paramMap.put("startIndex", startIndex);
        paramMap.put("endIndex", endIndex);

        quickSortStack.push(paramMap);

        //栈不空
        while (!quickSortStack.isEmpty()) {
            Map<String, Integer> map = quickSortStack.pop();
            //从Map中获取对应属性值来获取基准点
            int pivot = singleParition(arr, map.get("startIndex"), map.get("endIndex"));
            if (map.get("startIndex") < pivot - 1) {
            //入栈模拟调用递归方法
                HashMap<String, Integer> left = Maps.newHashMap();
                left.put("startIndex", map.get("startIndex"));
                left.put("endIndex", pivot - 1);
                quickSortStack.push(left);

            }
            if (map.get("endIndex") > pivot + 1) {
                HashMap<String, Integer> right = Maps.newHashMap();
                right.put("endIndex", map.get("endIndex"));
                right.put("startIndex", pivot + 1);
                quickSortStack.push(right);

            }
        }
    }

相关文章

  • 三大排序算法

    归并排序[稳定的排序算法] 递归实现 非递归实现 快速排序[不稳定的排序算法] 堆排序[不稳定的排序算法]

  • 排序

    八大排序算法 一、归并排序 递归及非递归的JAVA实现 二、快速排序 快排算法JAVA实现 三、堆排序 堆排序堆排...

  • 排序——快排/归并(nlgn)

    快速排序一般是递归实现,但是递归有一个问题就是如果递归太深会导致栈溢出,而大部分的递归实现都有对应的非递归解决方案...

  • 快速排序的递归和非递归实现

    快速排序的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,...

  • 快速排序的递归和非递归实现

    排序算法中很重要的快速排序 递归实现方式 递归实现方式的不同在于分区函数的不同 双向循环指针式,原理是利用左右指针...

  • 简易快排和二分查找

    1.快排 快速排序有多种实现方式,有递归和非递归,之前遇到的解法多是递归的,而且分成了两部分代码,较难理解和使用,...

  • 常见算法的 Python 实现

    二分法查找 非递归版本: 递归方法实现: 冒泡排序 选择排序

  • 快速排序

    程序员小灰-快速排序 挖坑法 指针交换法 非递归实现

  • 2020-08-21 算法合集

    1. 冒泡排序 2.选择排序 3. 插入排序 4. 希尔排序 5. 归并排序(递归实现) 6. 快速排序(递归实现...

  • 折半查找

    要求:序列有序 实现:采用递归和非递归两种办法都能实现。 非递归: 递归:

网友评论

      本文标题:快速排序的递归和非递归实现

      本文链接:https://www.haomeiwen.com/subject/mrsqrctx.html