实验三 树的应用

// BTreeFinal.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"


/*
** 树的构建和遍历实现
** 需要借助栈和队列来实现
*/


#include <iostream>
using namespace std;

const int STACK_INIT_SIZE = 20;		//顺序栈容量
const int QUEUE_INIT_SIZE = 20;		//循环队列容量
const int ERROR = 0;
const int OK = 1;
const int EMPTY = 1;

typedef int Status;

//顺序栈的模板实现
template <typename T>
class SqStack
{
public:
	SqStack();
	~SqStack();
	T GetTop() const;
	Status Push(T &e);
	Status Pop(T &e);
	int stackLength() const;
	Status IsEmpty() const;

private:
	T * base;		//栈的起始位置
	T *top;			//栈顶指针
	int stackSize;	//栈的容量
};

//构造函数
//初始化一个栈
template <typename T>
SqStack<T>::SqStack()
{
	base = new T[STACK_INIT_SIZE];	//申请空间
	top = base;
	stackSize = STACK_INIT_SIZE;	//更新当前栈长
}

//析构函数
//释放一个栈
template <typename T>
SqStack<T>::~SqStack()
{
	delete[] base;
}

//取栈顶元素
template <typename T>
T SqStack<T>::GetTop() const
{
	if (top == base)
	{
		cerr << "当前栈为空" << endl;
	}
	T e = *(top - 1);
	return e;
}

//顺序栈入栈
template <typename T>
Status SqStack<T>::Push(T &e)
{
	if (top - base >= stackSize)	//栈满
	{
		return ERROR;
	}
	*top++ = e;	//先赋值,再加指针
	return OK;
}

//顺序栈出栈
template <typename T>
Status SqStack<T>::Pop(T &e)
{
	if (top == base)
	{
		return ERROR;	//栈空
	}
	e = *--top;	//先赋值,再加指针
	return OK;
}

//求栈长
template <typename T>
int SqStack<T>::stackLength() const
{
	return (top - base);
}

//判断栈是否为空
template <typename T>
Status SqStack<T>::IsEmpty() const
{
	if (top == base)
	{
		return EMPTY;	//栈空
	}
	else
	{
		return !EMPTY;	//栈非空
	}
}


//循环队列的模板实现
template <typename T>
class CircularQueue
{
public:
	CircularQueue();
	~CircularQueue();
	Status EnQueue(T e);
	Status DeQueue(T &e);
	int QueueLength() const;
	Status IsEmpty() const;

private:
	T * base;		//内存空间的首地址
	int front;		//头指针
	int rear;		//尾指针
	int queueSize;	//队列的长度
};

//构造函数
//初始化队列
template <typename T>
CircularQueue<T>::CircularQueue()
{
	base = new T[QUEUE_INIT_SIZE];
	if (base == nullptr)
	{
		cerr << "内存分配错误!!" << endl;
	}
	rear = front = 0;
	queueSize = QUEUE_INIT_SIZE;
}

//析构函数
//释放空间
template <typename T>
CircularQueue<T>::~CircularQueue()
{
	delete[] base;
}

//循环队列元素入队
template <typename T>
Status CircularQueue<T>::EnQueue(T e)
{
	if ((rear + 1) % QUEUE_INIT_SIZE == front)	//队列已满
	{
		return ERROR;
	}
	base[rear] = e;
	rear = (rear + 1) % QUEUE_INIT_SIZE;	//尾指针后移
	return OK;
}

//循环队列元素出队
template <typename T>
Status CircularQueue<T>::DeQueue(T &e)
{
	if (rear == front)	//队列为空
	{
		return ERROR;
	}
	e = base[front];
	front = (front + 1) % QUEUE_INIT_SIZE;	//删除一个元素后头指针后移
	return OK;
}


//求循环队列的长度
template <typename T>
int CircularQueue<T>::QueueLength() const
{
	//确保其为一个整数再取模
	return (rear - front + QUEUE_INIT_SIZE) % QUEUE_INIT_SIZE;
}

//判断该循环队列是否为空
template <typename T>
Status CircularQueue<T>::IsEmpty() const
{
	return (rear == front) ? EMPTY : !EMPTY;
}


//二叉链表表示的树节点
template <class T>
class BTNode
{
public:
	T data;			//存储该节点的相关数据信息
	BTNode *lChild;	//左孩子节点
	BTNode *rChild;	//右孩子节点
};


