2013-03-17---二叉树递归,非递归实现(附代码)深度,叶子节点数量,逐行打印二叉树

昨天晚上没有发文章,说来话长啊,昨天不知道是csdn的问题,还是我的问题,我访问了半天,访问不上网站啊,后来12点多了,就睡了。上一篇文章说到了二叉树的先序,中序,后序遍历问题,这次还是说的简单的一点,说计算二叉树的深度,和叶子节点数量

int ceng(Node *pRoot)	//计算层数,递归实现
{
	int left = 0;
	int right = 0;
	int res = 0;
	if (pRoot == NULL)
	{
		return 0;
	}
	if (pRoot->pLeft != NULL)
	{
		left = ceng(pRoot->pLeft);
	}
	if (pRoot->pRight != NULL)
	{
		right = ceng(pRoot->pRight);
	}
	res = left > right ? left : right;
	return res + 1;
}
class CengNode
{
public:
	int n = 0;
	Node *p = NULL;
	CengNode(int now, Node *p) :n(now), p(p)
	{

	}
};

int cengstack(Node *pRoot)	//计算深度,非递归实现
{
	stack<CengNode> mystack;
	Node *pnow = pRoot;
	mystack.push(CengNode(1, pRoot));
	int res = 0;
	while (false == mystack.empty())
	{
		CengNode now = mystack.top();
		mystack.pop();
		if (now.n > res)
		{
			res = now.n;
		}
		if (now.p->pRight != NULL)
		{
			mystack.push(CengNode(now.n + 1, now.p->pRight));
		}
		if (now.p->pLeft != NULL)
		{
			mystack.push(CengNode(now.n + 1, now.p->pLeft));
		}
	}
	return res;
}
int getyenum(Node *pRoot)	//计算叶子节点数,递归实现
{
	int left = 0;
	int right = 0;

	if (pRoot == nullptr)
	{
		return 0;
	}
	if (pRoot->pLeft == NULL && pRoot->pRight == NULL)
	{
		return 1;
	}
	if (pRoot->pLeft != nullptr)
	{
		left = getyenum(pRoot->pLeft);
	}
	if (pRoot->pRight != nullptr)
	{
		right = getyenum(pRoot->pRight);
	}
	return left + right;
}
int getyenumstack(Node *pRoot)//计算叶子节点数,非递归实现
{
	stack<Node *> mystack;
	Node *pnow = NULL;
	mystack.push(pRoot);
	int res = 0;
	while (false == mystack.empty())
	{
		pnow = mystack.top();
		mystack.pop();
		if (pnow != NULL)
		{
			if (pnow->pLeft == NULL && pnow->pRight == NULL)
			{
				res += 1;
			}
			else
			{
				if (pnow->pRight != NULL)
				{
					mystack.push(pnow->pRight);
				}
				if (pnow->pLeft != NULL)
				{
					mystack.push(pnow->pLeft);
				}
			}
		}
	}
	return res;
}
void hengprintqueue(Node *pRoot)	//逐行打印,非递归,队列实现
{
	queue<Node *> myqueue;
	myqueue.push(pRoot);
	Node *pnow = NULL;
	while (false == myqueue.empty())
	{
		pnow = myqueue.front();
		myqueue.pop();
		if (pnow != NULL)
		{
			cout << pnow->data << " ";
			if (pnow->pLeft != NULL)
			{
				myqueue.push(pnow->pLeft);
			}
			if (pnow->pRight != NULL)
			{
				myqueue.push(pnow->pRight);
			}
		}
	}
}
void hengprintstack(Node *pRoot)	//逐行打印,非递归,栈实现
{
	stack<Node *> mystack;
	stack<Node *> mystacktemp;
	mystack.push(pRoot);
	Node *pnow = NULL;
	bool flag = true;
	while (false == mystacktemp.empty() || false == mystack.empty()) {
		if(false == mystack.empty())
		{
			pnow = mystack.top();
			mystack.pop();
			if (pnow != NULL)
			{
				cout << pnow->data << " ";
				mystacktemp.push(pnow->pLeft);
				mystacktemp.push(pnow->pRight);
			}

		}
		else
		{
			while (false == mystacktemp.empty())
			{
				mystack.push(mystacktemp.top());
				mystacktemp.pop();
			}
		}
	}

}

自己感觉这些代码,还算是二叉树里面比较简单的吧,具体的就不解释了,相信大家还是都能理解的,递归的好理解,栈就是我们手动模拟递归的过程啊。

说说这几天的感受,说好的15号结束c++啊,今天都17号了,其实这个东西不能急功近利啊,真的是只能慢慢来,从上个月18号开始的c++吧,不知不觉过了1个月了,其实现在感觉c++的语言还好吧,主要是基本功,数据结构,还有设计模式,因为以前用别的语言做过打的项目,所以其实设计模式还好,主要就是数据结构,树和图,还有n种排序算法,所以这几天真的发现越学东西越多啊,总之,这个坎是要迈过去的,我要在6月之前尽力搞啊,时间也算是够长的,具体的看自己了。

基础不牢地动山摇,如果想要好的offer,好的工作就要努力啊,加油吧。明天还要调整一下学习计划,复习一下,我们一起搞,搞cocos2dx,搞数据结构,搞设计模式,

我去刷牙了,一会儿就睡觉了。

时间: 2024-10-11 23:45:14

2013-03-17---二叉树递归,非递归实现(附代码)深度,叶子节点数量,逐行打印二叉树的相关文章

