先说那两个让哥震惊的递归问题:
1、用递归实现单链表的倒序输出
2、从二叉查找树中删除节点,并保证还是二叉查找树
同学们可以开始思考这两个问题了,当然你可能N年前就遇到过这两个问题,那么不妨看看,看你是否真的理解了递归。实现这两个问题的代码当然很简单,就在下面。
百度百科中递归的名片:递归做为一种算法在程序设计语言中广泛应用.是指函数/过程/子程序在运行过程中直接或间接调用自身而产生的重入现象.递归是计算机科学的一个重要概念,递归的方法是程序设计中有效的方法,采用递归编写程序能使程序变得简洁和清晰。
刚开始学习的递归的时候,觉得他好强大,实现某些功能不用递归可能要几十行代码,用递归可能几行就搞定了,而且代码清晰简洁。一直以为递归也就是自己调用自己,有一个出口条件,让他停止递归,退出函数,其实的特点并非就这些。
递归还有一个非常重要的特点:先进后出,跟栈类似,先递进去的后递出来。由于递归一直在自己调用自己,有时候我们很难清楚的看出,他的返回值到底是哪个,只要你理解了先进后出这个特点,你就会明白,第一次调用时,作为返回值的那个变量的值就是递归函数的返回值。先进后出吗,他是第一个进来,也就是最后出去的那个,当然就是递归的返回值啦。
第一个让哥震惊的问题:用递归实现单链表的倒序输出。
我前段时间写过一篇博客《四种方式实现--从尾到头输出链表》,其中一种方法就是用递归实现的,当时看见那位高人用递归实现了这个功能,哥被震住了,他怎么可以这么聪明,他的博客真的是学算法的好地方:http://zhedahht.blog.163.com/blog/#m=0。代码如下,这是我那篇博客的源码:
//用递归实现 //很诚实的说盗用了别人的思想,真的太妙了,完全能看出你是否真的体会了递归的原理 //正如那位哥们所说,递归就是一个进栈出栈的过程,链表前面的元素先进栈,在栈底,后面的元素后进栈,在栈顶,先出栈,哈哈。。。 voidrecursion(node* head) { if(NULL==head) { return; } if(head->next!=NULL) { recursion(head->next); } //如果把这句放在第二个if前面,那就是从头到尾输出链表,曾经的你或许是用while或者用for循环输出链表,现在你又多了一种方式 cout<<head->data<<"\t"; } |
这里充分运用了递归的先进后出的特点。
最近在博客园中看的一些博客,发现有几篇文章跟树联系得比较紧,前天晚上,我于是把数据结构与算法中树的那一章温习了一下,哥被二叉查找树删除节点的算法给震住了,因为我以前也写过一篇关于二插查找树的博客《算法学习--二叉查找树》,在这篇博客中,删除节点的那个算法写得很长,以至于叫我自己现在去看都不是很理解,今天会让大家看到看到简洁清晰的代码,递归写的吗,哈哈哈!
先来C++版的吧,好久没写了,都生疏了:
#include"string.h" #include <iostream> usingnamespacestd; typedefstructTreeNode1 { public: intelement; TreeNode1 *left; TreeNode1 *right; TreeNode1(intelement):element(element),left(NULL),right(NULL){} } TreeNode; classAdtTree { public: TreeNode *root;//根节点 AdtTree() { root=NULL; } //查找指定节点下的最小节点 TreeNode* FindMin(TreeNode *t) { if(t==NULL) { returnNULL; }elseif(t->left==NULL) { returnt; }else { returnFindMin(t->left); } } //查找最小节点 TreeNode* FindMin() { returnFindMin(root); } //查找指定节点下的节点 TreeNode* Find(intelement,TreeNode *t) { if(t==NULL) { returnNULL; } if(element<t->element) { returnFind(element,t->left); }elseif(element>t->element) { returnFind(element,t->right); }else { returnt; } } //查找节点 TreeNode* Find(intelement) { returnFind(element,root); } //在指定节点下天骄节点 TreeNode* Add(intelement,TreeNode *t) { if(t==NULL) { returnNULL; } if(element<t->element) { if(t->left==NULL) { returnt->left=newTreeNode(element); } returnAdd(element,t->left); }elseif(element>t->element) { if(t->right==NULL) { returnt->right=newTreeNode(element); } returnAdd(element,t->right); } returnt; } //天骄节点 TreeNode* Add(intelement) { if(root==NULL) { returnroot=newTreeNode(element); }else{ returnAdd(element,root); } } //删除指定节点下节点 TreeNode* Delete(intelement,TreeNode *t) { if(t==NULL) { returnNULL; }elseif(element<t->element) { t->left= Delete(element,t->left); }elseif(element>t->element) { t->right= Delete(element,t->right); }else { if(t->left!=NULL && t->right!=NULL) { TreeNode* tmpNode=FindMin(t->right); t->element=tmpNode->element; t->right=Delete(t->element,t->right); }else { TreeNode* tmpNode=t; if(t->left==NULL) { t=t->right; }elseif(t->right==NULL) { t=t->left; } delete tmpNode; } } returnt; } //删除节点 TreeNode* Delete(intelement) { returnDelete(element,root); } }; |