理论基础 —— 二叉树 —— 二叉链表
【二叉链表】
二叉树一般采用二叉链表存储,其基本思想是:令二叉树的每个结点对应一个链表结点,链表结点除了存放与二叉树结点有关的数据信息外,还要设置指示左右孩子的指针。
template<class T>
struct Node{
T data;//数据域,存放该结点的信息
Node<T> *lchild;//左指针域,存放指向左孩子的指针,当左孩子不存在时为空
Node<T> *rchild;//右指针域,存放指向右孩子的指针,当右孩子不存在时为空
};
如图,一个二叉链表的存储结构如下:
【实现类】
template<class T>
struct Node{
T data;
Node *lchild,*rchild;
};
template<class T>
class BiTree{
public:
BiTree();//构造函数,建立一棵二叉树
~BiTree();//析构函数,释放各结点存储空间
void countNode();//计算二叉树结点个数
void countLeaf();//计算二叉树叶结点个数
void countHeight();//计算二叉树高度
void exchange();//交换左右子树
void preOrder(){preOrder(root);}//前序遍历
void inOrder(){inOrder(root);}//中序遍历
void postOrder(){postOrder(root);}//后序遍历
void levelOrder(){levelOrder(root);}//层次遍历
private:
int numNode=0;//二叉树结点个数
int numLeaf=0;//二叉树叶结点个数
int heightTree=0;//二叉树的高度
Node<T> *root;//指向根节点的头指针
Node<T> *creat();//构造函数调用
void release(Node<T> *bt);//析构函数调用
void countNode(Node<T> *bt);//计算二叉树结点个数
void countLeaf(Node<T> *bt);//计算二叉树叶结点个数
int countHeight(Node<T> *bt);//计算二叉树的高度
void exchange(Node<T> *bt);//交换左右子树
void preOrder(Node<T> *bt);//前序遍历
void inOrder(Node<T> *bt);//中序遍历
void postOrder(Node<T> *bt);//后序遍历
void levelOrder(Node<T> *bt);//层次遍历
};
【构造函数】
构造函数的功能是建立一棵二叉树,由于前序、中序、后序三种遍历方式都无法唯一确定二叉树的左右子树情况,因此针对这个问题,可将二叉树中每个结点的空指针引出一个虚结点,其值为一特定值,如:" # ",以标识为空。
将经过如上处理的二叉树称为原二叉树的扩展二叉树,通过扩展二叉树的一个遍历序列就能唯一确定一棵二叉树。
template<class T>
BiTree<T>::BiTree(){
root=creat();
}
template<class T>
Node<T> *BiTree<T>::creat(){
Node<T> *root;
T ch;
cin>>ch;
if(ch=='#')
root=NULL;
else{
root=new Node<T>;
root->data=ch;
root->lchild=creat();
root->rchild=creat();
}
return root;
}
【析构函数】
template<class T>
BiTree<T>::~BiTree(){
release(root);
}
template<class T>
void BiTree<T>::release(Node<T> *bt){
if(bt!=NULL){
release(bt->lchild);
release(bt->rchild);
delete bt;
}
}
【计算二叉树结点个数】
template<class T>
void BiTree<T>::countNode(){
countNode(root);
}
template<class T>
void BiTree<T>::countNode(Node<T> *bt){
if(bt!=NULL){
countNode(bt->lchild);
numNode++;
countNode(bt->lchild);
}
}
【计算二叉树叶结点个数】
template<class T>
void BiTree<T>::countLeaf() {
countLeaf(root);
}
template<class T>
void BiTree<T>::countLeaf(Node<T> *bt) {
if (bt!=NULL) {
if (bt->lchild==NULL && bt->rchild==NULL)
leafcount=leafcount+1;
else {
countLeaf(bt->lchild);
countLeaf(bt->rchild);
}
}
return;
}
【计算二叉树的高度】
template<class T>
void BiTree<T>::countHeight() {
heightTree=countHeight(root);
}
template<class T>
int BiTree<T>::countHeight(Node<T> *bt) {
int lHeight=0,rHeight=0;
if(bt==NULL)
return 0;
else{
lHeight=countHeight(bt->lchild);
rHeight=countHeight(bt->rchild);
return max(lHeight,rHeight)+1;
}
}
【交换左右子树】
template<class T>
void BiTree<T>::exchange(){
exchange(root);
}
template<class T>
void BiTree<T>::exchange(Node<T> *bt){
if(bt!=NULL){
exchange(bt->lchild);
exchange(bt->rchild);
swap(bt->lchild,bt->rchild);
}
}
【遍历】
1.前序遍历
template<class T>
void BiTree<T>::preOrder(Node<T> *bt){
if(bt==NULL)
return;
else{
cout<<bt->data;
preOrder(bt->lchild);
preOrder(bt->rchild);
}
}
2.中序遍历
template<class T>
void BiTree<T>::inOrder(Node<T> *bt){
if(bt==NULL)
return;
else{
inOrder(bt->lchild);
cout<<bt->data;
inOrder(bt->rchild);
}
}
3.后序遍历
template<class T>
void BiTree<T>::postOrder(Node<T> *bt){
if(bt==NULL)
return;
else{
postOrder(bt->lchild);
postOrder(bt->rchild);
cout<<bt->data;
}
}
4.层次遍历
template<class T>
void BiTree<T>::levelOrder(Node<T> *bt){
queue<Node<T> *> Q;
if(bt!=NULL)
Q.push(bt);
while(!Q.empty()){
bt=Q.front();
Q.pop();
cout<<bt->data;
if(bt->lchild!=NULL)
Q.push(bt->lchild);
if(bt->rchild!=NULL)
Q.push(bt->rchild);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!