//二叉树类定义
template <typename T>
class BTree
{
public:
	BTree();
	~BTree();
	void PreOrderDispTree(BTNode<T> *const &t) const;
	void PreOrderDispTreeRE(BTNode<T> *t) const;
	void InOrderDispTree(BTNode<T> *t) const;
	void InOrderDispTreeRE(BTNode<T> *t) const;
	void PostOrderDispTree(BTNode<T> *t) const;
	void PostOrderDispTreeRE(BTNode<T> *t) const;
	void levelDispTree(BTNode<T> *t) const;
	void createBTree(char *str);
	int getBTreeHeight(BTNode<T> *t) const;
	void DispBTree(BTNode<T> *t) const;
	BTNode<T>* getRoot() { return root; }
	void destory(BTNode<T> *&t);
private:
	BTNode<T> *root;	//二叉树的根节点
};

//构造函数
//初始化该树
template <class T>
BTree<T>::BTree()
{
	root = nullptr;
}

//析构函数
template <class T>
BTree<T>::~BTree()
{
	destory(root);
}

//销毁树结构
//相当于树的后序遍历
template <class T>
void BTree<T>::destory(BTNode<T> *&t)
{
	if (t != NULL)
	{
		destory(t->lChild);
		destory(t->rChild);
		delete t;
	}
}

//先序遍历算法 -- 递归实现
//按照根-左-右的顺序
template <typename T>
void BTree<T>::PreOrderDispTree(BTNode<T> *const &t) const
{
	if (t != nullptr)		//根节点不为空
	{
		cout << t->data;
		PreOrderDispTree(t->lChild);	//递归遍历左子树
		PreOrderDispTree(t->rChild);	//递归遍历右子树
	}
}

//先序遍历算法
//非递归实现  --  利用栈
template <typename T>
void BTree<T>::PreOrderDispTreeRE(BTNode<T> *t) const
{
	SqStack<BTNode<T>*> s;	//声明一个指针栈
	BTNode<T> *p = t;		//开始时指向根

	while (p != nullptr || !s.IsEmpty())
	{
		while (p != nullptr)
		{
			cout << p->data;
			s.Push(p);
			p = p->lChild;
		}
		//通过下一次循环中的内嵌while实现右子树的遍历
		if (!s.IsEmpty())
		{
			s.Pop(p);	//将当前子树的根节点出栈访问右节点
			p = p->rChild;
		}
	}
	cout << endl;
}

//中序遍历算法 -- 递归实现
//按照左---根---右的顺序
template <typename T>
void BTree<T>::InOrderDispTree(BTNode<T> *t) const
{
	if (t != nullptr)
	{
		InOrderDispTree(t->lChild);		//中序遍历左子树
		cout << t->data;
		InOrderDispTree(t->rChild);		//中序遍历右子树
	}
}

//中序遍历算法
//非递归实现
template <typename T>
void BTree<T>::InOrderDispTreeRE(BTNode<T> *t) const
{
	SqStack<BTNode<T>*> s;
	BTNode<T> *p = t;

	while (p != nullptr || !s.IsEmpty())
	{
		while (p != nullptr)
		{
			s.Push(p);
			p = p->lChild;
		}
		if (!s.IsEmpty())
		{
			s.Pop(p);
			cout << p->data;	//访问根节点
			p = p->rChild;		//通过下一次循环来实现右子树遍历
		}
	}
	cout << endl;
}

//后序遍历算法 -- 递归实现
//按照左---右---根的顺序
template <typename T>
void BTree<T>::PostOrderDispTree(BTNode<T> *t) const
{
	if (t != nullptr)
	{
		PostOrderDispTree(t->lChild);
		PostOrderDispTree(t->rChild);
		cout << t->data;
	}
}

//后序遍历算法
//非递归实现
//采用双栈法实现
template <typename T>
void BTree<T>::PostOrderDispTreeRE(BTNode<T> *t) const
{
	if (t != nullptr)
	{
		SqStack<BTNode<T>*> s1;
		SqStack<BTNode<T>*> s2;
		BTNode<T> *p = nullptr;
		s1.Push(t);
		while (!s1.IsEmpty())
		{
			s1.Pop(p);
			s2.Push(p);
			if (p->lChild != nullptr)
			{
				s1.Push(p->lChild);
			}
			if (p->rChild != nullptr)
			{
				s1.Push(p->rChild);
			}
		}
		while (!s2.IsEmpty())
		{
			//出栈序列即为后序遍历序列
			s2.Pop(p);
			cout << p->data;
		}
	}
	cout << endl;
}


