##数据结构##二叉树的三种遍历,以及求叶子节点,第k层,求树的高度等代码实现

本文介绍了二叉树的基本概念,包括结点的度、树的高度等属性,并详细阐述了前序、中序和后序三种遍历方法。同时,提供了相关属性的代码实现,帮助理解二叉树的操作。
摘要由CSDN通过智能技术生成
树:n个有限数据元素的集合

结点:包含了数据和指向其他结点的指针

结点的度:结点拥有的子节点的个数

高度:树当中距根节点最远系欸但的路径长度

前序遍历:根  左子树  右子树

中序遍历:左子树 根  右子树

后序遍历:左子树  右子树  根


#include<iostream>
#include<queue>
#include<stack>
using namespace std;
template<class T>
struct __BinaryNode
{
	T _data;
	 __BinaryNode<T>* _leftChild;
	 __BinaryNode<T>* _rightChild;

	__BinaryNode(const T& x) :_leftChild(NULL), _rightChild(NULL), _data(x)
	{}
};

//用一个数组存放数据,然后再构造出一棵二叉树,二叉树没有子树的左右子树用#代替,也就是这里的参数invalid,
//
template<class T>
class BinaryTree
{
	typedef __BinaryNode<T> Node;
public:
	BinaryTree();
	BinaryTree(T* a,size_t n,const T& invalid)
	{
		size_t index = 0;
		_root = _CreatBinaryTree(a,n, invalid,index);
	}
	//拷贝构造t2(t)
	BinaryTree(const BinaryTree<T>& t);
	BinaryTree& operator=(const BinaryTree<T>& t);

	//析构函数,需要参数,所以写一个函数,里面来调用
	~BinaryTree()
	{
		_Destroy(_root);
		_root = NULL;
	}

	//前序遍历,因为需要传参所以只能再写一个函数
	void PrevOrder()
	{
		_PrevOrder(_root);
		cout << endl;
	}

	//中序遍历
	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}
	//后序遍历
	void PostOrder()
	{
		_PostOrder(_root);
		cout << endl;
	}
	//层序遍历,这并不是子问题所以不能使用递归实现,利用队列可以实现
	void LevelOrder()
	{
		queue<Node*> q;
		if (_root)
			q.push(_root);
		while (!q.empty())
		{
			Node* front = q.front();
			cout << front->_data << " ";
			q.pop();
			if (front->_leftChild != NULL)
				q.push(front->_leftChild);
			if (front->_rightChild)
				q.push(front->_rightChild);
		}
		cout << endl;
	}
	//非递归前序遍历  根 + 左 + 右,利用栈来实现结点的遍历
	void PrevOrder_NonR()
	{
		Node* cur = _root;
		stack<Node*> s;
	
		while (cur||!s.empty())
		{
			while (cur)
			{
				cout << cur->_data << " ";
				s.push(cur);
				cur = cur->_leftChild;
			}
			Node* top = s.top();
			s.pop();
			cur = top->_rightChild;
		}
		cout << endl;
	}
	//非递归中序遍历
	void InOrder_NonR()
	{
		Node* cur = _root;
		stack<Node*> s;
		while (cur || !s.empty())
		{
			while (cur)
			{
				s.push(cur);
				cur = cur->_leftChild;
			}
			Node* top = s.top();
			cout << top->_data << " ";
			s.pop();
			cur = top->_rightChild;
		}
		cout << endl;
	}
	//非递归后序遍历此处有问题,如何知道右子树已经被访问??定义一个prev去记录并将它去和根的右树比较
	void PostOrder_NonR()
	{
		Node* cur = _root;
		Node* prev = NULL;
		stack<Node*> s;
		while (cur || !s.empty())
		{
			while (cur)
			{
				s.push(cur);
				cur = cur->_leftChild;
			}
			Node* top = s.top();
			if (top->_rightChild == NULL || prev == top->_rightChild)
			{
				cout << top->_data << " ";
				s.pop();
				prev = top;
			}
			else
			{
				cur = top->_rightChild;
			}
		}
		cout << endl;
	}
	//求结点个数,可利用前序遍历,但不同的是多一个参数size,每进行一步就加1
	size_t Size()
	{
		size_t size = 0;
		 _Size(_root,size);
		return size;
	}
	//先算左树的高度再算右树的高度,然后比较哪个树的高度最高就返回哪个
	size_t Depth()
	{
		return _Depth(_root);
	}
	size_t LeafSize()
	{
		size_t size = 0;
		_leafNodeSize(_root, size);
		return size;
	}
	//求第k层的结点
	size_t GetKLevel()
	{
		int k = 2;
		size_t size = _GetKLevel(_root,k);
		return size;
	}

