以二叉链表作为存储结构编写程序,实现如下功能:
将近400行代码,觉得挺好的给个关注给个赞吧!谢谢
1、根据输入的数据建立一个二叉树;
2、分别采用前序、中序、后序的遍历方式显示输出二叉树的遍历结果
3、采用非递归的编程方法,分别统计二叉树的节点个数、度为1、度为2和叶子节点的个数,以及数据值的最大值和最小值。
4.7种递归方式:递归前序、递归中序、递归后序、层序
、非递归前序、非递归后序、非递归中序
代码如下(内含注释)!!
由于非递归遍历以及层次遍历需要栈和队列、因此其中还包含栈、队列的构建!!
输入:PBC##DE###GF#I##H##
预期输出:
经前序遍历后的结果为:P B C D E G F I H
经中序遍历后的结果为:C B E D P F I G H
经后序遍历后的结果为:C E D B I F H G P
经层序遍历后的结果为:P B G C D F H E I
经非递归前序遍历后的结果为:P B C D E G F I H
经非递归中序遍历后的结果为:C B E D P F I G H
经非递归后序遍历后的结果为:C E D B I F H G P
该二叉树中含有9个结点
该二叉树中度为2的结点有3个
该二叉树中度为1的结点有2个
该二叉树中叶子结点有4个
该二叉树中最大数据值为:P
该二叉树中最小数据值为:B
#include <iostream>
using namespace std;
//============栈结构================
template <class T>
struct Node{
//成员变量
T data;
Node *next;
//构造函数
Node(T x) : data(x), next(NULL) {}
Node(){}
};
//模板类
template <class T>
class Stack{
//私有成员变量
private:
Node<T> *head;
//栈的大小
int sizeOfStack;
public:
//构造函数
Stack() : head(NULL), sizeOfStack(0) {}//参数总表
//成员方法
//求栈的大小
int size();
//判断是否为空
bool isEmpty();
//入栈
void push(T x);
//出栈
void pop();
//求栈顶元素
T top();
};
//栈是否为空
template <class T>
bool Stack<T>::isEmpty(){
return sizeOfStack == 0;
}
//压栈
template <class T>
void Stack<T>::push(T x){
//新建一个结点
Node<T> *node = new Node<T>(x);
node->next = head;
head = node;
sizeOfStack++;
}
//出栈
template <class T>
void Stack<T>::pop(){
if (isEmpty()) return;//若无元素,则退出当前方法
Node<T> *p = head;
head = head->next;
delete p;
sizeOfStack--;
}
//获取栈顶元素
template <class T>
T Stack<T>::top(){
return head->data;
}
//==============队列==================
//模板类
template <class T>
class Quene{
private:
//头指针、尾指针
Node<T> *front;
Node<T> *rear;
//队列大小
int sizeOfQuene;
public:
//构造函数L:
Quene(){
front = new Node<T>();
rear = new Node<T>();
front->next = rear;
rear->next = NULL;
sizeOfQuene = 0;
}
//成员方法
//初始化
// void initQuene();
//入队
void enQuene(T data);
//出队
T ouQuene();
//是否为空
bool isEmpty();
};
//队列是否为空
template <class T>
bool Quene<T>::isEmpty(){
return sizeOfQuene == 0;
}
//入队
template <class T>
void Quene<T>::enQuene(T x){
Node<T> *node = new Node<T>(x);
Node<T> *p = front;
while (p->next != rear){
p = p->next;
}
p->next = node;
node->next = rear;
sizeOfQuene++;
}
//出队
template <class T>
T Quene<T>::ouQuene(){
Node<T> *p = front->next;
front->next = front->next->next;
sizeOfQuene--;
return p->data;
}
//==============队列==================
//==============二叉树================
//结点类型
class BiNode{
public:
//数据域
char data;
//左右孩子指针
BiNode *left_Child;
BiNode *right_Child;
};
//二叉树类
class BiTree{
//用根结点表示一棵二叉树
public:
BiNode *root;
//构造函数
BiTree(){
root = createTree(root);
}
//创建树
BiNode* createTree(BiNode *bt);
//递归前序遍历树
void preOrderTraverse(BiNode *bt);
//递归中序遍历树
void inOrderTraverse(BiNode *bt);
//递归后序遍历树
void postOrderTraverse(BiNode* bt);
//递归层次遍历树
void leverOrderTravrse(BiNode* bt);
//非递归前序遍历
void unDiGuiPreOrderTraverse(BiNode* b, int &count, int &number, int &amount,char &max, char &min);//引用传递,count是指结点数,
//非递归中序遍历
void unDiGuiInOrderTraverse(BiNode* bt);
//非递归后序遍历
void unDiGuiPostOrderTraverse(BiNode* bt);
//非递归统计结点个数
};
//将指针和入栈次数标记temp封装成一个结构体
struct Flag{
BiNode* ptr;
int temp;
};
//建树
BiNode* BiTree::createTree(BiNode *bt){
char ch;
cin >> ch;
if (ch == '#')
bt = NULL;
else{
bt = new BiNode;
bt->data = ch;
bt->left_Child = createTree(bt->left_Child);
bt->right_Child = createTree(bt->right_Child);
}
return bt;
}
//递归前序遍历树
void BiTree::preOrderTraverse(BiNode* bt){
if (bt)
{
cout << bt->data << " ";
preOrderTraverse(bt->left_Child);
preOrderTraverse(bt->right_Child);
}
else{
return;
}
}
//递归中序遍历树
void BiTree::inOrderTraverse(BiNode* bt){
if (bt){
inOrderTraverse(bt->left_Child);
cout << bt->data << " ";
inOrderTraverse(bt->right_Child);
}
else{
return;
}
}
//递归后序遍历树
void BiTree::postOrderTraverse(BiNode* bt){
if (bt){
postOrderTraverse(bt->left_Child);
postOrderTraverse(bt->right_Child);
cout << bt->data << " ";
}
else{
return;
}
}
//层次遍历树
void BiTree::leverOrderTravrse(BiNode* bt){
//设置队列
Quene<BiNode*> quene;
BiNode* p;
if (bt == NULL) return;
quene.enQuene(bt);//根先入队
while (!quene.isEmpty()){
//出队
p = quene.ouQuene();
//访问结点
cout << p->data<<" ";
//左孩子入队
if (p->left_Child != NULL){
quene.enQuene(p->left_Child);
}
if (p->right_Child != NULL){
quene.enQuene(p->right_Child);
}
}
}
//非递归前序遍历
void BiTree::unDiGuiPreOrderTraverse(BiNode* bt, int &count , int &number,int &amount,char &max,char &min){
//创建一个指针栈
Stack<BiNode*> s;
BiNode *p = bt;
while (p != NULL || !s.isEmpty()){//当p为空且栈也为空时才退出循环
while (p != NULL){
//访问根结点
cout << p->data << " ";
//最大值
if (max < p->data){
max = p->data;
}
//最小值
if (min>p->data){
min = p->data;
}
//节点数
count++;
//度为2结点数
if (p->left_Child&&p->right_Child){
number++;
}
//度为1结点数
else if (p->left_Child || p->right_Child){
amount++;
}
//将p指向的结点入栈
s.push(p);
//遍历左子树
p = p->left_Child;
}
//栈不为空
if (!s.isEmpty()){
//根结点出栈
p = s.top();
s.pop();
//遍历右子树
p = p->right_Child;
}
}
}
//非递归中序遍历(与前序十分类似)
void BiTree::unDiGuiInOrderTraverse(BiNode* bt){
//创建一个指针栈
Stack<BiNode*> s;
BiNode *p = bt;
while (p != NULL || !s.isEmpty()){//当p为空且栈也为空时才退出循环
while (p != NULL){
//将p指向的结点入栈
s.push(p);
//遍历左子树
p = p->left_Child;
}
//栈不为空
if (!s.isEmpty()){
//根结点出栈
p = s.top();
//访问根结点
cout << p->data << " ";
s.pop();
//遍历右子树
p = p->right_Child;
}
}
}
//非递归后序遍历(在后序遍历中结点要入两次栈,出两次栈,要加以区分将temp标记和指针封装成一个结构体)
void BiTree::unDiGuiPostOrderTraverse(BiNode* bt){
//创建一个存储Flag的栈
Stack<Flag> s;
Flag flag;
BiNode *p = bt;
//当p为空且栈也为空时才退出循环
while (p != NULL || !s.isEmpty()){
if (p != NULL){
flag.ptr = p;
flag.temp = 1;//标记为1表示第一次入栈
//将flag压入栈
s.push(flag);
//访问左孩子
p = p->left_Child;
}
else{
//出栈
flag = s.top();
s.pop();
//将p指向当前需要处理的结点
p = flag.ptr;
//判断入栈次数,若为1,则表明只访问过左子树,还需继续访问右子树
if (flag.temp == 1){
//将temp改为2,即指将要进行第二系入栈
flag.temp = 2;
s.push(flag);
//访问右孩子
p = p->right_Child;
}
//若temp=2则表示左右子树均已被访问
else{
//输出结点数据域
cout << p->data << " ";
//令p为空,以保证下一次循环时会出栈
p = NULL;
}
}
}
}
//主函数
int main(){
//PBC##DE###GF#I##H##
//创建一棵树
int count = 0;
int number = 0;
int amount = 0;
char max = 'A';
char min = 'Z';
BiTree *tree = new BiTree();
cout << "经前序遍历后的结果为:";
tree->preOrderTraverse(tree->root);
cout << "\n";
cout << "经中序遍历后的结果为:";
tree->inOrderTraverse(tree->root);
cout << "\n";
cout << "经后序遍历后的结果为:";
tree->postOrderTraverse(tree->root);
cout << "\n";
cout << "经层序遍历后的结果为:";
tree->leverOrderTravrse(tree->root);
cout << "\n";
cout << "经非递归前序遍历后的结果为:";
tree->unDiGuiPreOrderTraverse(tree->root, count,number,amount,max,min);
cout << "\n";
cout << "经非递归中序遍历后的结果为:";
tree->unDiGuiInOrderTraverse(tree->root);
cout << "\n";
cout << "经非递归后序遍历后的结果为:";
tree->unDiGuiPostOrderTraverse(tree->root);
cout << "\n";
cout << "该二叉树中含有" << count << "个结点" << endl;
cout << "该二叉树中度为2的结点有" << number << "个" << endl;
cout << "该二叉树中度为1的结点有" << amount << "个"<<endl;
cout << "该二叉树中叶子结点有" << count - number - amount << "个" << endl;
cout << "该二叉树中最大数据值为:" << max << endl;
cout << "该二叉树中最小数据值为:" << min << endl;
return 0;
}
运行结果: