赞
踩
(1)在构造二叉树时,采用的是以递归的方式进行构造,递归构造二叉树的算法如下所示:
#include<stdio.h> #include<stdlib.h> typedef int ElemType; typedef int Status; typedef struct BiTNode { ElemType data; struct BiTNode *lchild; struct BiTNode *rchild; }BiTNode,*BiTree; Status InputTree(BiTree &T) { ElemType num; scanf("%d",&num); if(num==0) T=NULL; else { T=(BiTNode *)malloc(sizeof(BiTNode)); if(!T) { printf("二叉树构造失败!\n"); exit(0); } T->data=num; InputTree(T->lchild); InputTree(T->rchild); } return 0; } Status FistTree(BiTree &T) { if(T) { printf("%d ",T->data); FistTree(T->lchild); FistTree(T->rchild); } else T=NULL; return 0; } int main() { BiTree T; printf("输入数据进入二叉树(输入数字0子树根为空):\n"); InputTree(T); printf("遍历二叉树中所有数据\n"); FistTree(T); printf("\n"); return 0; }
构造一颗二叉树的运行截图如下所示:
(2)实现二叉树的各种基本运算:查找节点、返回父节点、子节点、高度的算法如下所示:
#include<stdio.h> #include<stdlib.h> typedef int ElemType; typedef int Status; typedef struct BiTNode { ElemType data; struct BiTNode *lchild; struct BiTNode *rchild; }BiTNode,*BiTree; Status CreateTree(BiTree &T) { int number; scanf("%d",&number); if(number=='\0') { T=NULL; } else { T=(BiTNode *)malloc(sizeof(BiTNode)); if(!T) { printf("二叉链表创建失败!"); exit(0); } T->data=number; CreateTree(T->lchild); CreateTree(T->rchild); } return 0; } Status FindTree(BiTree &T,ElemType e) { BiTree p=T; if(p==NULL) return -1; if(p->data==e) { printf("节点已找到:%d\n",p->data); return 0; } if(!FindTree(p->lchild,e)) FindTree(p->rchild,e); if(!FindTree(p->rchild,e)) FindTree(p->lchild,e); } Status DethTree(BiTree &T) { int left=0; int right=0; if(T) { left+=1+DethTree(T->lchild); right+=1+DethTree(T->rchild); return left>right?left:right; } else return 0; } Status printTree(BiTree &T,ElemType e) { BiTree p=T; BiTree q=NULL; if(p==NULL) return -1; else { if(p->data==e) { printf("该节点为:%d\n",p->data); if(p->lchild!=NULL) { if(p->lchild->data!=0) { printf("该节点的左孩子为:%d\n",p->lchild->data); } } if(p->rchild!=NULL) { if(p->rchild->data!=0) { printf("该节点的右孩子为:%d\n",p->rchild->data); } } } } printTree(p->lchild,e); printTree(p->rchild,e); } int main() { int num1,num2; BiTree T; printf("输入数据进入二叉树(输入数字0子树根为空):\n"); CreateTree(T); printf("输入你要查找的节点:"); scanf("%d",&num1); FindTree(T,num1); printf("输入你要查找的节点,并返回其子节点:"); scanf("%d",&num2); printTree(T,num2); printf("树的深度:"); printf("%d",DethTree(T)); printf("\n"); return 0; }
运行结果如下图所示:
二叉树的遍历是指按某条搜索路径访问树中每个结点,使得每个结点均被访问一次,而且仅被访问一次。
二叉树是一种非线性结构,每个结点都可能有两颗子树,需要寻找一种规律,以便于二叉树上的结点能排列在一个线性队列上,进而便于遍历。
由二叉树的递归定义可知,遍历一颗二叉树便要决定对根结点 N,左子树 L,右子树 R 的访问顺序。常见的遍历顺序有:先序(NLR)、中序(LNR)、后序(LRN)三种遍历算法。其中“序”指的是根结点在何时被访问。
先序遍历的操作过程如下:
若二叉树为空,不进行遍历;否则:
(1)访问根结点;
(2)先遍历左子树;
(3)先遍历右子树;
对应的递归算法如下所示:
void PreOrder(BiTree T){
if(T!=null){
visit(T); //访问根结点
PreOrder(T->lchild); //访问左子树
PreOrder(T->rchild); //访问右子树
}
}
下图所示的二叉树,先序遍历所得结点序列如下:
中序遍历的操作过程如下:
若二叉树为空,不进行遍历;否则:
(1)先遍历左子树;
(2)访问根结点;
(3)先遍历右子树;
对应的递归算法如下所示:
void PreOrder(BiTree T){
if(T!=null){
PreOrder(T->lchild); //访问左子树
visit(T); //访问根结点
PreOrder(T->rchild); //访问右子树
}
}
下图所示的二叉树,中序遍历所得结点序列如下:
后序遍历的操作过程如下:
若二叉树为空,不进行遍历;否则:
(1)先遍历左子树;
(2)先遍历右子树;
(3)访问根结点;
对应的递归算法如下所示:
void PreOrder(BiTree T){
if(T!=null){
PreOrder(T->lchild); //访问左子树
PreOrder(T->rchild); //访问右子树
visit(T); //访问根结点
}
}
下图所示的二叉树,后序遍历所得结点序列如下:
注意:上述三种遍历算法中,递归遍历左、右子树的顺序都是固定的,只是访问根结点的顺序不同。不管采用哪种遍历算法,每个结点访问一次且仅被访问一次,故时间复杂度都为 O(n)。
在使用层次算法遍历二叉树时,需要借助一个队列。层次遍历的操作流程如下:
(1)先将二叉树根结点入队,然后出队,访问出队结点,若它由左子树,则将左子树根结点入队;
(2)若它有右子树,则将右子树根结点入队,然后出队,访问出队结点;
(3)如此重复上述两步,直至队列为空。
二叉树的层次遍历算法如下:
void LevelOrder(BiTree T){
InitQueue(Q); //初始胡辅助队列
BiTree p;
EnQueue(Q,T); //将根结点入队
while(!isEmpty(Q)){ //队列不空则循环
DeQueue(Q,p); //队头结点出队
visit(p); //访问出队结点
if(p->lchild!=null)
EnQueue(Q,p->lchild); //左子树不空,则左子树根结点入队
if(p->rchild!=null)
EnQueue(Q,p->rchild); //右子树不空,则右子树根结点入队
}
}
层次算法操作示意图如下图所示:
(1)由二叉树的先序序列和中序序列可以唯一的确定一颗二叉树。例如:已知一颗二叉树的先序遍历结果为:ABCDEF,中序遍历结果为:CBAEDF,则由先序和中序序列构造的二叉树如下图所示:
(2)由二叉树的后序序列和中序序列可以唯一确定一颗二叉树。例如:已知一颗二叉树的后序遍历结果为:DABEC,中序遍历结果为:DEBAC,则由后序和中序序列构造的二叉树如下图所示:
(3)由二叉树的层次序列和中序序列可以唯一确定一颗二叉树。例如:已知一颗二叉树的层次遍历结果为:ABCDEF,中序遍历结果为:BADCFE,则由层次和中序序列构造的二叉树如下图所示:
注意:若只知道二叉树的先序遍历和后序遍历,无法唯一确定一颗二叉树。
(1)递归实现:实现二叉树的遍历的先序算法、中序算法和后序算法示例代码如下所示:
#include<stdio.h> #include<stdlib.h> typedef int ElemType; typedef int Status; typedef struct BiTNode { ElemType data; struct BiTNode *lchild; struct BiTNode *rchild; }BiTNode,*BiTree; Status CreateTree(BiTree &T) { int number; scanf("%d",&number); if(number=='\0') { T=NULL; } else { T=(BiTNode *)malloc(sizeof(BiTNode)); if(!T) { printf("二叉链表创建失败!"); exit(0); } T->data=number; CreateTree(T->lchild); CreateTree(T->rchild); } return 0; } Status FirstTree(BiTree &T) { if(T) { printf("%d ",T->data); FirstTree(T->lchild); FirstTree(T->rchild); } else return 0; } Status SecondTree(BiTree &T) { if(T) { SecondTree(T->lchild); printf("%d ",T->data); SecondTree(T->rchild); } else return 0; } Status FinalTree(BiTree &T) { if(T) { FinalTree(T->lchild); FinalTree(T->rchild); printf("%d ",T->data); } else return 0; } Status DethTree(BiTree &T) { int left=0; int right=0; if(T) { left+=1+DethTree(T->lchild); right+=1+DethTree(T->rchild); return left>right?left:right; } else return 0; } int main() { BiTree T; printf("输入数据进入二叉树(输入数字0子树根为空):\n"); CreateTree(T); printf("先序遍历:"); FirstTree(T); printf("\n"); printf("中序遍历:"); SecondTree(T); printf("\n"); printf("后序遍历:"); FinalTree(T); printf("\n"); printf("树的深度:"); printf("%d",DethTree(T)); printf("\n"); return 0; }
三种遍历算法遍历二叉树的运行截图如下所示:
(2)非递归实现:实现二叉树的遍历的先序算法、中序算法和后序算法示例代码如下所示:
#include<stdio.h> #include<stdlib.h> #define STACK_INIT_SIZE 100 #define STACKINCERMENT 10 typedef int ElemType; typedef int Status; typedef struct BiTNode { ElemType data; struct BiTNode *lchild; struct BiTNode *rchild; }BiTNode,*BiTree; typedef BiTree SElemType; typedef struct { SElemType *base; SElemType *top; int stacksize; }SqStack; Status InitStack(SqStack &S)//创建栈 { S.base=(SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); if(!S.base) exit(-1); S.top=S.base; S.stacksize=STACK_INIT_SIZE; return 0; } Status push(SqStack &S,SElemType e)//入栈 { if(S.top-S.base>=S.stacksize) { S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCERMENT) * sizeof(SElemType)); if(!S.base) exit(0); S.top=S.base+S.stacksize; S.stacksize+=STACKINCERMENT; } *S.top++=e; return 0; } Status gettop(SqStack &S,SElemType &e)//获取栈顶元素 { if(S.top==S.base) return -1; e=*(S.top-1); return 0; } Status pop(SqStack &S,SElemType &e)//栈顶元素出栈 { if(S.top==S.base) return -1; e=*--S.top; return 0; } Status StackEmpty(SqStack &S)//判断栈是否空 { if(S.base==S.top) return true; else return false; } Status CreateTree(BiTree &T) { int num; scanf("%d",&num); if(num=='\0') T=NULL; else { T=(struct BiTNode *)malloc(sizeof(BiTNode)); if(!T) exit(-1); T->data=num; CreateTree(T->lchild); CreateTree(T->rchild); } return 0; } Status FistTree(BiTree &T)//先序遍历 { SqStack S; BiTree p=T; InitStack(S); while(p!='\0'||!StackEmpty(S)) { if(p!='\0') { push(S,p);//入栈 printf("%d ",p->data); p=p->lchild; } else { pop(S,p);//栈顶元素出栈 p=p->rchild; } } return 0; } Status MiddleTree(BiTree &T)//中序遍历 { SqStack S; BiTree p=T; InitStack(S); while(p!='\0'||!StackEmpty(S)) { if(p!='\0') { push(S,p); p=p->lchild; } else { pop(S,p); printf("%d ",p->data); p=p->rchild; } } return 0; } Status FinalTree(BiTree &T)//后序遍历 { SqStack S; InitStack(S); BiTree p=T; BiTree q; push(S,p); while(!p||!StackEmpty(S)) { gettop(S,p); if((p->lchild==NULL&&p->rchild==NULL)||(q==p->lchild||q==p->rchild)) { printf("%d ",p->data); pop(S,p); q=p; } else { if(p->rchild!=NULL) push(S,p->rchild); if(p->lchild!=NULL) push(S,p->lchild); } } return 0; } Status DethTree(BiTree &T)//树的深度 { int left=0; int right=0; if(T) { left+=1+DethTree(T->lchild); right+=1+DethTree(T->rchild); return left>right?left:right; } else return 0; } int main() { BiTree T; printf("二叉树的创建(输入0时子树为空):\n"); CreateTree(T); printf("二叉树非递归先序遍历:\n"); FistTree(T); printf("\n"); printf("二叉树非递归中序遍历:\n"); MiddleTree(T); printf("\n"); printf("二叉树非递归后续遍历:\n"); FinalTree(T); printf("\n"); printf("二叉树的深度:%d\n",DethTree(T)); return 0; }
运行结果如下图所示:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。