private:
	//运用递归创建二叉树,当遇到非法值时就退出递归,这样一次创建出左右子树,由于有返回值,所以不能直接使用递归
	Node* _CreatBinaryTree(T* a, size_t n, const T& invalid, size_t& index)
	{
		Node* root = NULL;
		if (a[index] != invalid)
		{
			root = new Node(a[index]);
			root->_leftChild = _CreatBinaryTree(a, n, invalid, ++index);
			root->_rightChild = _CreatBinaryTree(a, n, invalid, ++index);
		}
		return root;
	}
	//二叉树的销毁,因为这是一个二叉树,所以不能直接delete  root,需要递归从最后一个节点开始释放
	void _Destroy(Node* root)
	{
		if (root == NULL)
			return;
		_Destroy(root->_leftChild);
		_Destroy(root->_rightChild);

		delete root;
	}
	//前序递归遍历
	void _PrevOrder(Node* root)
	{
		if (root == NULL)
			return;
		cout << root->_data << " ";
		_PrevOrder(root->_leftChild);
		_PrevOrder(root->_rightChild);
	}
	//中序递归遍历
	void _InOrder(Node* root)
	{
		if (root == NULL)
			return;
		_InOrder(root->_leftChild);
		cout << root->_data << " ";
		_InOrder(root->_rightChild);
	}
	//后序遍历
	void _PostOrder(Node* root)
	{
		if (root == NULL)return;
		_PostOrder(root->_leftChild);
		_PostOrder(root->_rightChild);
		cout << root->_data << " ";
	}
	//求结点的个数,子问题求解
	void  _Size(Node* root,size_t& n)
	{
		if (root == NULL)return;
		_Size(root->_leftChild, n);
		n++;
		_Size(root->_rightChild, n);
	}
	//求二叉树的高度,先算左树的高度再算右树的高度,然后比较哪个树的高度最高就返回哪个
	size_t _Depth(Node* root)
	{
		if (root == NULL) return 0;

		size_t left = _Depth(root->_leftChild);
		size_t right = _Depth(root->_rightChild);

		return left > right ? left + 1 : right + 1;
	}
	//求叶子节点的个数,叶子节点就是左右子树都为空
	void _leafNodeSize(Node* root, size_t& size)
	{
		if (root == NULL) return;
		if (root->_leftChild == NULL&&root->_rightChild == NULL)
		{
			size++;
		}
		_leafNodeSize(root->_leftChild, size);
		_leafNodeSize(root->_rightChild, size);
	}
	//求第k层
	size_t _GetKLevel(Node* root, size_t k)
	{
		if (root == NULL) return 0;
		if (k == 1)return 1;
		return _GetKLevel(root->_leftChild, k - 1) + _GetKLevel(root->_rightChild, k - 1);
	}
private:
	Node* _root;
};
void testBinaryTree()
{
	int array[] = { 1, 2, 3, '#', '#', 4, 7, '#', '#', '#', 5, 6, '#', '#', '#' };
	BinaryTree<int> bt(array,sizeof(array)/sizeof(int),'#');
	cout << "前序递归遍历 :";
	bt.PrevOrder();
	cout << "中序递归遍历 :";
	bt.InOrder();
	cout << "后序递归遍历 :";
	bt.PostOrder();

	cout << "层序遍历 :";
	bt.LevelOrder();
	cout << "前序非递归遍历 :";
	bt.PrevOrder_NonR();
	cout << "中序非递归遍历 :";
	bt.InOrder_NonR();
	cout << "后序非递归遍历 :";
	bt.PostOrder_NonR();

	cout << "Size: " << bt.Size() << endl;
	cout << "Depth: " << bt.Depth() << endl;
	cout << "leafsize:  " << bt.LeafSize() << endl;
	cout << "GetKLevel :" << bt.GetKLevel() << endl;
}
//测试
#define _CRT_SECURE_NO_WARNINGS 1
#include"BinaryTree.h"
#include<stdlib.h>
int main()
{
	testBinaryTree();
	system("pause");
	return 0;
}
//测试结果:


 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值