精华内容
下载资源
问答
  • 快速排序 对冒泡排序的一种改进,若初始记录序列按关键字有序或基本有序,蜕化为冒泡排序。使用的是递归原理,在所有同数量级O(n longn) 的排序方法中,其平均性能最好。就平均时间而言,是目前被认为最好的一种内部...

    快速排序 对冒泡排序的一种改进,若初始记录序列按关键字有序或基本有序,蜕化为冒泡排序。使用的是递归原理,在所有同数量级O(n longn) 的排序方法中,其平均性能最好。就平均时间而言,是目前被认为最好的一种内部排序方法

    基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

    三个指针: 第一个指针称为pivotkey指针(枢轴),第二个指针和第三个指针分别为left指针和right指针,分别指向最左边的值和最右边的值。left指针和right指针从两边同时向中间逼近,在逼近的过程中不停的与枢轴比较,将比枢轴小的元素移到低端,将比枢轴大的元素移到高端,枢轴选定后永远不变,最终在中间,前小后大。

    需要两个函数:

    ① 递归函数  public static void quickSort(int[]n ,int left,int right)

    ② 分割函数(一趟快速排序函数) public static int partition(int[]n ,int left,int right)

    JAVA源代码(成功运行):

    package testSortAlgorithm;

    public class QuickSort {

    public static void main(String[] args) {

    int [] array = {49,38,65,97,76,13,27};

    quickSort(array, 0, array.length - 1);

    for (int i = 0; i < array.length; i++) {

    System.out.println(array[i]);

    }

    }

    /*先按照数组为数据原型写出算法,再写出扩展性算法。数组{49,38,65,97,76,13,27}

    * */

    public static void quickSort(int[]n ,int left,int right){

    int pivot;

    if (left < right) {

    //pivot作为枢轴,较之小的元素在左,较之大的元素在右

    pivot = partition(n, left, right);

    //对左右数组递归调用快速排序,直到顺序完全正确

    quickSort(n, left, pivot - 1);

    quickSort(n, pivot + 1, right);

    }

    }

    public static int partition(int[]n ,int left,int right){

    int pivotkey = n[left];

    //枢轴选定后永远不变,最终在中间,前小后大

    while (left < right) {

    while (left < right && n[right] >= pivotkey) --right;

    //将比枢轴小的元素移到低端,此时right位相当于空,等待低位比pivotkey大的数补上

    n[left] = n[right];

    while (left < right && n[left] <= pivotkey) ++left;

    //将比枢轴大的元素移到高端,此时left位相当于空,等待高位比pivotkey小的数补上

    n[right] = n[left];

    }

    //当left == right,完成一趟快速排序,此时left位相当于空,等待pivotkey补上

    n[left] = pivotkey;

    return left;

    }

    }

    展开全文
  • java 快速排序 递归The function calls itself until someone stops it. 该函数将自行调用,直到有人停止它为止。 Recursion can feel difficult to new developers. Perhaps that's because many resources teach...

    java 快速排序 递归

    The function calls itself until someone stops it.

    该函数将自行调用,直到有人停止它为止。

    Recursion can feel difficult to new developers. Perhaps that's because many resources teach it using algorithmic examples (Fibonacci, linked-lists). This piece will hopefully introduce things plainly, using one simple example.

    对于新开发人员而言,递归可能会感到困难。 也许是因为许多资源都使用算法示例(斐波纳契(Fibonacci),链接列表)来教它。 希望通过一个简单的例子,这篇文章将简单地介绍一下。

    核心思想 (Core Idea)

    Recursion is when a function calls itself until someone stops it. If no one stops it then it'll recurse (call itself) forever.

    递归是指函数调用自身直到有人停止它。 如果没有人停止,它将永远递归 (自称)。

    no-this-is-patrick

    Recursive functions let you perform a unit of work multiple times. This is exactly what for/while loops let us accomplish! Sometimes, however, recursive solutions are a more elegant approach to solving a problem.

    递归函数使您可以多次执行一个工作单元。 这正是for/while循环让我们完成的! 但是,有时递归解决方案是解决问题的一种更优雅的方法。

    倒数功能 (Countdown Function)

    Let's create a function that counts down from a given number. We'll use it like this.

    让我们创建一个从给定数字开始倒数的函数。 我们将像这样使用它。

    countDownFrom(5);
    // 5
    // 4
    // 3
    // 2
    // 1

    And here's our algorithm to solve this problem.

    这是我们解决此问题的算法。

    1. Take one parameter called number. This is our starting point.

      取一个称为number参数。 这是我们的出发点。

    2. Go from number down to 0, logging each one along the way.

      number降低到0 ,并沿途记录每个number

    We'll start with a for loop approach and then compare it to a recursive one.

    我们将从for循环方法开始,然后将其与递归方法进行比较。

    命令式方法(循环) (Imperative approach (loops))

    function countDownFrom(number) {
    	for (let i = number; i > 0; i--) {
    		console.log(i);
    	}	
    }
    
    countDownFrom(5);
    // 5
    // 4
    // 3
    // 2
    // 1

    This one contains both algorithmic steps.

    这包含两个算法步骤。

    1. ✅ Take one parameter called number.

      ✅取一个称为number参数。

    2. ✅ Log everything from number to 0.

      ✅记录从number0所有内容。

    递归方法 (Recursive approach)

    function countDownFrom(number) {
    	if (number === 0) {
    		return;
    	}
    
        console.log(number);    
        countDownFrom(number - 1);
    }
    
    countDownFrom(5);
    // 5
    // 4
    // 3
    // 2
    // 1

    This one also passes.

    这也过去了。

    1. ✅ Take one parameter called number.

      ✅取一个称为number参数。

    2. ✅ Log everything from number to 0.

      ✅记录从number0所有内容。

    So conceptually the two approaches are the same. However, they get the job done in different ways.

    因此,从概念上讲,这两种方法是相同的。 但是,他们以不同的方式完成工作。

    调试我们的命令性解决方案 (Debugging our imperative solution)

    For a more visual example, let's put a debugger in our loop version and throw it into Chrome Developer Tools.

    对于更直观的示例,让我们在循环版本中放入debugger ,然后将其放入Chrome开发者工具中。

    function countDownFrom(number) {
    	for (let i = number; i > 0; i--) {
    		console.log(i);
    		debugger;
    	}	
    }

    countdownFrom-iterative

    See how it uses an extra variable, i, to track the current number? As you iterate i decreases, eventually hitting 0 and terminating.

    看看它如何使用额外的变量i来跟踪当前数字吗? 随着您的迭代, i逐渐减少,最终达到0并终止。

    And in the for loop we specified "stop if i > 0".

    for循环中,我们指定“如果i > 0停止”。

    调试我们的递归解决方案 (Debugging our recursive solution)

    function countDownFrom(number) {
    	if (number === 0) {
    		return;
    	}
    
        console.log(number);
    	
    	debugger;
    
        countDownFrom(number - 1);
    }

    countdownFrom-recursive

    The recursive version doesn't need extra variables to track its progress. Notice how the pile of functions (call stack) grows as we recurse?

    递归版本不需要额外的变量来跟踪其进度。 注意我们递归时函数堆( 调用堆栈 )如何增长?

    That's because each call to countDownFrom adds to the stack, feeding it number - 1. By doing this we're we're passing along an updated number each time. No extra state needed!

    这是因为对countDownFrom的每次调用countDownFrom添加到堆栈中,并向其提供number - 1 。 通过这样做,我们每次都传递一个更新的number 。 不需要额外的状态!

    That's main difference between the two approaches.

    这是两种方法之间的主要区别。

    1. Iterative uses internal state (extra variables for counting, etc).

      迭代使用内部状态(用于计数的其他变量等)。
    2. Recursive does not, it simply passes updated parameters between each call.

      递归没有,它只是在每次调用之间传递更新的参数。

    But how does either version know when to stop?

    但是,哪个版本知道何时停止?

    无限循环 (Infinite Loops)

    In your travels, you may have been warned about the dreaded infinite loop.

    在旅行中,您可能已经被警告过可怕的无限循环。

    🚨 THIS RUNS FOREVER, BE WARNED 🚨
    while (true) { console.log('WHY DID YOU RUN THIS?!' }
    
    🚨 THIS RUNS FOREVER, BE WARNED 🚨
    for (i = 0;;) { console.log('WHY DID YOU RUN THIS?!') }

    Since they'd theoretically run forever, an infinite loop will halt your program and possibly crash your browser. You can prevent them by always coding a stopping condition.

    由于理论上它们将永远运行,因此无限循环将暂停您的程序,并可能导致浏览器崩溃。 您可以通过始终编写停止条件来防止它们发生。

    ✅ This does not run forever
    x = 0;
    while (x < 3) { console.log(x); x++; }
    
    ✅ This does not run forever
    for (x = 0; x < 3; x++) { console.log(x); }

    In both cases we log x, increment it, and stop when it becomes 3. Our countDownFrom function had similar logic.

    在这两种情况下,我们都记录x ,递增x ,然后在x变为3时停止。 我们的countDownFrom函数具有类似的逻辑。

    // Stop at 0
    for (let i = number; i > 0; i--)

    Again, loops need extra state to determine when they should stop. That's what x and i are for.

    同样,循环需要额外的状态来确定何时停止。 这就是xi是。

    无限递归 (Infinite Recursion)

    Recursion also presents the same danger. It's not hard to write a self-referencing function that'll crash your browser.

    递归也存在同样的危险。 编写会导致浏览器崩溃的自引用功能并不难。

    🚨THIS RUNS FOREVER, BE WARNED🚨
    function run() {
        console.log('running');
        run();
    }
    
    run();
    // running
    // running
    // ...

    is-this-a-recursive

    Without a stopping condition, run will forever call itself. You can fix that with an if statement.

    在没有停止条件的情况下, run将永远自我调用。 您可以使用if语句解决该问题。

    ✅ This does not run forever
    
    function run(x) {
        if (x === 3) return;
        
        console.log('running');
        run(x + 1);
    }
    
    run(0);
    // running
    // running
    // running
    
    // x is 3 now, we're done.

    基本情况 (Base case)

    This is known as the base case–our recursive countDownFrom had one.

    这被称为基本案例–我们的递归countDownFrom有一个。

    if (number === 0) {
        return;
    }

    It's the same idea as our loop's stopping logic. Whichever approach you pick, always remember that at some point it needs to be stopped.

    这与循环的停止逻辑相同。 无论选择哪种方法,请始终记住,必须在某个时候停止它

    is-this-you-need-to-be-stopped

    摘要 (Summary)

    • Recursion is when a function calls itself until someone stops it.

      递归是一个函数调用自身直到有人停止它的时间。
    • It can be used instead of a loop.

      可以使用它代替循环。
    • If no one stops it, it'll recurse forever and crash your program.

      如果没有人停止它,它将永远递归并崩溃您的程序。
    • A base case is a condition that stops the recursion. Don't forget to add them!

      基本情况是停止递归的条件。 不要忘记添加它们!

    • Loops use extra state variables for tracking and counting, while recursion only uses the provided parameters.

      循环使用额外的状态变量进行跟踪和计数,而递归仅使用提供的参数。

    disappearing-loops

    谢谢阅读 (Thanks for reading)

    For more content like this, check out https://yazeedb.com. And please let me know what else you'd like to see! My DMs are open on Twitter.

    有关此类的更多内容,请访问https://yazeedb.com 。 并且,请让我知道您还想看到什么! 我的DM在Twitter上打开。

    Until next time!

    直到下一次!

    翻译自: https://www.freecodecamp.org/news/quick-intro-to-recursion/

    java 快速排序 递归

    展开全文
  • 使用递归实现快速排序(Java实现)

    千次阅读 2018-10-13 19:58:47
    使用递归实现快速排序(Java实现) 1.先确定一个key值(也就是参考值),初状态定义如下 2.实现key的左边都是小于key的值,右边都是大于key的值 int key = arr[start];//防止访问溢出 while(start &amp;lt; end...

    使用递归实现快速排序(Java实现)

    一、

    1.先确定一个key值(也就是参考值),初状态定义如下
    在这里插入图片描述
    2.实现key的左边都是小于key的值,右边都是大于key的值

     int key = arr[start];//防止访问溢出
                while(start < end){
                    for(; end > start; end--){
                        if(arr[end] < key){
                            arr[start] = arr[end];
                            start++;
                            break;
                        }
                            
                    }
                    for(; start < end; start++){
                        if(arr[start] > key){
                            arr[end] = arr[start];
                            end--;
                            break;
                        }
                            
                    }
                    arr[start] = key;
                }
    

    3.用递归实现左右排序

     QuickSort(arr,copyStart,start);//左递归
     QuickSort(arr,start+1,copyEnd);//右递归
    

    完整程序

    public class Test{
    
        public static void main(String[] args){
            int[] arr = new int[]{3,5,6,1,2,8,9,3};
            for(int i = 0; i < arr.length; i++){
                System.out.print(arr[i]+"  ");
            }
                System.out.print("\n");
            QuickSort(arr,0,arr.length);
    
            for(int i = 0; i < arr.length; i++){
                System.out.print(arr[i]+"  ");
            }
        } 
        public static void QuickSort(int arr[],int start,int sz){
            int end = sz - 1;
            int copyEnd = sz;
            int copyStart = start;
            if(end > start){
                int key = arr[start];//防止访问溢出
                while(start < end){
                    for(; end > start; end--){
                        if(arr[end] < key){
                            arr[start] = arr[end];
                            start++;
                            break;
                        }
                            
                    }
                    for(; start < end; start++){
                        if(arr[start] > key){
                            arr[end] = arr[start];
                            end--;
                            break;
                        }
                            
                    }
                    arr[start] = key;
                }
                QuickSort(arr,copyStart,start);//左递归
                QuickSort(arr,start+1,copyEnd);//右递归
            }
    
        }
    
    
    }
    
    二、
    public class Test {
        private static int Partition(int[] arr, int start, int end) {
            int key = arr[start];
            while (start < end) {
                while (arr[end] >= key && end > start)
                    end--;
                arr[start] = arr[end];
                while (arr[start] <= key && end > start)
                    start++;
                arr[end] = arr[start];
            }
            arr[start] = key;
            return start;
        }
        public static void quickSort(int[] arr, int start, int end) {
            if (start < end) {
                int index = Partition(arr, start, end);
                quickSort(arr, start, index - 1);
                quickSort(arr, index + 1, end);
            }
        }
        public static void main(String[] args) {
            int[] data = new int[]{1,3,2,9,7,4,6,8,20,17,25,21};
            quickSort(data,0,data.length-1);
            for (int temp : data) {
                System.out.print(temp+"、");
            }
        }
    }
    
    展开全文
  • 快速排序递归实现) 我们知道快速排序有递归和非递归两种实现方法,这里只展示递归实现的代码。忘记该代码取自哪个网站了,如果侵权,请删! public class FastSort { public static void main(String []args){ ...

    快速排序(递归实现)

    我们知道快速排序有递归和非递归两种实现方法,这里只展示递归实现的代码。忘记该代码取自哪个网站了,如果侵权,请删!

    public class FastSort {
        public static void main(String []args){
            System.out.println("Hello World");
            int[] a = {12,20,5,16,15,1,30,45,23,9};
            int start = 0;
            int end = a.length-1;
            sort(a,start,end);
            for(int i = 0; i<a.length; i++){
                System.out.println(a[i]);
            }
        }
    
        public static void sort(int[] a,int low,int high){
            int start = low;
            int end = high;
            int key = a[low];
    
            while(end>start){
                //从后往前比较
                while(end>start && a[end]>=key)  //如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
                    end--;
                if(a[end]<=key){
                    int temp = a[end];
                    a[end] = a[start];
                    a[start] = temp;
                }
                //从前往后比较
                while(end>start && a[start]<=key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
                    start++;
                if(a[start]>=key){
                    int temp = a[start];
                    a[start] = a[end];
                    a[end] = temp;
                }
                //此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用
            }
            //递归
            if(start>low) sort(a,low,start-1);//左边序列。第一个索引位置到关键值索引-1
            if(end<high) sort(a,end+1,high);//右边序列。从关键值索引+1到最后一个
        }
    }
    
    展开全文
  • 快速排序属于一种划分交换排序方法,它采用了一种分治的策略。 基本思想如下: (1)从待排序的数中选取一个数作为基准数,一般选取第一个数。 (2)把比基准数大的数放在基准数后面,把比基准数小的数放在基准数...
  • java 递归实现快速排序

    千次阅读 2017-08-13 21:42:17
    快速排序的基本思想:  通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则分别对这两部分继续进行排序,直到整个序列有序。 先看一下这幅图:  把...
  • 主要为大家详细介绍了Java递归实现字符串全排列与全组合,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 快速排序 的原理及其java实现递归与非递归
  • java 快速排序 折半查找的界面实现递归与分治法)
  • 两种方法: 传统的递归快速排序 采用非递归堆栈模拟
  • 快速排序递归实现

    2019-10-10 12:43:39
    快速排序的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到...
  • GO语言非递归实现快速排序算法func QuickSort2(src []int) {SubSeqSet := make([][]int, 0)SubSeqSet = append(SubSeqSet, src)for len(SubSeqSet) > 0 {// pop one sequencesubSeq := SubSeqSet[len(SubSeqSet)-...
  • 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个...
  • 递归实现快速排序

    2020-12-21 20:49:47
    以前学习数据结构的时候写快排用的循环都是双重for循环,今天偶尔看到了运用递归来实现快速排序,所以突发想记录一下。由于我以前学过c和java,现在在自学python,所以一下代码均为python。但基本思想是一样的。 1....
  • 快速排序递归、非递归)(Java

    千次阅读 2018-05-03 21:12:27
    问题当数据量较大时(数组长度1000000),快速排序递归算法栈溢出,且实际运行时间也比其他算法长,我猜测是由于大量的函数调用。有人能分析一下吗?如何改进?递归private void quick_sort_recursive(int head, int...
  • java快速排序递归

    千次阅读 2019-03-25 16:41:35
    因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反*/ { i++; } a[j] = a[i]; } a[i] = key;/*当在当组内找完一遍以后就把中间数key回归*/ sort(a, left, i - 1);/*最后用同样...
  • 快速排序算法递归和非递归的思路以及java实现
  • 快速排序Java版(递归与非递归

    千次阅读 2019-07-03 19:36:29
    快速排序Java版) 听名字就很diao,直接上干货。(杠精别打我,支点的英文是pivot,我全拼错了) 快排一定要思路清晰,没事多写几遍,要不容易忘。 对于一个数组对它进行排序,快排的思想就是交换交换再交换,我们...
  • 与合并排序类似,quicksort也采用了分而治之,因此在Java中使用递归实现快速排序算法很容易,但编写quicksort的迭代版本稍微困难一些。这就是为什么面试官现在要求在不使用递归的情况下实现快速排序。面试首先要用...
  • 一、快速排序原理:   首先找到一个基准,一般以第一个元素作为基准(pivot),然后先从右向左搜索, 如果发现比pivot小,则和pivot交换,然后从左向右搜索,如果发现比pivot大,则和pivot交换,以此循环,一轮...
  • 基础总结一下,快速排序的步骤: 1、找到一个key值(就是数组第一个值),先从右到左找,找到一个比它小的值,记录下标。 2、然后从左往右找,找到一个比它大的值,记录下标。 3、交换找到的两个数字。 4、继续...
  • JAVA实现快速排序算法(递归快速排序是对冒泡排序的一种改进,它的基本思想是:选取数组中的第一个元素作为中间值,以中间值为基准,通过一趟排序后将要排序的数据分为两部分,左边部分的数值全部小于中间值,...
  • 快速排序使用“分而治之”的思想,在待排序的元素中选取某一元素作为基准值,通过一趟快速排序将待排序序列分割成两部分,基准值左边部分的所有元素均小于基准值,右边部分的所有元素均大于基准值,之后分别对这两...
  • 快速排序递归实现

    千次阅读 2018-05-15 23:49:29
    快速排序(Quicksort),又称划分交换排序(partition-exchange sort),简称快排,是一种效率很高的排序算法。 排序思路: ·从数列中挑出一个元素,称为&amp;amp;amp;quot;基准&amp;amp;amp;quot;...
  • Java实现快速排序递归和非递归

    千次阅读 2016-04-27 18:22:52
    * 快速排序 * */ public class QuickSort{ /** * 递归一 * */ public static void sort1(int[] arr, int start, int end) { if(start ){ //初始先将第一个值 int pvoit = arr[start]; int ...
  • 快速排序的算法思想、动态演示 、C++、python实现,请参考快速排序详解 快速排序也是一种选择排序。 快速排序的思想:将序列分为两部分,左边一部分比它小,右边一部分比它大。然后递归。这里的它,指的是基数。 ...
  • 递归实现时借助栈, package sort; import java.util.Stack; public class Sort { /*  * 非递归版本  */  public void quick2(int[] array){  if (array == null || array.length == 1) return...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 48,931
精华内容 19,572
关键字:

快速排序java递归实现

java 订阅
友情链接: XS128-pwm.rar