1.递归进行二叉树的建立、遍历:
//#include<iostream>
//using namespace std;
#include<stdio.h>
#include<stdlib.h>
#define maxsize 100
typedef char datatype;
typedef struct BNode
{
datatype data;
struct BNode *lchild;
struct BNode *rchild;
}BNode;
int i=0;
void init(BNode *&b)
{
char ch;
// printf("请输入:\n");
/*
{
ch=scanf("%c",&ch);
getchar();
用C语言scanf进行递归建立二叉树时总是无法跳出循环 ,因为在用scanf输入时ch未接收到赋给它的值 且为防止输入回车应在scanf后加上getcharts();
}
*/
ch= getchar();
//用getchar()输入字符ch可以获取到赋给它的值且回车不会被赋给ch
// getchar();
// cin>>ch;
printf("ch:%c\n",ch);
if(ch=='#')
b=NULL;
else
{
b=(BNode *)malloc(sizeof(BNode));
// b=new BNode;
b->data=ch;
init(b->lchild);
init(b->rchild);
}
}
void print_f(BNode *b) //递归法进行先序遍历
{
if(b!=NULL)
//注意要进行判断b是否为空,因为二叉树中有节点为NULL,若不进行判断则会直接进行NULL节点的值的输出从而导致错误
{
printf("%c",b->data);
printf("(");
print_f(b->lchild);
printf(",");
print_f(b->rchild);
printf(")");
}
}
int main()
{
BNode *b;
init(b);
printf("ok!\n");
print_f(b);
return 0;
}
2.非递归进行二叉树的建立与遍历:
后序:
void postorder(BNode *b)
{
BNode *str[maxsize],*p=b;//*str[maxsize]充当顺序栈
int top=-1;
do
{
while(p!=NULL)
{
top++;
str[top]=p;
p=p->lchild;
}
BNode *r=NULL;
bool flag=true;
while(!(top==-1)&&flag)
{
p=str[top];
if(p->rchild==r)
//栈顶元素的右子树指针是刚刚处理过的元素/为NULL => 栈顶结点的右子树已被处理过
{
printf("%c",p->data);
top--;
r=p;// 令r指向刚刚处理的元素
}
else
{
p=p->rchild;
flag=false; //若栈顶元素的右子树未被处理过则 flag==false
}
}
} while(!(top==-1));
}
#include<stdio.h>
#include<stdlib.h>
#define maxsize 100
typedef char datatype;
typedef struct BNode
{
datatype data;
struct BNode *lchild;
struct BNode *rchild;
}BNode;
void init(BNode *&b,char *str) //非递归构建二叉链表 "A(B(D(,G)),C(E,F)"
{
BNode *p,*st[maxsize];
b=NULL;
int j=0,k=0,top=-1;
char ch=str[j];
while(ch!='\0')
{
printf("ch:%c\n",ch);
switch (ch)
{
case '(':
{
k=1; //用来决定ch后面的字母是左子树还是右子树
top++;
st[top]=p;
break;
}
case ')':
{
top--;
break;
}
case ',':
{
k=2;
break;
}
default:
{
p=(BNode *)malloc(sizeof(BNode));
p->data=ch;
p->lchild=p->rchild=NULL;
if(b==NULL)
b=p;
else
{
if(k==1)
{
st[top]->lchild=p;
}
else
{
st[top]->rchild=p;
}
}
}
}
j++;
ch=str[j];
}
}
void destory(BNode *&b)
{
if (b!=NULL)
{
destory(b->lchild);
destory(b->rchild);
free(b);
}
}
void preorder(BNode *b)
{
BNode *str[maxsize],*p;
int top=-1;
if(b!=NULL)
{
printf("%c",b->data);
top++;
str[top]=b;
p=b->lchild;
while(!(top==-1&p==NULL))
//top==-1&p==NULL是遍历完成的条件,缺一个就可能是遍历过程中而不是遍历结束
//eg:当遍历完根的左子树开始遍历根的右子树时:此时top==-1,栈为空,但p!=NULL
{
while(p!=NULL)
{
if(top<maxsize)
{
printf("%c",p->data);
top++;
str[top]=p;
}
else
{
printf("栈满!\n");
}
p=p->lchild;
}
p=str[top];
top--;
{
p=p->rchild;
}
}
}
}
void inorder(BNode *b)
{
BNode *str[maxsize],*p=b;
int top=-1;
while(!(top==-1&&p==NULL))
{
while(p!=NULL)
{
top++;
str[top]=p;
p=p->lchild;
}
printf("%c",str[top]->data);
p=str[top]->rchild;
top--;
}
}
int main()
{
char *str="A(B(D(,G)),C(E,F)";
BNode *b;
init(b,str);
printf("ok!\n");
// print_f(b);
preorder(b);//非递归的先序遍历
inorder(b);
destory(b);
return 0;
}
3.层次遍历:
void ALLpath(BNode *b)//层次遍历,利用队列进行
{
BNode *str[maxsize],*p;
int front=0,rear=0;
if(b!=NULL)
{
str[rear]=b;
rear=(rear+1)%maxsize;
}
else
return;
while(rear!=front)
{
p=str[front];
printf("%c",p->data);
front=(front+1)%maxsize;
if(p->lchild!=NULL)
{
str[rear]=p->lchild;
rear=(rear+1)%maxsize;
}
if(p->rchild!=NULL)
{
str[rear]=p->rchild;
rear=(rear+1)%maxsize;
}
}
}
5.插入一个节点(利用递归):
void insert(BNode *&b,char ch,char parent) //将ch插入,作为parent的左子树
{
BNode *p;
if(b->data==parent)
{
printf("b->data:%c",b->data);
if(b->lchild!=NULL)
{
p=(BNode *)malloc(sizeof(BNode));
p->data=ch;
p->lchild=b->lchild;
p->rchild=NULL;
b->lchild=p;
}
else
{
p=(BNode *)malloc(sizeof(BNode));
p->data=ch;
p->lchild=NULL;
p->rchild=NULL;
b->lchild=p;
}
return;
}
printf("%d\n",i++);
if(b->lchild!=NULL)
//注意要进行判断,必须在 b->lchild!=NULL条件下对b->lchild进行递归插入
insert(b->lchild,ch,parent);
if(b->rchild!=NULL)
insert(b->rchild,ch,parent);
}
void preorder(BNode *b) //输出二叉树
{
if(b->lchild!=NULL||b->rchild!=NULL)
{
printf("(");
if(b->lchild!=NULL)
preorder(b->lchild);
if(b->rchild!=NULL)
{
printf(",");
preorder(b->rchild);
}
printf(")");
}
}
int main()
{
BNode *b;
init(b);
preorder(b);
printf("\nOK!\n");
char K='K',D='C';
insert(b,K,D);
preorder(b);
destory(b);
return 0;
}
6.查找一个固定值的结点;求树的深度
void find(BNode *b,char ch) //查找结点
{
if(b->data==ch)
{
printf("find!!\n");
printf("b->data:%c\n",b->data);
}
else
{
if(b->lchild!=NULL)
find(b->lchild,ch);
if(b->rchild!=NULL)
find(b->rchild,ch);
}
}
int height(BNode *b) //求子树的高度,利用递归
{
int max,l,r;
if (b==NULL)
return 0;
else
{
l=height(b->lchild);
r=height(b->rchild);
if(l>r)
max=l;
else
max=r;
return max+1;
}
}
7.递归的应用:
- 找叶子结点
void Displea(BNode *b)
{
if(b->lchild==NULL&&b->rchild==NULL)
printf("%c",b->data);
else
{
if(b->lchild!=NULL)
Displea(b->lchild);
if(b->rchild!=NULL)
Displea(b->rchild);
}
}
- 找结点的层次
bool flag=false;
void level(BNode *b,char ch,int h)
{
if (b->data==ch)
{
flag=true;
printf("结点深度:%d",h);
}
else
{
if(b->lchild!=NULL)
level(b->lchild,ch,h+1);
if(flag==false&&b->rchild!=NULL)
level(b->rchild,ch,h+1);
}
}