一、二叉树的创建
//前序创建二叉树
void creat(node *& T)
{
int c;
cin>>c;
if(c==0) T=NULL;
else
{
T=new node;
T->data=c;
creat(T->l);
creat(T->r);
}
}
不难看出还可以有后序、层序创建。
样例输入:1 2 4 0 7 0 0 0 3 5 8 0 0 9 0 0 6 0 0(红色的0对应2号的右分支为空)
二、二叉树的遍历
Ⅰ遍历顺序
前序遍历:由根出发,先尽可能走左枝,实在走不了了就往右。
对于上图:1 2 4 7 3 5 8 9 6
中序遍历:从二叉树的最左下端走起,每次按左枝->根->右枝走。
对于上图:4 7 2 1 8 5 9 3 6
后序遍历:从左到右先叶子后节点的方式遍历访问左右子树,最后访问根节点。逆时针型 (左 右 中)。
对于上图:7 4 2 8 9 5 6 3 1
层序遍历:从上到下,由左至右。
对于上图:1 2 3 4 5 6 7 8 9
Ⅱ 代码实现遍历(递归)
1)前序遍历
//前序遍历二叉树(递归)
void pre1(node *T)
{
if(T)
{
cout<<T->data<<" ";
pre1(T->l);
pre1(T->r);
}
}
2)中序遍历
//中序遍历二叉树(递归)
void mid1(node *T)
{
if(T)
{
mid1(T->l);
cout<<T->data<<" ";
mid1(T->r);
}
}
3)后序遍历
//后序遍历二叉树 (递归)
void post1(node *T)
{
if(T)
{
post1(T->l);
post1(T->r);
cout<<T->data<<" ";
}
}
Ⅲ代码实现遍历(非递归)
1)前序
//前序遍历二叉数(非递归)
void pre2(node *root)
{
stack<node*> s;
node *p=root;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
cout<<p->data<<" ";//第一次遇见时打印
s.push(p);
p=p->l;
}
if(!s.empty())
{
p=s.top();
s.pop();
p=p->r;
}
}
}
2)中序:遇到一个节点就把它压栈,并遍历它的左子树;当左子树遍历结束,从栈顶弹出这个节点并访问它;然后对其右子树再次中序遍历。
//中序遍历二叉树(栈)
void mid2(node* T)
{
node *cur=T;
stack<node*> s;
while(cur||!s.empty())
{
while(cur)//一直向左并把沿途结点压入栈
{
s.push(cur);
cur=cur->l;
}
if(!s.empty())
{
cur=s.top() ;
cout<<cur->data<<" ";//第二次遇到时打印
s.pop();
cur=cur->r;
}
}
}
3)后序
4)层序
//层序遍历二叉树(队列)
void level(node *T)
{
queue<node*> q;
node* cur;
if(!T) return ;
q.push(T);
while(!q.empty())
{
cur=q.front();
q.pop();
cout<<cur->data<<" ";
if(cur->l) q.push(cur->l) ;
if(cur->r )q.push(cur->r);
}
}
深度了解之后可以去试试杭电1710由前序中序求后序,本蒟蒻也写了一篇配套的解题报告。
三、二叉树的查询
这里需要二叉树是一个二叉搜索树,百度百科定义:
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
1)递归实现搜索:
//二叉树搜索(递归)
node *find2(int val,node* T)
{
if(T==NULL) return NULL;
if(T->data>val) return find2(val,T->l);
else if(T->data<val) return find2(val,T->r);
else return T;
}
2)迭代实现查询:
//二叉树搜索(迭代)
node * find(int val,node *T)
{
node* cur=T;
while(cur)
{
if(cur->data==val) return cur;
else if(cur->data>val) cur=cur->l;
else cur=cur->r;
}
return NULL;
}
四、二叉树的删除
五、二叉树的插入
六、二叉树的高度
//1:后序遍历,结点最大栈长即为树的高度
int Heigh1(node *T)
{
node *p=T,*r=NULL;
int max=0; //树高
stack<node*> s;
while(p||!s.empty())
{
if(p!=NULL)
{
s.push(p);
p=p->l;
}
else
{
p=s.top();
if(p->r!=NULL && p->r!=r)
p=p->r;
else
{
if(s.size()>max) max=s.size();//最大层次即为高度
r=p;
s.pop();
p=NULL;
}
}
}
return max;
}
//2:层次遍历,层次即为高度
int Heigh2(node* T)
{
if(!T) return 0;
node *p=T,*Q[100];
int front=-1,rear=-1,last=0,level=0;
Q[++rear]=p;
while(front<rear)
{
p=Q[++front];
if(p->l)
Q[++rear]=p->l;
if(p->r)
Q[++rear]=p->r;
if(front==last)
{
last=rear;
level++; //层次+1
}
}
return level;
}
//3:递归求树高2
int Heigh3(node *T)
{
if(T==NULL) return 0;
else
{
int m = Heigh3(T->l);
int n = Heigh3(T->r);
return (m > n) ? (m+1) : (n+1);
}
}