数据结构(C++) - 实现二叉树链式存储结构

#pragma once

#include <iostream>
using namespace std;

template <typename DataType>
struct BinTreeNode
{
	DataType data;
	BinTreeNode* lChild;
	BinTreeNode* rChild;
};


// 二叉树
template <class DataType>
class BinTree
{
public:
	BinTree();
	~BinTree();
	//创建二叉树
	BinTreeNode<DataType>* Create(BinTreeNode<DataType>* bt);
	// 访问节点
	void Vistied(BinTreeNode<DataType>* bt);
	// 前序递归遍历
	void PreOrder();
	// 中序递归遍历
	void InOrder();
	// 后序递归遍历
	void PostOrder();
	// 前序非递归遍历
	void NPreOrder();
	// 中序非递归遍历
	void NInOrder();
	// 后序非递归遍历
	void NPostOrder();
	// 层序遍历
	void LevelOrder();
	// 求二叉树的深度
	int Depth();

private:
	BinTreeNode<DataType>* root;
	// 前序遍历
	void PreOrder(BinTreeNode<DataType>* bt);
	// 中序遍历
	void InOrder(BinTreeNode<DataType>* bt);
	// 后序遍历
	void PostOrder(BinTreeNode<DataType>* bt);
	// 销毁二叉树
	void Destory(BinTreeNode<DataType>* bt);
	int Depth(BinTreeNode<DataType>* bt);
};
#include "BiTree.h"

template<class DataType>
BinTree<DataType>::BinTree()
{
	root = Create(root);
}

template<class DataType>
BinTree<DataType>::~BinTree()
{
	Destory(root);
}

/*
前序遍历序列构造二叉树递归
*/
template<class DataType>
BinTreeNode<DataType>* BinTree<DataType>::Create(BinTreeNode<DataType>* bt)
{
	DataType data;
	cin >> data;
	// "#"表示创建一个空结点
	if (data == '#')
	{
		bt = NULL;
	}
	else
	{
		bt = new BinTreeNode<DataType>();
		bt->data = data;
		// 左子树
		bt->lChild = Create(bt->lChild);
		// 右子树
		bt->rChild = Create(bt->rChild);
	}
	return bt;
}

/*
销毁结点
*/
template<class DataType>
void BinTree<DataType>::Destory(BinTreeNode<DataType>* bt)
{
	if (bt)
	{
		Destory(bt->lChild);
		Destory(bt->rChild);
		delete bt;
	}
}

/*
递归算法求树的深度
*/
template<class DataType>
int BinTree<DataType>::Depth(BinTreeNode<DataType>* bt)
{
	// 如果当前结点为空, 结束遍历
	if (!bt) // == if(bt == NULL)
	{
		return 0;
	}
	// 左子树深度
	int lDepth = Depth(bt->lChild);
	// 右子树深度
	int rDepth = Depth(bt->rChild);
	// 取左右子树深度较大的值;根结点占一成, 所以要+1
	return lDepth > rDepth ? lDepth + 1 : rDepth + 1;
}

/*
访问结点
*/
template<class DataType>
void BinTree<DataType>::Vistied(BinTreeNode<DataType>* bt)
{
	cout << bt->data << "\t";
}

template<class DataType>
void BinTree<DataType>::PreOrder()
{
	PreOrder(root);
}

template<class DataType>
void BinTree<DataType>::InOrder()
{
	InOrder(root);
}

template<class DataType>
void BinTree<DataType>::PostOrder()
{
	PostOrder(root);
}

// 前序非递归遍历
template<class DataType>
void BinTree<DataType>::NPreOrder()
{
	// 指针数组
	BinTreeNode<DataType>* stack[50];
	int top = -1;
	if (!root)
	{
		return;
	}
	// 根节点入栈
	stack[++top] = root;
	// 如果栈不为空
	while (top > -1){
		// 栈顶元素出栈
		BinTreeNode<DataType>* pop = stack[top--];
		if (pop)
		{
			// 访问栈顶元素
			Vistied(pop);
			/*右孩子先于左孩子入栈*/
			// 栈顶元素右孩子入栈
			stack[++top] = pop->rChild;
			// 栈顶元素左孩子入栈
			stack[++top] = pop->lChild;
		}
	}
}

// 中序非递归遍历
template<class DataType>
void BinTree<DataType>::NInOrder()
{
	// 栈
	BinTreeNode<DataType>* stack[50];
	// 栈顶指针
	int top = -1;
	// 遍历指针
	BinTreeNode<DataType>* p = root;
	// 如果当前结点不为空或者栈不为空循环如下操作
	while (p || top > -1) {
		// 如果当前结点不为空则入栈,那么先访问其左子结点
		if (p)
		{
			// 当前节点入栈
			stack[++top] = p;
			// 访问左子节点
			p = p->lChild;
		}
		else
		{
			// 栈顶元素出栈
			p = stack[top--];
			// 访问当前结点
			Vistied(p);
			// 继续访问其右子节点
			p = p->rChild;
		}
	}
}

// 后续非递归遍历
template<class DataType>
void BinTree<DataType>::NPostOrder()
{
	/*
	后序遍历比较复杂: 暂且搁置
	*/
}

/*
前序遍历递归算法
*/
template<class DataType>
void BinTree<DataType>::PreOrder(BinTreeNode<DataType>* bt)
{
	if (bt !=NULL)
	{
		// 访问根节点
		Vistied(bt);
		// 前序遍历左子树
		PreOrder(bt->lChild);
		// 前序遍历右子树
		PreOrder(bt->rChild);
	}
	// 结束遍历
	return;
}

/*
中序遍历递归算法
*/
template<class DataType>
void BinTree<DataType>::InOrder(BinTreeNode<DataType>* bt)
{
	if (bt)
	{
		// 中序遍历左子树
		InOrder(bt->lChild);
		// 访问根节点
		Vistied(bt);
		// 中序遍历右子树
		InOrder(bt->rChild);
	}
	// 结束遍历
	return;
}

/*
后续遍历递归算法
*/
template<class DataType>
void BinTree<DataType>::PostOrder(BinTreeNode<DataType>* bt)
{
	if (bt)
	{
		// 后序遍历左子树
		PostOrder(bt->lChild);
		// 后序遍历右子树
		PostOrder(bt->rChild);
		// 访问根结点
		Vistied(bt);
	}
	return;
}
/*
层序遍历
*/
template<class DataType>
void BinTree<DataType>::LevelOrder()
{
	// 如果是空树,结束遍历
	if (!root)
	{
		return;
	}
	// 创建一个指针数组模拟队列
	BinTreeNode<DataType>* queue[50];
	// 队首指针
	int front = -1;
	// 对尾指针
	int rear = -1;
	// 根结点入队
	queue[++rear] = root;
	// 如果队列不为空
	while (front != rear)
	{
		// 队首元素出队
		BinTreeNode<DataType>* p = queue[++front];
		// 访问队首元素
		Vistied(p);
		// 如果存在左孩子结点, 则左孩子结点入队
		if (p->lChild != NULL)
		{
			queue[++rear] = p->lChild;
		}
		// 如果存在右孩子结点, 则右孩子结点入队
		if (p->rChild != NULL)
		{
			queue[++rear] = p->rChild;
		}
	}
	return;
}

// 树的深度
template<class DataType>
int BinTree<DataType>::Depth()
{
	return Depth(root);
}
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值