// 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;
}
实验三 树的应用
最新推荐文章于 2022-06-21 22:32:00 发布