二叉树遍历及其相关问题

二叉树定义
* 在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

* 二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^{i-1}个结点;深度为k的二叉树至多有2^k-1个结点;对任何一棵二叉树T,如果其终端结点数为n_0,度为2的结点数为n_2,则n_0=n_2+1。

* 一棵深度为k,且有2^k-1个节点称之为满二叉树;深度为k,有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中,序号为1至n的节点对应时,称之为完全二叉树(百度百科)

下面我用一个一维数组来构建一颗二叉树:首先呢,我们需要给一个数组作为二叉树中的数值,其次我们还需要一个非法值,还有一个需要注意的是这里在进行下标传递的过程需要传递它的引用,否则在递归中下标着数组中的数时,就会出现问题。

二叉树前中后递归遍历:

	//前序   
	void preOrder()
	{
		
		 _preOrder(_root);
	}

	void  _preOrder(Node *root)
	{
		
		if (root)
		{
			cout << root->_data << "  ";
			_preOrder(root->_left);
			_preOrder(root->_right);
		}
		
	}
	//中序
	void inOrder()
	{
		_inOrder(_root);
	}

	void _inOrder(Node *root)
	{
		if (root)
		{
			_inOrder(root->_left);
			cout << root->_data << " ";
			_inOrder(root->_right);
		}
	}
	//后序
	void postOrder()
	{
		_postOrder(_root);
	}

	void _postOrder(Node *root)
	{
		if (root)
		{
			_postOrder(root->_left);
			_postOrder(root->_right);
			cout << root->_data << " ";
		}
	}

非递归

void preOrderNotR()
	{
		_preOrderNotR(_root);
	}
	void _preOrderNotR(Node *root)
	{
		assert(root);
		stack<Node *> s;
		Node *cur = root;            
	
		while (cur ||!s.empty())                           //cur代表一棵树的开始
		{
			while (cur)
			{
				s.push(cur);
				cout << cur->_data << endl;
				cur = cur->_left;
			}
			Node *top = s.top();
			s.pop();
			cur = top->_right;

		}
	}

	void inOrderNotR()
	{
		_inOrderNotR(_root);
	}

	void _inOrderNotR(Node *root)
	{
		assert(root);
		stack<Node *> s;
		Node *cur = root;
		while (cur || !s.empty())
		{
			while (cur)
			{
				s.push(cur);
				cur = cur->_left;
			}
			Node *top = s.top();
			s.pop();
			cout << top->_data << endl;
			cur = top->_right;
		}

	}

	void postOrderNotR()
	{
		_postOrderNotR(_root);
	}

	void _postOrderNotR(Node *root)
	{
		assert(root);
		stack<Node*> s;
		Node *cur = root;
		Node *prev = NULL;
		while (cur || !s.empty())
		{
		
			while (cur)
			{
				s.push(cur);
				cur = cur->_left;
			}
			Node *top = s.top();
			if (top->_right == NULL || top->_right == prev)
			{
				cout << top->_data << endl;
				s.pop();
				prev = top;
			}
			else
			{
				cur = top->_right;
			}
		}
	}

递归求节点数:

	//求节点数
	size_t Size()
	{
		return _Size(_root);
	}

	size_t _Size(Node *root)
	{
		if (root == NULL)
		{
			return 0;
		}
		else
		{
			return _Size(root->_left) + _Size(root->_right) + 1;
		}
	}

递归求解叶子节点


代码如下:

	//求叶子结点
	size_t Leafsize()
	{
		return _Leafsize(_root);
	}

	size_t _Leafsize(Node *root)
	{
		if (root == NULL)
		{
			return 0;
		}
		if (root != NULL &&root->_left == NULL &&root->_right == NULL)
		{
			return 1;
		}
		return _Leafsize(root->_left) + _Leafsize(root->_right);
	}

求二叉树高度

	//求高度
	size_t Height()
	{
		return _Height(_root);
	}

	size_t _Height(Node *root)
	{
		if (root == NULL)
		{
			return 0;
		}
		size_t left = _Height(root->_left);
		size_t right = _Height(root->_right);
		return left > right ? left+1 : right+1;
	}

求k层节点数:

	//求k层的节点数
	size_t sizek(size_t k)
	{
		return _sizek(_root,k);
	}

	size_t _sizek(Node *root,size_t k)
	{
		if (root == NULL  || k<0)
		{
			return 0;
		}
		if (k == 1)
		{
			return 1;
		}
		else
		{
			return _sizek(root->_left,k - 1)+_sizek(root->_right,k-1);
		}
	}

按层遍历二叉树

	//求k层的节点数
	size_t sizek(size_t k)
	{
		return _sizek(_root,k);
	}

	size_t _sizek(Node *root,size_t k)
	{
		if (root == NULL  || k<0)
		{
			return 0;
		}
		if (k == 1)
		{
			return 1;
		}
		else
		{
			return _sizek(root->_left,k - 1)+_sizek(root->_right,k-1);
		}
	}





猜你喜欢

转载自blog.csdn.net/skinwhite/article/details/78176357