//层次遍历
//借助循环队列实现
template <typename T>
void BTree<T>::levelDispTree(BTNode<T> *t) const
{
	CircularQueue<BTNode<T>*> queue1;
	BTNode<T> *p = t;
	BTNode<T> *q = nullptr;
	if (t != nullptr)
	{
		queue1.EnQueue(p);	//根节点进队列
		while (!queue1.IsEmpty())
		{
			queue1.DeQueue(q);
			cout << q->data;
			if (q->lChild != nullptr)
			{
				queue1.EnQueue(q->lChild);
			}
			if (q->rChild != nullptr)
			{
				queue1.EnQueue(q->rChild);
			}
		}
	}
	cout << endl;
}

//根据广义表类型创建二叉树
template <typename T>
void BTree<T>::createBTree(char *str)
{
	//需要用到存放BTree的堆栈
	SqStack<BTNode<T>*> s;
	BTNode<T> *p = nullptr;
	int j = 0;	//当前处理字符的标志
	int k = -1;	//当前处理字符的左右标志
	char ch;
	ch = str[j];	//逐个处理字符

	while (ch != '\0')	//到字符串尾部
	{
		switch (ch)
		{
		case '(':
			s.Push(p);	//将根节点入栈,设置处理左子树
			k = 1;		//表示后面节点为前面节点的左孩子
			break;
		case ')':
			s.Pop(p);
			break;
		case ',':
			k = 2;	//设置处理右子树
			break;
		default:
			p = new BTNode<T>;
			p->data = ch;
			p->lChild = nullptr;
			p->rChild = nullptr;
			if (root == nullptr)
			{
				root = p;	//设置根节点
			}
			else
			{
				if (k == 1)
				{
					s.GetTop()->lChild = p;
				}
				if (k == 2)
				{
					s.GetTop()->rChild = p;
				}
			}
		}
		ch = str[++j];
	}
}

//计算二叉树的高度
template <typename T>
int BTree<T>::getBTreeHeight(BTNode<T> *t) const
{
	int lChildHeight = -1;
	int rChildHeight = -1;
	if (t == nullptr)
	{
		return 0;
	}
	else
	{
		lChildHeight = getBTreeHeight(t->lChild);
		rChildHeight = getBTreeHeight(t->rChild);
		return (lChildHeight > rChildHeight ? lChildHeight + 1 : rChildHeight + 1);
	}
}

//输出二叉树
template <typename T>
void BTree<T>::DispBTree(BTNode<T> *t) const
{
	if (t != nullptr)
	{
		cout << t->data;
		if ((t->lChild != nullptr) || (t->rChild != nullptr))
		{
			cout << '(';
			DispBTree(t->lChild);
			if (t->rChild != nullptr)
			{
				cout << ',';
			}
			DispBTree(t->rChild);
			cout << ')';
		}
	}
}

int main()
{
	BTree<char> tree;
	char str[] = "A(B(D(,G)),C(E,F))";
	cout << "-----二叉树功能测试-----" << endl;
	tree.createBTree(str);
	BTNode<char> *root = tree.getRoot();
	cout << "这棵树的结构为:";
	tree.DispBTree(root);
	cout << endl;
	cout << "先序遍历递归实现:";
	tree.PreOrderDispTree(root);
	cout << endl;
	cout << "先序遍历非递归实现:";
	tree.PreOrderDispTreeRE(root);
	cout << "中序遍历递归实现:";
	tree.InOrderDispTree(root);
	cout << endl;
	cout << "中序遍历非递归实现:";
	tree.InOrderDispTreeRE(root);
	cout << "后序遍历递归实现:";
	tree.PostOrderDispTree(root);
	cout << endl;
	cout << "后序遍历非递归实现:";
	tree.PostOrderDispTreeRE(root);
	cout << "层序遍历结果为:";
	tree.levelDispTree(root);
	cout << "树的高度为:";
	cout << tree.getBTreeHeight(root) << endl;

	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值