递归算法

树的递归和非递归遍历

ε祈祈猫儿з 提交于 2019-11-29 23:41:38
利用循环和栈实现前序、中序和后序遍历、利用队列实现层次遍历 typedef struct node { int data; int cnt;//在后序遍历中使用,子树的根节点在第一次遍历的时候不会输出,只有在第二次遍历的时候才输出。 struct node *lchild; struct node *rchild; }bitree; stack<node*> s; 前序遍历 //针对一个根结点,先输出其根结点值,再push其所有左结点,然后再弹出一个结点取其右结点作为新的根结点。 void preorder(bitree *t)//前序遍历的非递归算法 { bitree *temp = t; while(temp != NULL || !s.empty()) { //遍历所有左结点 while(temp != NULL)//先遍历左孩子,并输出。 { printf("%4d",temp->data); s.push(temp); temp = temp->lchild; } if(!s.empty())//当左孩子遍历完后,取栈顶,找右孩子。此时循环还没有结束,再遍历它的左孩子,直至孩子全部遍历结束。 { temp = s.top(); s.pop(); temp = temp->rchild; } } printf("\n"); } 中序遍历 void inorder

使用递归来实现螺旋矩阵

混江龙づ霸主 提交于 2019-11-29 21:50:20
螺旋矩阵问题 问题描述: 螺旋矩阵是指一个呈螺旋状的矩阵,它的数字由第一行开始到右边不断变大,向下变大,向左变大,向上变大,如此循环。 创建n阶螺旋矩阵并输出。 输入描述: 输入包含多个测试用例,每个测试用例为一行,包含一个正整数n(1≤n≤50),用输入0表示结束。 输出描述 : 每个测试用例输出n行,每行包含n个整数,整数之间用一个空格分隔。 样例 输入: 4 0 输出: 1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 7 问题分析 :一个n阶的二维数组,从起始位开始向左、向下、向右、向上螺旋变大,输入n并输出这个二维数组,可以把问题由不同的增长方向分为四步,每完成一轮四步则规模减小2阶,起始数变为前面一轮的末尾加1,即问题变为解决为n的每一轮再加上规模为n-2的问题 算法设计:对规模为n的先按顺序向左、向下、向右、向上变大,最后再进行规模为n-2的增加,当最后为0的时候结束,若初始规模n为奇数,则最后规模为1的时候加上前一个值+1 代码实现 : void num(int a,int**n,int begin,int first) { int i, j, k; if (a == 0) { return;//已经赋值完 } if (a == 1) {//第一个为first n[begin][begin] = first; return; } i =

递归与分治

人盡茶涼 提交于 2019-11-29 21:50:12
一、递归与分治概述: 1、分治方法在于分和治。将一定规模的问题划分成性质相同的若干个小问题,分;对于每个小问题,进行所需要进行的操作,如排序等。 2、关于递归: (1)递归中需要的成分是递归边界和递归规则,没有递归边界递归无法停止、无法进行。 (2)通过将各层的关系从小到大逐渐带入,可以求解出一个函数的非递归表达式。 (3) n 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。 3、Ackerman函数: Ackerman函数的定义为: 根据关系可以递推出来: 在m取不同的值的过程中,该函数的递推关系式也不同。只是一种无法用单一的非递归关系表达的函数。 4、在Ackerman函数中,定义它的逆拟函数α(n)为使A(x)>n成立的最小的x。 5、整数划分问题: 对于整数的不同划分,考虑以下几种不同的情况:(1)m>n:q(n,m)=q(n,n) (2)m=n:q(n,m)=1+q(n,m-1) (3)m<n:q(n,m)=w(n,m)+q(n,m-1) 又:w(n,m)=q(n-m,m) (4)m=1:q(n,1)=1 6、汉诺塔问题: 思路:将前n-1个元素移动到c上,然后将第n个移动到b上,再将c上的n-1个移动到b上。 注意边界条件是:如果只有一个元素,直接move到b上。 void Move(int no,char a,char b){ printf(

算法与数据结构基础 - 递归(Recursion)

久未见 提交于 2019-11-29 21:34:01
递归基础 递归(Recursion)是常见常用的算法,是DFS、分治法、回溯、二叉树遍历等方法的基础,典型的应用递归的问题有求阶乘、汉诺塔、斐波那契数列等, 可视化过程 。 应用递归算法一般分三步,一是定义基础条件(base case),二是改变状态、向基础条件转移,三是递归地调用自身。例如 LeetCode题目 1137. N-th Tribonacci Number: // 1137. N-th Tribonacci Numberprivate: vector<int> nums={0,1,1}; //基础条件 int maxN=2; public: int tribonacci(int n) { if(n<=maxN) return nums[n%3]; //改变状态、递归地调用自身 nums[n%3]=tribonacci(n-3)+tribonacci(n-2)+tribonacci(n-1); maxN=n; return nums[n%3]; } 相关LeetCode题: 1137. N-th Tribonacci Number 题解 938. Range Sum of BST 题解 779. K-th Symbol in Grammar 题解 894. All Possible Full Binary Trees 题解 776. Split BST 题解 247.

递归,回溯算法两大经典案例—迷宫问题和八皇后问题

江枫思渺然 提交于 2019-11-29 20:02:22
迷宫问题: 问题描述: 用二维数组表示一个迷宫,比如1表示墙,0表示空格,设置一个起点和终点,让小球自己从迷宫的起点到终点走出一条路径,并将路径标识为2。 代码实现: 1 package cn.ftf.digui; 2 3 public class MiGong { 4 public static boolean findPath(int[][]arr,int i,int j) { 5 //结束条件 6 if(arr[6][5]==2) { 7 return true; 8 } 9 if(arr[i][j]==0) { 10 arr[i][j]=2; 11 if(findPath(arr,i+1,j)) { 12 return true; 13 }else if(findPath(arr,i,j+1)){ 14 return true; 15 }else if(findPath(arr,i-1,j)){ 16 return true; 17 }else if(findPath(arr,i,j-1)){ 18 return true; 19 }else { 20 arr[i][j]=3; 21 return false; 22 } 23 }else { 24 return false; 25 } 26 } 27 public static void main(String[]

Python函数编程——递归

余生长醉 提交于 2019-11-29 19:27:08
Python函数编程——递归 求100不断除以2直到商为0为止,打印每次除的商 用循环实现: n = 100 while n > 0: n = int(n/2) print(n) 输出: 50 25 12 6 3 1 0 如果用函数,如何实现呢? def calc(n): n = int(n/2) print(n) if n > 0: calc(n) # 调用自己 calc(100) 在函数内部,可以调用其他函数。如果一个函数在内部调用自已本身,这个函数就叫做递归函数。上面我们写的这个代码就是递归。 递归的执行过程 def calc(n): n = int(n/2) print(n) if n > 0: calc(n) print(n) calc(10) 输出: 5 2 1 0 0 1 2 5 为什么输出结果会是这样? 如上图所示,函数在每进入下一层的时候,当前层的函数并未结束,它必须等它调用的下一层函数执行结束返回后才能继续往下走。 所以最下面的那句print(n)会等最里层的函数执行时才会执行,然后不断往外退层,所以会出现0、1、2、5的效果。 递归特性: 1、必须有一个明确的结束条件。 2、每次进入更深一层递归时,问题规模相比上次递归都应有所减少。 3、递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用

python实现基础的数据结构(二)

非 Y 不嫁゛ 提交于 2019-11-29 18:33:55
本文涉及到的代码均已放置在我的github中 --> 链接 python实现基础的数据结构(一) python实现基础的数据结构(二) python实现基础的数据结构(三) python语法较为简洁,正好最近在复习数据结构,索性就用python去实现吧😀 本文实现的有线性表、栈、队列、串、二叉树、图、排序算法。参照教材为 数据结构(C语言版)清华大学出版社 ,还有网上的一些大神的见解。由于包含代码在内,所以内容很多,分了几篇,话不多说,我们直接步入正题🙈 注:本文实验环境:Anaconda 集成 python 3.6.5 ( 故代码为 python3 ) 由于本文代码过多,故每一步不做太详细的介绍,我尽量在代码中解释细节,望体谅 串 串是由零个或者多个字符组成的优先序列,一般记为是s = ‘a1a2…an’ ,python对字符串的操作已经比较成熟和简单,所以我们这里着重介绍串的模式匹配算法,这就不得不提KMP匹配算法,这种算法和正则表达式有类似之处,一个用了DFA的思想,一个用了NFA的思想。 KMP算法的思想是,当匹配失败时,可以利用已经知晓的一部分文本内容,避免从头开始重新匹配。这个匹配的过程可以使用有限状态自动机(DFA)。可以看看 这位大神 的描述。 每当一趟匹配过程中出现字符比较不等时,不需要回溯I指针,而是利用已经的带的“部分匹配

浅谈并发与并行(一)

一笑奈何 提交于 2019-11-29 18:33:52
原文地址: http://www.cnblogs.com/yangecnu/p/3164167.html#undefined 一、引言 前天在 GitHub 上看到一幅图,问如何向五岁的小孩讲解并发和并行。然后有人以这幅图做答: 这幅图有点儿意思,用咖啡机的比喻来形容并发和并行,从中最直接的体会是,并发是有状态的,某一线程同时执行一个任务,完了才能进行到下一个,而并行是无状态的。 近些年,计算机的处理能力成指数能力增长。处理能力也越来越快,以前的一些工作站现在都可以移植到笔记本电脑或者手持设备上。但是近几年,由于处理器的处理速度已经达到了极限,所以处理器开始向多核方向发展,而提高程序性能的一个最简单的方式之一就是充分利用多核处理器的计算资源。但要编写利用多核处理器处理的程序并不那么简单。所以一些函数是编程语言,如F#,Scala,Erlang等又开始流行起来,因为他们带来的不可变性,递归思想等在一定程度上简化了并行和并发编程。 本文和下文从任务并行和数据并行两个方面,简要讨论一下.NET中的并行编程。这篇文章不可能讲完所有的API,框架,工具或者设计模式。对着方面感兴趣的同学可以看看专门的书籍如Concurrent Programming on Windows 、Concurrency and Parallelism in .NET, 这些书专门讲解了.NET中的并发和并行编程

算法面试3---链表

此生再无相见时 提交于 2019-11-29 18:23:23
1 链表反转 例1:LeetCode 206。本题虽然简单但却是众多公司的面试问题。反转前后的图示如下: 在反转的过程中主要是依据指针之间的移动,如下图所示: class Solution { public ListNode reverseList(ListNode head) { ListNode prev = null; while (head != null) { //1 每次修改前先把head.next备份否则head修改后找不到head.next ListNode nextTemp = head.next; //2 修改head.next temp用来保存的是上次头节点的信息 head.next = prev; //3 temp进行更新保存此次头节点的信息 prev = head; //4 继续进行遍历 head = nextTemp; } //返回新链表的头结点 return prev; } } //递归版本的实现 class Solution { public ListNode reverseList(ListNode head) { //递归的终止条件 if (head == null || head.next == null) return head; //递归处理的操作是从最后一个元素开始的 ListNode p = reverseList(head.next)

递归树

不羁的心 提交于 2019-11-29 17:26:58
求递归算法的时间复杂度:递归树 递归算法时间复杂度的一个递归方程: 在引入递归树之前可以考虑一个例子: T(n) = 2T(n/2) + n 2 ; 迭代2次可以得: T(n) = n 2 + 2(2T(n/4) + (n/2) 2 ) 还可以继续迭代,将其完全展开可得: T(n) = n 2 + 2((n/2) 2 + 2((n/2 2 ) 2 + 2((n/2 3 ) 2 + 2((n/2 4 ) 2 +…+2((n/2 i ) 2 + 2T(n/2 i+1 )))…))))  ……(1) 来源: https://www.cnblogs.com/SpicyArticle/p/11524442.html