递归算法

树、图、排序查找重要算法(960算法)

老子叫甜甜 提交于 2019-11-29 17:09:09
设计求T的WPL的算法:   (1) .给出二叉树结点的数据类型定义;   (2) .给出C语言描述算法;   【 1 】: typedef struct node { int weight; struct node *left,*right; //指向结点左右子女的指针 }BiNode,*BiTree;   【 2 】: int WPL=0; void inorder(BiTree bt,level lv) //bt是二叉树,lv是结点的层次,初值为1 { if(bt) {inorder (bt->left,lv+1); //中序遍历左子树 if(bt->left==null &&bt->right==null) //判断该结点是否为叶子 WPL+=(lv-1)*bt->weight; //累加结点带权路径长度 inorder(bt->right,lv+1); } } 【先序遍历】 NLR (递归) void PreOrder(BiTree T){ if(T!=NULL){ visit(T); //访问根结点 PreOrder(T->lchild); //递归遍历左子树 preOrder(T->rchild); } } 【中序遍历】 LNR (递归) void InOrder(BiTree T){ if(T!=NULL){ InOrder(T->lchild); visit(T)

Java实现八大排序算法

巧了我就是萌 提交于 2019-11-29 15:20:30
本文对常见的排序算法进行了总结。 常见排序算法如下: 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 它们都属于内部排序,也就是只考虑数据量较小仅需要使用内存的排序算法,他们之间关系如下: \[ \begin{cases}内部排序 \begin{cases}插入排序\begin{cases}直接插入排序\\希尔排序\end{cases}\\选择排序\begin{cases}简单选择排序\\堆排序\end{cases}\\交换排序\begin{cases}冒泡排序\\快速排序 \end{cases}\\归并排序\\ 基数排序\end{cases}\\外部排序 \end{cases} \] \[ \left\{\begin{matrix} 内部排序\\ 外部排序 \end{matrix}\right. \] 稳定与非稳定 : 如果一个排序算法能够保留数组中重复元素的相对位置则可以被称为是 稳定 的。反之,则是 非稳定 的。 直接插入排序 基本思想 通常人们整理桥牌的方法是一张一张的来,将每一张牌插入到其他已经有序的牌中的适当位置。在计算机的实现中,为了要给插入的元素腾出空间,我们需要将其余所有元素在插入之前都向右移动一位。 算法描述 一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下: 从第一个元素开始,该元素可以认为已经被排序

二叉树算法题

断了今生、忘了曾经 提交于 2019-11-29 15:20:30
二叉树层次遍历 //思路 特殊情况 ,根节点为null,深度为0,return 0 借助队列,队列储存每一层的所有节点, 先保存数组长度,用于控制依次遍历循环——遍历每一个节点保存值,该节点的所有子结点从队尾入队,访问过的节点从头出队 注意——需要先把width存下来,用于for循环的结束标志,因为for循环里面直接操作了queue,不能去都不敢动态获取 队列初始值为root,对每一层都要进行上述遍历——while循环控制,队列空代表叶节点这一层遍历完成,此时遍历结束,退出循环 每次循环开始前初始化一个curNodes储存该层所有节点,每次循环结束,将curNodes压入result var levelOrder = function(root) { if (root === null) return []; //空树 var result = [], queue = [root]; while (queue.length) { let width = queue.length; //需要先把width存下来,用于for循环,for循环里面直接操作了数组 let curNodes = []; for (let i = 0; i < width; i++) { let node = queue.shift(); curNodes.push(node.val); node.left ?

数据结构与算法之排序详解 一点课堂(多岸学院)

时光毁灭记忆、已成空白 提交于 2019-11-29 15:20:18
通过前面的知识,我们已经知道,有序的数据在查找时有极大的性能提升。很多查找都基于有序数据,但并不是所有的结构都能像二叉排序树一样,在插入数据时就已经排好序,很多时候往往是无序的数据,需要我们使用时再进行排序,这就意味着我们需要寻找高效率的排序算法。接下来,我们对当下使用较为普遍的几个算法逐一进行分析。这里推荐一个可以查看算法运行动态过程的网站,加深对算法原理的理解。 基础知识 排序定义 假设含有n个记录的序列为{r1. r2, ..., rn},其相应的关键字分别为{k1, k2, ..., kn},需确定1, 2, ..., n的一种排列p1, p2, ..., pn,使其相应的关键字满足kp1≤kp2≤...≤kpn(非递减或非递增) 关系,即使得序列成为一个按关键字有序的序列{rp1, rp2, ..., rpn} , 这样的操作就称为排序。 稳定性 假设ki=kj( 1≤i≤n, 1≤j≤ n, i≠j ) ,且在排序前的序列中 ri 领先于 rj (即i<j) 。如果排序后 ri 仍领先于 rj,则称所用的排序方法是稳定的;反之,若可能使得排序后的序列中 rj 领先 ri,则称所用的排序方法是不稳定的。 简单来说,就是对于原数据中相等的数据,排序前后如果相对位置没有改变,就是稳定的。 内排序与外排序 内排序是在排序整个过程中,待排序的所有记录全部被放置在内存中

【算法】递归思想

核能气质少年 提交于 2019-11-29 15:05:05
给定一个字符串(该字符串没有相同的字母),使用递归的方式打印出这个字符串所包含字母的所有组合方式 package test1; public class num { public static void main(String[] args) { char[] c= {'a','b','c','d'}; f(c,0); } /* c为待递归数组,先确定第一个字符,再确定第二个...b为所有已确定字符位的后一个字符位 */ static void f(char c[],int b) { if(b==c.length-1) { /* 如果b已经是最后一个字符,所有字符已经确定 */ System.out.println(c);//打印字符串,结束循环。 }else { /* 如果b不是最后一个字符 */ for(int i=b;i<c.length;i++) { swap(c,b,i);//b和自己以及和之后的字符交换,使未确定每一个字符都有在b位确定的机会,【已经确定字符】【b】【剩下的字符】——》【已经确定字符】【i】【剩下的字符】 f(c,b+1);//确定下一位 swap(c,i,b);//因为i++后的i位还要和原来的b位交换,保证每一个字符都有在b位确定的机会,【已经确定字符】【i】【剩下的字符】——》【已经确定字符】【b】【剩下的字符】 } } } /*

关于递归和动态规划的简单理解

。_饼干妹妹 提交于 2019-11-29 13:51:59
1.递归的定义 简单的来说,递归就是一个概念能够用自身来解释,比如说一本字典,每个字词的解释是依靠字典中其他的字词来解释的。一般来说,计算机中遇到的递归问题大多是把一个问题分解成规模更小的子问题求解,再进行合并。 递归的性质 一个具有递归性质的问题,大多具有两个特征,第一个是状态转移方程也就是递归方程,比如在求解阶乘时,n!=n*(n-1)!,就将求解n的阶乘转换为求解n-1的阶乘。第二个特征就是终止条件,一个递归是一类问题的求解,必定有一个结果 无法一只递归下去,有一个结束条件,也就是当问题规模简化的足够小的时候可以直接的出答案。在求解阶乘时,当问题过为1的时候就直接输出1. int f(n) { if(n==1)//终止条件 { return 1; } else { return n*f(n-1);//递归方程 } } 递归的代价 递归执行时,递归函数会被反复地调用,一层一层的进入,到达终止条件后,再一层一层出来,为了保证结果的正确性,每一层函数的运算结果和状态都必须保存在系统所分配的栈里面,当数据量很大的时候,递归所占用的空间和运行时间会非常恐怖,效率也很低 这里再介绍一种和递归类似的但执行效率更高的动态规划算法。 动态规划的性质 递归算法是从顶置低求解问题,而·动态规划算法是从低置顶求解问题,同样也需要状态转移方程方程,和初始条件,相较于递归算法的优势

纯JS实现在一个字符串b中查找另一个字符串a出现的所有位置,并且不使用字符串的方法(递归)

谁说我不能喝 提交于 2019-11-29 10:33:40
问题:判断字符串A在中所有出现字符串B中(长度大于1)的索引。不得使用字符串方法indexof,substring等    有小伙伴在面试遇到了这个问题,乍一看如果使用使用字符串方法indexof,substring,很简单容易实现,但如果不使用这些方法,怎么样才能实现这个需求呢     // 思路: 如果不能使用字符串的相应方法,我们可以把字符串转换成数组,使用递归函数不断去比对相应的数组索引,然后把满足条件的索引打印出来,其实很多现在前后端交互处理数据的方法,用的都是递归偏多,千万别小瞧递归! 话不多说,我们先上解决问题的方法: <script> // 其实很多现在前后端交互处理数据的方法,用的都是递归变多,千万别小瞧递归 // 思路: 不能使用字符串的相应方法,我们可以把字符串转换成数组,首先使用递归不断去比对相应的数组索引 // 随机的字符 var str1 = 'adfacddtgjacbasaclsaacdctacw'; // 条件筛选的字符 var str2 = 'basaclsa'; // 把相应的字符串转换为数组 var arr1 = str1.split(''); var arr2 = str2.split(''); function test (arr) { // 写一个for循环,先把需要筛选的数组arr2第一个索引拿来比对 for(var i = 0; i

算法与数据结构

一世执手 提交于 2019-11-29 10:24:16
1、线性表实现 2、栈的实现 3、队列的实现 4、二叉树的前中后序层序遍历的实现(结构体数组存储 递归实现) 5、二叉树的前中后序层序遍历的实现(链式存储 递归实现) 6、二叉树的前中后序遍历的实现(链式存储 非递归实现) 7、二叉树插入删除查找递归及非递归的实现 8、二叉树前中序变后序(高级方法) 9、二叉树的表达(打印各个节点的详细信息) 10、平衡二叉树的建立与调节(AVL树) 11、堆的初始化,创建,插入,删除以及乱序输入的调整 12、哈夫曼树的创建 13、图的邻接矩阵表示法 14、图的邻接表表示法 15、插入排序、选择排序、冒泡排序、希尔排序 来源: https://blog.csdn.net/qq_43590403/article/details/100783553

965.单值二叉树(简单)递归

徘徊边缘 提交于 2019-11-29 07:01:06
如果二叉树每个节点都具有相同的值,那么该二叉树就是 单值 二叉树。 只有给定的树是单值二叉树时,才返回 true ;否则返回 false 。 节点类: # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None 示例 1: 输入:[1,1,1,1,1,null,1] 输出:true 示例 2: 输入:[2,2,2,5,2] 输出:false 提示: 给定树的节点数范围是 [1, 100]。 每个节点的值都是整数,范围为 [0, 99] 。 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/univalued-binary-tree 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 分析:   对于二叉树的题目大部分都是使用递归算法。   1.使用递归,将所有的树的节点值添加到一个集合中,集合有自动去重功能,所以,如果最后set的长度大于1,说明有重复的值。返回false,否则返回True。   2.使用递归,判断节点值是否和左孩子和右孩子节点值相同,如果相同,则递归调用函数,将值变为左孩子和右孩子的与

递归算法

五迷三道 提交于 2019-11-29 06:03:36
一、递归的核心思想就是自己调用自己,一般来说能够用递归解决的问题应满足3个条件: 1.需要解决的问题可以转化为一个或多个子问题来求解,而这些子问题的求解方法与原问题完全相同,只是在数量和规模上不同。 2.递归调用的次数必须是有限的。 3.必须有结束递归的条件来终止递归。 二、何时使用递归? 1.定义是递归的 有许多数学公式、数列和概念的定义是递归的。比如求n!,Fibonacci数列等。这些问题的求解过程是可以将其递归定义直接转化为对应的递归算法的。 比如求 n! int fun(int n) { if(n==1) { //递归头 return(1); } else { //递归体 return (fun(n-1)*n); } } 2.有些数据结构是递归的 单链表就是一种递归数据结构,其结点类型定义如下: typedef struct LNode { ElemType data; struct LNode *next; }LinkList; 求一个不带头结点的单链表L所有的data域(假设为int类型)之和的递归算法如下: int Sum(LinkList *L) { if (L == NULL) { return 0; } else { return(L->data+sum(L->next)); } } 3.问题的求解方法是递归的 比如汉诺塔问题: 三、递归的不足