随着数据结构的进行平时打题练习的知识点越来越清晰,多看书看细节,比如要注意避免调用者查看数据运行节点,可以将树查询函数封为私有,公有时直接调用私有函数,多多积累平时更加严谨
多积累总能排上用场
首先是树基本的表示
通过两个结构体记录子节点,最后用一个顺序结构比如一维数组进行链接
(或者说手动建立关系)
//孩子表示法
struct CTNode
{
int child;
CTNode *next;
};
struct CENode
{
int data;
CTNode *firstChild;
};
同样是树的一种表示方法,上面的两个结构体进行的综合
//孩子兄弟表示法
struct TNode
{
int data;
TNNode *firstChild,*rightSib;
};
之后便是二叉树的表示,二叉树应用极为广泛,同样可以衍生多种算法,时十分优秀的基本结构,以下给出链表实现
数组实现思想也同样
//二叉链表实现
struct BiNode
{
int data;
BiNode *lchild,*rchild;
};
首先分解左右孩子
class BiTree
{
public:
BiTree(){root=Creat();}
~BiTree(){Release(root);}
void PreOrder(){PreOrder(root);}
void InOrder(){InOrder(root);}
void PostOrder(){PostOrder(root);}
void LevelOrder();
private:
BiNode *Creat();
void Release(BiNode *bt);
void PreOrder(BiNode *bt);
void InOrder(BiNode *bt);
void PostOrder(BiNode *bt);
BiNode *root;
};
基本操作一览
前中后序遍历普通版本:
//前序遍历
void BiTree::PreOrder(Binode *bt)
{
if(bt==NULL) return ;
else {
cout<<bt->data<<"\t";
PreOrder(bt->lchild);
PreOrder(bt->rchild);
}
}
//中序遍历
void BiTree::InOrder(Binode *bt)
{
if(bt==NULL) return;
else {
InOrder(bt->lchild);
cout<<bt->data<<"\t";
InOrder(bt->rchild);
}
}
//后序遍历
void BiTree::PostOrder(Binode *bt)
if(bt==NULL) return ;
else {
PostOrder(bt->lchild);
PostOrder(bt->rchild);
cout<<rt->data<<"\t";
}
}
前序中序后序遍历,树的生成过程是不变的,所谓前中后不过是在输出上下了功夫
极其简单
前中后序非递归版本
//前序遍历非递归算法
void Bitree::PreOrder()
{
Binode *bt=root;
Binode *s[100];
int top=-1;
while(bt!=NULL||top!=-1){
while(t!=NULL){
cout<<bt->data<<endl;
s[++top]=bt;
bt=bt->lchild;
}
if(top!=-1){
bt=s[top--];
bt=bt->rchild;
}
}
}
//中序遍历非递归算法
void Bitree::InOrder()
{
Binode *bt=root;
Binode *s[100];
int top=-1;
while(bt!=NULL||top!=-1){
while(t!=NULL){}
s[++top]=bt;
bt=bt->lchild;
}
if(top!=-1){
bt=s[top--];
cout<<bt->data<<endl;
bt=bt->rchild;
}
}
//层序遍历
void BiTree::LevelOrder()
{
BiNode *Q[100],*q=NULL;
int front=-1,rear=-1;
if(root==NULL) return ;
Q[++rear]=root;
while(front!=rear){
q=Q[++front];
cout<<q->data<<"\t";
if(q->lchild!=NULL) Q[++rear]=q->lchild;
if(q->rchild!=NULL) Q[++rear]=q->rchild;
}
}
层序遍历是利用队列思想,用数组进行模拟操作,每次将一层的节点所对应的指针进行压入队列,每层ok完之后就可以替换继续下一层
//建立二叉树(扩展二叉树)
BiNode *BiTree::Creat()
{
Binode *bt;
char ch;
cin>>ch;
if(ch=='#') bt=NULL;
else {
bt=new BiNode;
bt->data=ch;
bt->lchild=Creat();
bt->rchild=Creat();
}
return bt;
}
树的建立,可以理解为提前将树的每个节点值赋初值
//销毁二叉树
void BiTree::Release(BiNode *bt)
{
if(bt==NULL) return ;
else {
Release(bt->lchild);
Release(bt->rchild);
delete bt;
}
}
跟之前链表销毁指针操作同理,将指针所指向的数据空间清空,释放空间
//基本操作运行界面
#include<iostream>
using namespace std;
int main()
{
BiTree T;
cout<<"前序遍历:"<<endl;
T.PreOrder();
cout<<"中序遍历:"<<endl;
T.InOrder();
cout<<"后序遍历:"<<endl;
T.PostOrder();
cout<<"层序遍历:"<<endl;
T.LevelOrder();
return 0;
}