二叉树基础(创建方法,遍历方法(前序/中序/后序/层序、递归/非递归)

二叉树的创建及遍历是很多二叉树问题的基础,递归遍历逻辑清晰,代码简约漂亮,然则效率低下(所有递归方案的通病,非不得已不用递归): 非递归遍历高效,却不是能信手写出来的,特别是后续非递归遍历,相信很多资深码工也有这样的经历: 5年前学习了二叉树的非递归遍历,一个月前复习了并达到能熟练写出的程度,在不参考任何资料的情况下,今天却怎样也写不出来. 如果你也有过这种经历,恭喜你,这说明你是一个正常人…… 另一方面市面上有些国人写的教材,各种语法.逻辑错误层出不起,不知祸害了多少未来的码工,深感痛心. 印

二叉树的非递归遍历(先序、中序、后序和层序遍历)

[前文] 二叉树的非递归遍历有 先序遍历.中序遍历 .后续遍历 和 层序遍历. 非递归算法实现的基本思路:使用堆栈.而层序遍历的实现:使用队列. 如下图所示的二叉树: 前序遍历顺序为:ABCDE (先访问根节点,然后先序遍历其左子树,最后先序遍历其右子树) 中序遍历顺序为:CBDAE (先中序遍历其左子树,然后访问很节点,最后中序遍历其右子树) 后续遍历顺序为:CDBEA (先后序遍历其左子树,然后后续其右子树,最后访问根节点) 层序遍历顺序为:ABECD (由上至下.从左到右遍历二叉树) [准

[算法]二叉树的非递归遍历算法

1.二叉树的非递归中序遍历算法 二叉树的中序遍历方法是:左中右,因此一开始会顺着根节点的左孩子一直往下(这点和先序遍历一样,这也是二者前面部分代码很相似的原因),到最后一个左孩子时尝试把它的右孩子塞进栈内,然后顺着它的的左孩子而下,直到不能访问为止.利用的栈FILO的特性,对每个节点都进行顺左孩子而下即可. 上代码: 1 void inOrder(TreeNode* root,vector<int>& inOrder) 2 { 3 stack<TreeNode*>st; 4

二叉树的非递归遍历--京东2015笔试回忆

题目回忆: C/C++研发试卷:偏重于数据结构的考察,编程题有2题+1题附加题: 1.输入整数n,求m,m>9,m中各个数位的乘积=n的最小整数;如n=36,m=49; 2.二叉树前序遍历的非递归实现(本文的总结) 3.求第n个数,这个序列满足(2^i)*(3^j)*(5^k),前7个为:2,3,4,5,6,8,10 .... 小题有基本的数据结构.程序运行结果.SQL题目. 4.删除表格用DROP命令,死锁产生的条件: 4.1互斥使用(资源独占) 一个资源每次只能给一个进程使用 4.2.不可强

二叉树总结—建树和4种遍历方式(递归&amp;&amp;非递归)

今天总结一下二叉树,要考离散了,求不挂!二叉树最重要的就是 建立.4种遍历方式,简单应用,如何判断两颗二叉树是否相似 二叉树分为 :1.完全二叉树  2.满二叉树 结构性质: 1).满二叉树 高度为h ,节点数则为 2^h - 1,且叶子节点全在最下层,且叶子节点数为2^(n-1)个{n代表二叉树层数,也叫深度} 2).n个节点的 完全二叉树 深度为 int(log2n)(以2为底n的对数)+ 1: 3).非空二叉树 叶子节点个数==双分支节点数+1 4).非空二叉树 某节点编号 n  若有左孩

二叉树的非递归实现

之前一直觉得二叉树使用递归来实现就感觉有点绕,今天才发现二叉树使用非递归来实现更加的绕,但是考虑到我们得使用非递归来提高二叉树的遍历效率,使用非递归是一种比较好的方法. 三种递归遍历对遍历的描述,思路非常简洁,最重要的是三种方法完全统一,大大减轻了我们理解的负担.现在非递归使用栈来实现,利用了栈的先进后出的特点,可以解决. 二叉树的递归实现之前已经实现过了,我们直接实现非递归.并且都使用栈实现 (一)前序遍历 对于前序遍历,我们要解决的问题是何时压入左右子树?先压左子树还是右子树? 答案是显而易

二叉树,递归非递归遍历算法(全)

包含了所有的非递归和递归的算法: #include<iostream> #include<queue> #include<stack> using namespace std; //二叉树结点的描述 typedef struct BiTNode { char data; struct BiTNode *lchild, *rchild; //左右孩子 }BiTNode,*BiTree; //按先序遍历创建二叉树 //BiTree *CreateBiTree() //返回结

通过二叉树的中序和后序遍历序列构造二叉树(非递归)

题目:通过二叉树的中序和后序遍历序列构造二叉树 同样,使用分治法来实现是完全可以的,可是在LeetCode中运行这种方法的代码,总是会报错: Memory Limit Exceeded ,所以这里还是用栈来实现二叉树的构建. 与用先序和后序遍历构造二叉树的方法类似,但还是要做一些改变: 如果从后往前处理中序和后序的序列,则处理就为如下所示的情况: Reverse_Post: 根-右子树-左子树 Reverse_In: 右子树-根-左子树 这样处理方式和先序-中序就差不多了,只是将添加左孩子的情况

Java实现二叉树的创建、递归/非递归遍历

近期复习数据结构中的二叉树的相关问题,在这里整理一下 这里包含: 1.二叉树的先序创建 2.二叉树的递归先序遍历 3.二叉树的非递归先序遍历 4.二叉树的递归中序遍历 5.二叉树的非递归中序遍历 6.二叉树的递归后序遍历 7.二叉树的非递归后序遍历 8.二叉树的层次遍历 这里感谢博客http://blog.csdn.net/skylinesky/article/details/6611442的指导 /**二叉树的结点定义*/ class Node<T>{ private T value; pr