1.二叉树的基本操作算法实现
(1)利用二叉树字符串“A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))”创建二叉树的二叉链式存储结构;
(2)输出该二叉树;
(3)输出‘H’节点的左、右孩子结点值;
(4)输出该二叉树的结点个数、叶子结点个数和高度;
2.二叉树的各种遍历算法实现
实现上述二叉树的先序、中序和后序遍历的递归和非递归算法;
二叉树后序遍历非递归算法视频:https://www.bilibili.com/video/av23885544?from=search&seid=13686889146750850571
上面的视频对应的是代码块中的第二个二叉树后序遍历的代码
#include<iostream>
using namespace std;
char cha[100];
typedef struct BiTNode {
char data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
struct Tag {
BiTree p;
};
//链栈的存储结构
typedef struct StackNode
{
BiTNode *data;
struct StackNode *next;
}StackNode, *LinkStack;
//链栈的初始化
LinkStack InitStack(LinkStack &S) {
S = NULL;
return S;
}
//入栈
void Push(LinkStack &S, BiTNode *e)
{
LinkStack p;
p = new StackNode; //生成新结点
p->data = e; //将新结点的数据域置为e
p->next = S; //将新结点插入栈顶
S = p; //修改栈顶指针为p
}
//出栈
void Pop(LinkStack &S, BiTNode *&e)
{
if (S == NULL) cout << "栈空" << endl; //判断栈空
e = S->data; //将栈顶元素赋给e
LinkStack p;
p = S; //用p临时保存栈顶元素空间,以备释放
S = S->next; //修改栈顶指针
delete p; //释放原栈顶元素的空间
}
//判断栈空
int Empty(LinkStack S) {
return(S == NULL);
}
BiTree Gettop(LinkStack &S)//获取栈顶元素的值
{
if (S != NULL)
return S->data;
else return NULL;
}
//创建二叉树
void CreateBTNode(BiTree &T, char *str) {
BiTree St[100]; //顺序栈,便于回溯
BiTNode *p = NULL; //p用于存储即将进入二叉链的新结点
int top = -1, k, i = 0; //St[top]用于存储上一个进入二叉链的结点,以k判定
char ch;
T = NULL; //建立的二叉树初始时为空
ch = str[i]; // 把第一个字符赋给ch
while (ch != '\0') { //遍历字符数组,将字符存入二叉链表
switch (ch) {
case '(':St[++top] = p; k = 1; break; //为左节点
case ')':top--; break; //当遇到')'一次,就回溯一次
case ',':k = 2; break; //为右节点
default:p = new BiTNode;
p->data = ch; p->lchild = p->rchild = NULL;
if (T == NULL) //p指向二叉树的根节点
T = p;
else { //已建立二叉树根节点
switch (k) {
case 1:St[top]->lchild = p; break;
case 2:St[top]->rchild = p; break;
}
}
}
i++;
ch = str[i];
}
}
//输出二叉树
void OutBiTree(BiTree T) {
cout << T->data;
if (T->lchild != NULL || T->rchild != NULL) {
cout << '(';
if (T->lchild != NULL) OutBiTree(T->lchild);
cout << ',';
if (T->rchild != NULL) OutBiTree(T->rchild);
cout << ')';
}
}
//寻找某一结点的左右孩子
void Search_lr(BiTree T,char uch) {
if (T->data == uch)
{
if (T->lchild == NULL) cout << "左孩子为空" << endl;
else cout << T->lchild->data << " ";
if (T->rchild == NULL) cout << "右孩子为空" << endl;
else cout << T->rchild->data << endl;
}
if (T->lchild != NULL || T->rchild != NULL) {
if(T->lchild!=NULL) Search_lr(T->lchild,uch);
if(T->rchild!=NULL) Search_lr(T->rchild,uch);
}
}
//结点的个数
int NodeCount(BiTree T) {
if (T == NULL) return 0;
else
{
//左子树结点个数加右子树结点个数加一个根结点
return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;
}
}
//叶子结点个数
int Leaves(BiTree T) {
if (T == NULL) return 0;
if (T->lchild == NULL && T->rchild == NULL) return 1;
else return Leaves(T->lchild) + Leaves(T->rchild);
}
//计算树的深度
int Depth(BiTree T){
int m = 0, n = 0;
if (T == NULL) return 0;
else{
m = Depth(T->lchild);
n = Depth(T->rchild);
if (m > n) return(m + 1);
else{
return (n + 1);
}
}
}
//先序遍历递归
void FirstOrder(BiTree T) {
cout << T->data;
if (T) {
FirstOrder(T->lchild);
FirstOrder(T->rchild);
}
}
//中序遍历递归
void InOrder(BiTree T) {
if (T) {
InOrder(T->lchild);
cout << T->data;
InOrder(T->rchild);
}
}
//后序遍历递归
void LaterOrder(BiTree T) {
if (T) {
LaterOrder(T->lchild);
LaterOrder(T->rchild);
cout << T->data;
}
}
//先序遍历非递归
void _FirstOrder(BiTree T) {
LinkStack S;
InitStack(S);
BiTNode *p = T;
BiTNode *q = new BiTNode;
while (p || !Empty(S)) {
if (p) {
Push(S, p); //根指针进栈
cout << p->data;
p = p->lchild; //遍历左子树
}
else {
Pop(S, q); //退栈
p = q->rchild; //遍历右子树
}
}
}
//中序遍历非递归
void _InOrder(BiTree T) {
LinkStack S;
InitStack(S);
BiTNode *p = T;
BiTNode *q = new BiTNode;
while (p || !Empty(S)) {
if (p) {
Push(S,p); //根指针进栈
p = p->lchild; //遍历左子树
}
else {
Pop(S, q); //退栈
cout << q->data;//访问根节点
p = q->rchild; //遍历右子树
}
}
}
//后序遍历非递归
void _LaterOrder(BiTree T) {
Tag q[100]; //便于回溯
BiTree p = T, pre = T;
int top = 0;
q[top].p = NULL;
while (p || top != 0) {
if (p != NULL && pre != p->lchild&&pre != p->rchild) {
q[++top].p = p;
p=p->lchild;
}
else {
p = q[top].p;
if (p->rchild != NULL && pre != p->rchild) {
p = p->rchild;
}
else {
cout << p->data;
pre = q[top].p;
p = q[--top].p;
}
}
}
}
//后序遍历非递归第二种,这里可以去看一个b站视频
/*
void _LaterOrder(BiTree T) {
Tag q[100]; //便于回溯
int top = 0;
BiTree p = T;
while (p != NULL) {
q[top].p = p;
q[top++].LR = false;
p = p->lchild;
}
while (top != 0) {
if (top != 0) {
p = q[top - 1].p->rchild;
q[top - 1].LR = true;
}
while (p != NULL) {
q[top].p = p;
q[top++].LR = false;
p = p->lchild;
}
while (q[top - 1].LR == true) {
p = q[--top].p;
cout << p->data;
}
}
}
*/
int main() {
cin >> cha;
BiTree T;
CreateBTNode(T, cha);
OutBiTree(T);
cout << endl;
int depth = Depth(T);
cout <<"树的深度:"<< depth << endl;
char uch;
cout << "请输入想要搜索的结点: ";
cin >> uch;
Search_lr(T, uch);
_FirstOrder(T);
cout << endl;
FirstOrder(T);
cout << endl;
_InOrder(T);
cout << endl;
InOrder(T);
cout << endl;
_LaterOrder(T);
cout << endl;
LaterOrder(T);
cout << endl;
cout << "结点个数: " << NodeCount(T) << endl;
cout << "叶子结点个数: " << Leaves(T) << endl;
}