🌍新人小白的博客
⌛️希望大家多多关注
🌱一起加油,共同成长
🎃以后会经常更新哒~🙈
⭐️个人主页: 收藏加关注,永远不迷路~⭐️
数据结构系列👀
一:顺序表的操作,你真的学会了吗?
二:顺序栈的基本操作
三:循环队列的基本操作,你学会了吗?
四:单链表的操作(超详细),保证你看完不后悔
前言😺
Tips:文章有点长,小主耐心一点哦~
(1)采用二叉链表结构建立二叉树;
(2)编程实现二叉树的先序、中序、后序和层序遍历;
(3)编程实现非递归中序遍历
(4)编程实现:求二叉树的高度和叶子结点个数;
一、二叉树是什么?😜
二叉树是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。(◍°∇°◍)ノ゙
二、实现步骤🙊
1.定义存储表示
二叉树的链式存储结构
用链表来表示一棵二叉树。链表中的每个节点由三个域来组成,除了数据域以外,还有两个指针域,分别用来给出该结点的左孩子和右孩子所在结点的存储地址🐒
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
} BiTNode,*BiTree;
typedef struct StackNode
2.二叉树的遍历
遍历定义: 指以一定的次序访问二叉树中的每个结点,并且每个结点仅被访问一次。
遍历用途: 是树结构插入、删除、修改、查找和排序运算的前提,是二叉树一切运算的核心。
3.三种常见的遍历
三种遍历的代码实现:
1.先序遍历算法
void PreOrderTraverse(BiTree T)
{
if(T)
{
cout<<T->data;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
2.中序遍历算法
(1)递归实现
void InOrderTraverse(BiTree T)
{
if(T)
{
InOrderTraverse(T->lchild);
cout<<T->data;
InOrderTraverse(T->rchild);
}
}
(2)非递归
void InOrderTraverse_NonRecursive ( BiTree T)
{
LinkStack S=NULL;
BiTree p=T;
BiTree q;
while ( p || S!=NULL )
{
if ( p)
{
Push( S, p );
p=p->lchild;//根指针进栈,遍历左子树
}
else
{
Pop( S, q ); // 退栈
cout<<q->data;//访问根结点
p=q->rchild;//遍历右子树
}
}
}
3.后序遍历算法
void PostOrderTraverse(BiTree T)
{
if(T)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data;
}
}
4.特殊的遍历
层序遍历:
void FloorOrderTraverse(BiTree T) //层序遍历
{
BiTree temp[100];
int in=0;
int out=0;
temp[in++] = T; //保存二叉树结点
while(in>out)
{
if(temp[out])
{
cout<<temp[out]->data;
temp[in++] = temp[out]->lchild;
temp[in++] = temp[out]->rchild;
}
out++;
}
}
三、完整代码🐻
代码可直接运行😄
#include <iostream>
using namespace std;
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
} BiTNode,*BiTree;
typedef struct StackNode
{
BiTree data;
struct StackNode *next;
} StackNode,*LinkStack;
int idx=0;
void CreateBiTree(BiTree &T,char *treeSeq)
{
if(treeSeq[idx]=='#')
{
T=NULL;
++idx;
}
else
{
T=new BiTNode;
T->data=treeSeq[idx++];
CreateBiTree(T->lchild,treeSeq); //递归创建左子树
CreateBiTree(T->rchild,treeSeq); //递归创建右子树
}
}
void PreOrderTraverse(BiTree T)
{
if(T)
{
cout<<T->data;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void InOrderTraverse(BiTree T)
{
if(T)
{
InOrderTraverse(T->lchild);
cout<<T->data;
InOrderTraverse(T->rchild);
}
}
void PostOrderTraverse(BiTree T)
{
if(T)
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data;
}
}
void FloorOrderTraverse(BiTree T) //层序遍历
{
BiTree temp[100];
int in=0;
int out=0;
temp[in++] = T; //保存二叉树结点
while(in>out)
{
if(temp[out])
{
cout<<temp[out]->data;
temp[in++] = temp[out]->lchild;
temp[in++] = temp[out]->rchild;
}
out++;
}
}
void DestroyBiTree(BiTree &T)
{
if(T)
{
DestroyBiTree(T->lchild);
DestroyBiTree(T->rchild);
delete T;
T=NULL;
}
}
int NodeCount(BiTree T)
{
if(T == NULL )
return 0;
else
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
int LeafCount(BiTree T)
{
if(T==NULL) //如果是空树返回0
return 0;
if (T->lchild == NULL && T->rchild == NULL)
return 1; //如果是叶子结点返回1
else return LeafCount(T->lchild) + LeafCount(T->rchild);
}
int Depth(BiTree T)
{
if (T==NULL) return 0;
else
{
int m=Depth(T->lchild);
int n=Depth(T->rchild);
if (m>=n) return m+1;
else return n+1;
}
}
void Push(LinkStack &S,BiTree p)
{
StackNode *q=new StackNode;
q->data=p;
q->next=S;
S=q;
}
bool Pop(LinkStack &S,BiTree &p)
{
if(S==NULL)
return false;
p=S->data;
StackNode *q=S;
S=S->next;
delete q;
return true;
}
void InOrderTraverse_NonRecursive ( BiTree T)
{
LinkStack S=NULL;
BiTree p=T;
BiTree q;
while ( p || S!=NULL )
{
if ( p)
{
Push( S, p );
p=p->lchild;//根指针进栈,遍历左子树
}
else
{
Pop( S, q ); // 退栈
cout<<q->data;//访问根结点
p=q->rchild;//遍历右子树
}
}
}
int main()
{
char treeSeq[20]="ABC##DE#G##F###";
BiTree T;
CreateBiTree(T,treeSeq);
cout<<"PreOrder Traverse:"<<endl;
PreOrderTraverse(T);
cout<<endl;
cout<<"InOrder Traverse:"<<endl;
InOrderTraverse(T);
cout<<endl;
cout<<"Non-Recursive InOrder Traverse:"<<endl;
InOrderTraverse_NonRecursive(T);
cout<<endl;
cout<<"PostOrder Traverse:"<<endl;
PostOrderTraverse(T);
cout<<endl;
cout<<"FloorOrder Traverse:"<<endl;
FloorOrderTraverse(T);
cout<<endl;
cout<<"Number of Nodes:"<<NodeCount(T)<<endl;
cout<<"Number of LeafNodes:"<<LeafCount(T)<<endl;
cout<<"Depth of Tree:"<<Depth(T)<<endl;
DestroyBiTree(T);
return 0;
}
四、运行结果🐾
这里是运行的结果哦 ❤️
结语🌍
通过学习来掌握二叉树的二叉链表存储方式及二叉树的特征;验证二叉树在二叉链表存储结构下遍历操作的实现。🚀🚀🚀
线索二叉树和哈夫曼树的实现将于后续更新,敬请期待哦😎😎😎
如果您有什么问题或者建议,欢迎在评论区留言哦,博主会第一时间回复哒❤️❤️❤️