二叉树的基本操作
二叉树的创建
#include<stdio.h>
#include<stdlib.h>
typedef struct BNode{
char data;
struct BNode *left,*right;
}BNode,*Bitree;
void CreateTree(Bitree &T)//使用先序递归的方式建立,输入..代表该节点已是树叶
{
char n;
scanf("%c",&n);
if(n=='#') T=NULL;
else
{
T=(Bitree)malloc(sizeof(BNode));//接受到非.的字符立即创建一个节点,接着创建他的左子树和右子树
T->data=n;
CreateTree(T->left);
CreateTree(T->right);
}
}
- 输入124##5##36###即可
- 先序遍历:124536
- 中序遍历:425163
- 后序遍历:452631
- 层序遍历:123456
先序,中序,后序的递归算法
void pretravel(Bitree T)//先序遍历的递归
{
if(T)
{
printf("%c ",T->data);
pretravel(T->left);
pretravel(T->right);
}
}
void intravel(Bitree T)//中序遍历的递归
{
if(T)
{
intravel(T->left);
printf("%c ",T->data);
intravel(T->right);
}
}
void posttravel(Bitree T)//后续遍历的递归
{
if(T)
{
posttravel(T->left);
posttravel(T->right);
printf("%c ",T->data);
}
}
非递归的先序遍历,中序遍历
typedef struct Stack{
Bitree *top;
Bitree *base;
int high;
}stack;
void initstack(Stack &s)
{
s.base=(Bitree*)malloc(100*sizeof(Bitree));
s.top=s.base;
s.high=100;
}
void Push(Stack& s,Bitree &e)//e为指向树中节点的指针
{
if(s.top-s.base>=s.high)
{
Bitree *newbase=(Bitree*)realloc(s.base,10*sizeof(Bitree));
s.base=newbase;
s.top=s.base+s.high;
s.high+=10;
}
*s.top=e;//将指针存放在栈中
s.top++;
}
void Pop(Stack& s,Bitree &e)//用e来接收指向上一节点的指针
{
if(s.top==s.base) return;
s.top--;
e=*s.top;
}
void Firtravel(Bitree T)//非递归的先序遍历
{
Stack s;
initstack(s);
Bitree p=T;
while(p||s.base!=s.top)
{
if(p)
{
printf("%c ",p->data);
Push(s,p);
p=p->left;
}
else
{
Pop(s,p);
p=p->right;
}
}
}
void ordertravel(Bitree T)//非递归的中序遍历
{
Stack s;
initstack(s);
Bitree p=T;
while(p||s.base!=s.top)
{
if(p)
{
Push(s,p);
p=p->left;
}
else
{
Pop(s,p);
printf("%c ",p->data);
p=p->right;
}
}
}
层序遍历
typedef struct squeue{
Bitree *data;
int front;
int rear;
}squeue;
void initsqueue(squeue &q)//初始化循环队列
{
q.data=(Bitree*)malloc(100*sizeof(Bitree));
q.front=0;
q.rear=q.front;
}
void Enqueue(squeue &q,Bitree &e)
{
if((q.rear+1)%100==q.front) return;
q.data[q.rear]=e;
q.rear=(q.rear+1)%100;
}
void Dequeue(squeue &q,Bitree &e)
{
if(q.rear==q.front) return;
e=q.data[q.front];
q.front=(q.front+1)%100;
}
void ordertravel(Bitree &T)//层序遍历
{
squeue Q;
initsqueue(Q);
Bitree p=T;
if(T) Enqueue(Q,p);
while(Q.front!=Q.rear)
{
Dequeue(Q,p);
printf("%c ",p->data);
if(p->left) Enqueue(Q,p->left);
if(p->right) Enqueue(Q,p->right);
}
}
第k层的层序遍历的递归
void travelk(Bitree T,int k)//第k层的层序遍历
{
if(T==NULL||k<1) return;
if(k==1) printf("%c ",T->data);
else
{
travelk(T->left,k-1);
travelk(T->right,k-1);
}
}
第k层的层序遍历
void travelk_s(Bitree T,int k)//第k层的层序遍历
{
if(T==NULL||k<1) return;
squeue Q;
initsqueue(Q);
int level=1,levelnum;
Enqueue(Q,T);
while(Q.front!=Q.rear)
{
if(level==k) break;
levelnum=(Q.rear-Q.front+100)%100;
int n=0;
while(n<levelnum)
{
Bitree e;
Dequeue(Q,e);
if(e->left) Enqueue(Q,e->left);
if(e->right) Enqueue(Q,e->right);
n++;
}
level++;
}
while(Q.front!=Q.rear)
{
Bitree t;
Dequeue(Q,t);
printf("%c ",t->data);
}
}
判断是否为完全二叉树(两种方式)
int absolutetravel(Bitree &T)//无论出队节点有没有孩子,都将孩子入队(空指针作为判断标志)
{
squeue Q;
initsqueue(Q);
Bitree p=T;
if(T) Enqueue(Q,T);
while(Q.front!=Q.rear)
{
Dequeue(Q,p);
if(p)
{
Enqueue(Q,p->left);
Enqueue(Q,p->right);
}
else//此时出队元素为空指针,则后面的应该都为空指针
{
while(Q.front!=Q.rear)
{
Dequeue(Q,p);
if(p) return 0;
}
return 1;
}
}
}
int absolutetravel_s(Bitree T)//判断是否为完全二叉树,队中没有空指针
{
int tag=1;
squeue Q;
initsqueue(Q);
Bitree p=T;
if(T) Enqueue(Q,T);
while(Q.front!=Q.rear&&tag)
{
Dequeue(Q,p);
if(p->left)
{
Enqueue(Q,p->left);
if(p->right) Enqueue(Q,p->right);//当一个节点有左孩子和右孩子,继续
else tag=0;//当一个节点只有左孩子,给出停止标志
}
else
{
tag=0;//一个节点没有左孩子,给出停止标志
if(p->right) return 0;//一个节点没有左孩子,但有右孩子,必定不是完全二叉树
}
}
while(Q.front!=Q.rear)
{
Dequeue(Q,p);//此时队中存放的都不应该有左孩子和右孩子,说明为完全二叉树
if(p->left||p->right) return 0;//若出现,则不是
}
return 1;
}