递归调用

快速排序

 ̄綄美尐妖づ 提交于 2020-03-06 12:32:34
快速排序(QuickSort) 划分的关键是要求出基准记录所在的位置pivotpos,编程时候的关键点 快速排序: 既然能把冒泡KO掉,马上就激起我们的兴趣,tnd快排咋这么快,一定要好好研究一下。 首先上图: 从图中我们可以看到: left指针,right指针,base参照数。 其实思想是蛮简单的,就是通过第一遍的遍历(让left和right指针重合)来找到数组的切割点。 第一步:首先我们从数组的left位置取出该数(20)作为基准(base)参照物。 第二步:从数组的right位置向前找,一直找到比(base)小的数, 如果找到,将此数赋给left位置(也就是将10赋给20), 此时数组为:10,40,50,10,60, left和right指针分别为前后的10。 第三步:从数组的left位置向后找,一直找到比(base)大的数, 如果找到,将此数赋给right的位置(也就是40赋给10), 此时数组为:10,40,50,40,60, left和right指针分别为前后的40。 第四步:重复“第二,第三“步骤,直到left和right指针重合, 最后将(base)插入到40的位置, 此时数组值为: 10,20,50,40,60,至此完成一次排序。 第五步:此时20已经潜入到数组的内部,20的左侧一组数都比20小,20的右侧作为一组数都比20大, 以20为切入点对左右两边数按照

八大排序(三)-------快速排序

蹲街弑〆低调 提交于 2020-03-06 08:59:47
快速排序法介绍: 快速排序(Quicksort)是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 感觉自己能力并不足以将一个问题,或算法讲解的足够清楚,只是在别人的基础上理解,明白了代码的含义,知道了执行的流程,知道了原理,但是要我自己讲述,或者深入的说出其底层原理,做不来 所以很多内容粗糙且模糊,见谅 所以这下面的是我参考的别人的讲解,来源忘了 假设我们现在对“6 1 2 7 9 3 4 5 10 8”这个10个数进行排序。首先在这个序列中随便找一个数作为基准数(不要被这个名词吓到了,就是一个用来参照的数,待会你就知道它用来做啥的了)。为了方便,就让第一个数6作为基准数吧。接下来,需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,类似下面这种排列。 3 1 2 5 4 6 9 7 10 8 在初始状态下,数字6在序列的第1位。我们的目标是将6挪到序列中间的某个位置,假设这个位置是k。现在就需要寻找这个k,并且以第k位为分界点,左边的数都小于等于6,右边的数都大于等于6。想一想,你有办法可以做到这点吗? 给你一个提示吧。请回忆一下冒泡排序,是如何通过“交换”

py04_03:函数之递归函数

Deadly 提交于 2020-03-06 02:15:05
递归函数的定义:在函数内部,函数自身调用自己的return值,就叫做递归函数   要求:1. 必须有一个明确的结束条件:      2. 每次相对减少,不可能增加,否则永远不能结束,则出错      3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)  来源: https://www.cnblogs.com/yeyu1314/p/12424100.html

递归算法

℡╲_俬逩灬. 提交于 2020-03-05 19:55:21
直接或间接调用函数本身,则该函数称为递归函数。 舍得舍得,有舍才有得。 递归递归,有递才有归。 递归,先确定终止条件或者说是出口。当参数为何值时,递归结束,之后直接把结果返回。注意,确定出口时前几个数可能不能用规律得出,需要一 一确定下来。 再根据不同的条件进行变化,即找出函数的等价关系式。 举一个简单例子 Fibonacci具体 : int fib ( int n ) { if ( n <= 1 ) return 1 ; return fib ( n - 1 ) + fib ( n - 2 ) ; } 再举个经典例子阶乘 int f ( int n ) { if ( n == 0 ) return 1 ; else return n * f ( n - 1 ) ; } 实际上递归虽然看似很精简,实际效率很低,时间复杂度可达到O(2^N )。 递归调用实际上是函数自己在调用自己,而函数的调用开销是很大的,系统要为每次函数调用分配存储空间,并将调用点压栈予以记录。而在函数调用结束后,还要释放空间,弹栈恢复断点。所以说,函数调用不仅浪费空间,还浪费时间。 ——作者:Clemente 链接:https://www.jianshu.com/p/7a10b0221964 来源: CSDN 作者: 恋霏雨 链接: https://blog.csdn.net/z2431435/article

1、算法初识

痴心易碎 提交于 2020-03-05 12:42:10
1.什么是 算法 ? 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。 也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。 如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。 不同的算法可能用不同的时间、空间或效率来完成同样的任务。 一个算法的优劣可以用空间复杂度与时间复杂度来衡量。 算法中的指令描述的是一个计算,当其运行时能从一个初始状态和(可能为空的)初始输入开始,经过一系列有限而清晰定义的状态,最终产生输出并停止于一个终态。 一个状态到另一个状态的转移不一定是确定的。随机化算法在内的一些算法,包含了一些随机输入。 1.1特征 一个算法应该具有以下五个重要的特征: 有穷性 (Finiteness) 算法的有穷性是指算法必须能在执行有限个步骤之后终止; 确切性 (Definiteness) 算法的每一步骤必须有确切的定义; 输入项 (Input) 一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定出了初始条件; 输出项 (Output) 一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的; 可行性 (Effectiveness) 算法中执行的任何计算步骤都是可以被分解为基本的可执行的操作步

2.递归--基本概念及思路

