提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
学这些简单的知识点人就麻了。。。
一、二叉树的基本操作(数据的类型不要太乱了,不然容易混淆,血与泪的教训)
1. 二叉树的初始化
typedef struct bitnode{
elemtype data;
struct bitnode *lchild, *rchild;//只有两个度;
}bitnode,*bitree;
2.创建一个二叉树
void createbitree(bitree *t)
{
char c;
scanf("%c",&c);
if(c == '.')//.和#都可以
{
*t = NULL;
}
else
{
*t = (bitree)malloc(sizeof(bitnode));
(*t)->data = c;
createbitree(&(*t)->lchild);
createbitree(&(*t)->rchild);
}
}
3.二叉树的输出
void visit(bitree c)//
{
printf("%c",c->data);
}
4.前序遍历(只需要记住遍历是 根左右 就可以了)
void preorder(bitree t){//先序遍历;根左右
if(t)
{
visit(t);
preorder(t->lchild);
preorder(t->rchild);
}
}
5.中序遍历( 左根右 )
void inorder(bitree t){//中序遍历;左根右
if(t)
{
postorder(t->lchild);
visit(t);
postorder(t->rchild);
}
}
6.后序遍历(左右根)这三个遍历用递归的话基本上大同小异,相较非递归而言并不是我们的重点
void postorder(bitree t){//后序遍历;左右根
if(t)
{
postorder(t->lchild);
postorder(t->rchild);
visit(t);
}
}
7.前序遍历(非递归)
1.我们普通的搜索只能一直向一个方向(左或右)而栈可以保存上一个数据,从而可以回到上一个位置继续查找,进而查找另一边数 2.为什么push和pop不是一个类型的函数,我用void定义pop的时候,发现p=s->[s.top]这一步已经赋值了,但函数执行完毕的时候,p的指针就找不到位置了,为空,所以,我用了另一种方式,p的指针就不会突然找不到位置了。
void preorder2(bitree t){//先序非递归遍历(迭代法)
sqstack s;
initstack(s);
bitree p =t;
bitree a;
while(p || !stackempty(s)){
if(p)
{
visit(p);
push(s,p);
p = p->lchild;
}
else
{
a=pop(s,p);
p=a;
p = p->rchild;
}
}
}
8.中序遍历(非递归)和前序遍历差不多
void inorder2(bitree t){//中序非递归遍历(迭代法)
sqstack s;
initstack(s);
bitree p =t;
bitree a;
while(p || !stackempty(s))
{
if(p)
{
push(s,p);
p = p->lchild;
}
else
{
a=pop(s,p);
p=a;
visit(p);
p = p->rchild;
}
}
}
8.后序遍历(非递归)
这里也是一样,出栈赋值给q之后,q的指针就找不到方向了;
void postorder2(bitree t){//后序非递归遍历(迭代法)
sqstack s;
initstack(s);
bitree p = t;
bitree a;
bitree e;
bitree r=NULL;
while(p || !stackempty(s)){
if(p)
{
push(s,p);
p = p->lchild;
}
else
{
e=checktop(p,s);
p=e;
if(p->rchild && p->rchild!=r)/*后序遍历需要去先查找右子树,
所以将右子树的入栈,就有了这一步,
这里需要注意的是,因为不让指针指
向左子树的话,回到第一个push就会
导致重复入栈*/
{
p=p->rchild;
push(s,p);
p=p->lchild;
}
else
{
a=pop(s,p);
p=a;
visit(p);
r=p;/*将右子树的位置标记,就是在右边时*/
p=NULL;
}
}
}
}
8.层次遍历(非递归)需要用到队列(利用它的先进先出的原则实行层次遍历)
void levelorder(bitree t){//层次遍历
sqqueue q;
initqueue(q);
bitree p=t;
bitree a;
enqueue(q,p);
while(q.rear!=q.front)
{
a=dequeue(q,p);
p=a;
visit(p);
if(p->lchild) enqueue(q,p->lchild);
if(p->rchild) enqueue(q,p->rchild);
}
}
二、完整的代码
//输入为:AB.D…CE.F…
//12.46…3.5…
//ABC…DE…F.G…
这是三种数据输入,可以去试试哦
# include<stdio.h>
# include<stdlib.h>
# define maxsize 50
# define ok 1
# define error 0
typedef char elemtype;
typedef int status;
int cnt=0;
typedef struct bitnode{
elemtype data;
struct bitnode *lchild, *rchild;
}bitnode,*bitree;
typedef struct{
bitree data[maxsize];
int top;
int length;
int bottom;
}sqstack,*sqstackpoint;
typedef struct{
bitree data[maxsize];
int front,rear;
}sqqueue;
void createbitree(bitree *t)
{
char c;
scanf("%c",&c);
if(c == '.')
{
*t = NULL;
}
else
{
*t = (bitree)malloc(sizeof(bitnode));
(*t)->data = c;
createbitree(&(*t)->lchild);
createbitree(&(*t)->rchild);
}
}
void initstack(sqstack &s){
s.top=s.bottom=-1;
}
bool stackempty(sqstack &s){
if(s.top==-1) return ok;
else return error;
}
void visit(bitree c)
{
printf("%c",c->data);
}
void push(sqstack &s,bitree e){
if(s.top==maxsize-1) return;
else
{
s.top++;
s.data[s.top]=e;
}
}
bitree pop(sqstack &s,bitree e){
if(s.top==-1) return error;
else
{
e=s.data[s.top];
s.top--;
return e;
}
}
bitree checktop(bitree q,sqstack &s){
if(s.top==-1) return error;
q=s.data[s.top];
return q;
}
void initqueue(sqqueue &q){
q.front=q.rear=-1;
}
bool queueempty(sqqueue &q){
if(q.front==q.rear) return ok;
else return error;
}
void enqueue(sqqueue &q,bitree e){
if((q.rear+1)%maxsize==q.front) return;
if(q.rear==maxsize) q.rear=q.rear%maxsize;
q.rear++;
q.data[q.rear]=e;
}
bitree dequeue(sqqueue &q,bitree e){
if(q.rear==q.front) return error;
if(q.front==maxsize) q.front=q.front%maxsize;
q.front++;
e=q.data[q.front];
return e;
}
void inorder(bitree t){//中序遍历;左右根
if(t)
{
inorder(t->lchild);
visit(t);
inorder(t->rchild);
}
}
void preorder(bitree t){//先序遍历;根左右
if(t)
{
visit(t);
preorder(t->lchild);
preorder(t->rchild);
}
}
void postorder(bitree t){//后序遍历;左右根
if(t)
{
postorder(t->lchild);
postorder(t->rchild);
visit(t);
}
}
void inorder2(bitree t){//中序非递归遍历(迭代法)
sqstack s;
initstack(s);
bitree p =t;
bitree a;
while(p || !stackempty(s))
{
if(p)
{
push(s,p);
p = p->lchild;
}
else
{
a=pop(s,p);
p=a;
visit(p);
p = p->rchild;
}
}
}
void preorder2(bitree t){//先序非递归遍历(迭代法)
sqstack s;
initstack(s);
bitree p =t;
bitree a;
while(p || !stackempty(s)){
if(p)
{
visit(p);
push(s,p);
p = p->lchild;
}
else
{
a=pop(s,p);
p=a;
p = p->rchild;
}
}
}
void postorder2(bitree t){//后序非递归遍历(迭代法)
sqstack s;
initstack(s);
bitree p = t;
bitree a;
bitree e;
bitree r=NULL;
while(p || !stackempty(s)){
if(p)
{
push(s,p);
p = p->lchild;
}
else
{
e=checktop(p,s);
p=e;
if(p->rchild && p->rchild!=r)
{
p=p->rchild;
push(s,p);
p=p->lchild;
}
else
{
a=pop(s,p);
p=a;
visit(p);
r=p;
p=NULL;
}
}
}
}
void levelorder(bitree t){//层次遍历
sqqueue q;
initqueue(q);
bitree p=t;
bitree a;
enqueue(q,p);
while(q.rear!=q.front){
a=dequeue(q,p);
p=a;
visit(p);
if(p->lchild) enqueue(q,p->lchild);
if(p->rchild) enqueue(q,p->rchild);
}
}
//输入为:AB.D..CE.F...
//12.46...3.5..
//ABC..DE...F.G..
int main()
{
bitree t;
createbitree(&t);
printf("递归遍历:\n");
preorder(t);
printf("\n");
inorder(t);
printf("\n");
postorder(t);
printf("\n");
printf("非递归遍历:\n");
preorder2(t);
printf("\n");
inorder2(t);
printf("\n");
postorder2(t);
printf("\n");
levelorder(t);
return 0;
}
总结
再见!