徘徊边缘 提交于 2020-03-05 10:55:40
递归设计经验: 1.找重复:找到规模更小的子问题(本次做一部分剩下的分给下一次调用函数去做) 2.找重复中的变化量-->参数 3.找参数的变化趋势-->设计出口 思路: 1.(切蛋糕)将一个大问题分解为子问题(一个小问题或多个子问题) 2.递推公式(逐步变小) 例如:n的阶乘,斐波那契数列等 1.思路一:小练习:字符串的反转(从后向前递归) static String reverse(String src,int end)//字符串的反转 { if(end==0) return ""+src.charAt(0); return src.charAt(end)+reverse(src,end-1);//charAt() 方法用于返回指定索引处的字符。索引范围为从 0 到 length() - 1 } 2.思路二:最大公约数(辗转相除) static int f5(int a,int b) { if(a%b==0)return b; int k=a%b; a=b;b=k; return f5(a,b); } //f5简化为f6 static int f6(int a,int b) { if(a%b==0)return b; return f6(b,a%b); } 3.(思路一)插入排序的递归函数 static void insertsort(int arr[],int k)/

算法图解|选择排序和递归

帅比萌擦擦* 提交于 2020-03-03 22:30:30
一:选择排序,O(n2) 选择排序是一种灵巧的算法,但其速度不是很快 代码示例: # 选择排序:O(nxn) # 找出数组中最小的元素 def findsmallest(arr): # 假设小值为arr[0] smallest = arr[0] # 存储最小元素的索引 smallest_index = 0 # O(n) for i in range(1, len(arr)): if arr[i] < smallest: smallest = arr[i] smallest_index = i return smallest_index # 对数组进行选择排序 def selectionSort(arr): newArr = [] # O(nxn) for i in range(len(arr)): smallest_index = findsmallest(arr) # 将该索引的元素添加到newArr newArr.append(arr.pop(smallest_index)) return newArr print(selectionSort([1, 8, 6, 9, 10])) # [1, 6, 8, 9, 10] 二:递归 问题:有个盒子里有盒子,而盒子里的盒子又有盒子。钥匙就在某个盒子中。怎么能找到钥匙。 代码示例: 第一种方法: 详细检查盒子内的东西

递归排序数组(图文讲解)

僤鯓⒐⒋嵵緔 提交于 2020-03-03 20:54:21
递归排序数组 本人为一名普通二本学校自动化专业的大二学生,对编程有着少许兴趣。 小郑最近一直都有在看视频学习递归,所以想写一篇博客作为学习笔记。 题目要求 计划输入一组乱序数组给递归函数,然后输出排好序的数组(从小到大)。 题中要求用递归来给数组排序,所以我们可以通过次递归函数排一个的情况,将每个数排到相应位置上。对这个问题,我给出了两个方案。 方案一:前排法 将要排序的元素下标和值都先保存下来,然后再向“前面”和其他元素比较。 首先由于递归函数的调用,k不断“-1”,最后到k==1的时候停止,然后开始回到“上一个”递归函数,开始第二个元素排序。 第二个元素排序 我们可以想象将第一个元素“拿出来”,与第一个元素比较,如果temp比arr[index]大的话则放回原位,否则与第一个元素交换。 第三个元素排序出现了前面比后面大的情况。当第二个元素(6)大于temp(3)时,第二个元素成为第三个元素。 temp要与第一个元素相比较,大于第一个元素则,temp成为了第二个元素,排序成功。 接下来步骤都相似,我就不再这里一一列举了(若想加深理解,可以看看后排法,图文更加详细、清晰)。 //递归排序数组 # include <bits/stdc++.h> using namespace std ; void f ( int * arr , int k ) { if ( k == 1 )

二叉树图解以及二叉树的递归原理

帅比萌擦擦* 提交于 2020-03-03 20:46:18
递归(recursion) 又称递回,在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。 一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。 构成递归需具备的条件: 1. 子问题须与原始问题为同样的事,且更为简单; 2. 不能无限制地调用本身,须有个出口,化简为非递归状况处理。 代码取自美国课本 "Java How to Program "(Deitel & Detel)的练习: 20.25。 以中序遍历递归方法为例,这里显示的图解,仅诠释开始一小部分递归前进段与递归返回段的交叉过程。通过这一小段的繁琐解释,希望读者可见到二叉树递归遍历的端倪。 private void inorderHelper( TreeNode node ){ if ( node == null ) //若节点为空 return; //无任何操作 inorderHelper( node.leftNode ); //有序遍历下一级左子树 System.out.print( node.data + " " ); //输出节点数据 inorderHelper( node.rightNode );//有序遍历下一级右子树 } 插图说明: 前进段的进程 1 :鉴于以树根 节点 "49" 为参数,调用 inorderHelper(...)

Python之递归

北城以北 提交于 2020-03-03 05:28:15
python之递归 递归的特征:有调用自身函数的行为 2.有正确的返回条件(不能写成死循环了) 1. 汉诺塔 def hanoi ( n , x , y , z ) : #n代表盘子的层数(个数),x代表盘子的初始位置,y代表盘子中间缓存的位置,z代表盘子的目的位置,这三个位置一定要搞清楚!!! if n == 1 : print ( x , "-->" , z ) else : hanoi ( n - 1 , x , z , y ) #先将n-1个盘子放到Y上去() print ( x , "-->" , z ) #再将第n个盘子(最底下的盘子)从X放入到Z上面去 hanoi ( n - 1 , y , x , z ) #最后把在Y上面的n-1个盘子放到Z上面去 hanoi ( 3 , "a" , "b" , "c" ) 2. 求阶乘 ``python def factorial ( n ) : if n == 1 : return 1 else : return n * factorial ( n - 1 ) num = input ( "请输入一个整数,以便求其阶乘:" ) num = int ( num ) print ( "%d 的阶乘是 %d" % ( num , factor ( num ) ) ) 3.一块长方形能被切割成完全一样的正方形的边长是多少?