![二叉链表 二叉链表](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![二叉链表 二叉链表](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![二叉链表 二叉链表](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![二叉链表 二叉链表](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![二叉链表 二叉链表](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![二叉链表 二叉链表](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
![二叉链表 二叉链表](https://i-blog.csdnimg.cn/blog_migrate/a4c26d1e5885305701be709a3d33442f.gif)
“a.h”
#include
#include
#include
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OK 1
typedef int Status;
#define INT
#ifdef INT
typedef int ElemType;
ElemType Nil=0;
#endif
#ifdef CHAR
typedef char ElemType;
ElemType Nil=' ';
#endif
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
“b.h”
Status InitTree(BiTree *T)
{
*T=NULL;
return OK;
}
void DestroyTree(BiTree *T)
{
if(*T){
if((*T)->lchild)
DestroyTree(&(*T)->lchild); //递归删除每一个结点
if((*T)->rchild)
DestroyTree(&(*T)->rchild);
free(*T);
*T=NULL;
}
}
void CreateTree(BiTree *T)//按先序次序建立二叉树
{
ElemType ch;
#ifdef CHAR //结点区分字符和整形
scanf("%c",&ch);
#endif
#ifdef INT
scanf("%d",&ch);
#endif
if(ch==Nil)
*T=NULL;
else{
*T=(BiTree)malloc(sizeof(BiTNode));
if(!*T)
exit(0);
(*T)->data=ch;
CreateTree(&(*T)->lchild); //递归创建
CreateTree(&(*T)->rchild);
}
}
Status EmptyTree(BiTree T)
{
if(!T)
return TRUE;
else
return FALSE;
}
#define ClearTree DestroyTree //性质相同
int DepthTree(BiTree T) //求树的深度,递归
{
int i,j;
if(!T)
return 0;
if(T->lchild)
i=DepthTree(T->lchild);
else
i=0;
if(T->rchild)
j=DepthTree(T->rchild);
else
j=0;
return i>j?i+1:j+1; //深度即最大深度所以要比较左右子树的深度,并加1递归
}
ElemType RootTree(BiTree T) //求根
{
if(EmptyTree(T))
exit(0);
else
return T->data;
}
Status Visit(BiTNode p)
{
#ifdef INT
if(printf(" %d ",p.data)!=EOF)
return OK;
#endif
#ifdef CHAR
if(printf(" %c ",p.data)!=EOF)
return OK;
#endif
return ERROR;
}
void PreTraverse(BiTree T)//先序遍历
{
if(T){
Visit(*T);
PreTraverse(T->lchild);
PreTraverse(T->rchild);
}
}
void PostTraverse(BiTree T)//后序遍历
{
if(T){
PostTraverse(T->lchild);
PostTraverse(T->rchild);
Visit(*T);
}
}
void InTraverse(BiTree T)//中序遍历
{
if(T){
InTraverse(T->lchild);
Visit(*T);
InTraverse(T->rchild);
}
}
typedef BiTree QElemType;
#include"a-queue.h"
#include"b-queue.h"
ElemType Parent(BiTree T,ElemType e) //找到e的双亲,使用队列
{
LinkQueue Q;
QElemType q;
if(T){
InitQueue(&Q);
EnQueue(&Q,T);
while(!QueueEmpty(Q)){
DeQueue(&Q,&q);
if(q->lchild->data==e||q->rchild->data==e) //找出孩子结点为e的然后返回该结点
return q->data;
else{
if(q->lchild)
EnQueue(&Q,q->lchild); //对于每一个结点先进队列,然后取出看是否符合条件
if(q->rchild)
EnQueue(&Q,q->rchild);
}
}
}
return Nil; //当所有的节点都找过之后没有找到
}
BiTree Point(BiTree T,ElemType e) //返回该结点指针
{
LinkQueue Q;
QElemType q;
if(T){
InitQueue(&Q);
EnQueue(&Q,T);
while(!QueueEmpty(Q)){
DeQueue(&Q,&q);
if(q->data==e) //找出孩子结点为e的然后返回该结点
return q;
else{
if(q->lchild)
EnQueue(&Q,q->lchild); //对于每一个结点先进队列,然后取出看是否符合条件
if(q->rchild)
EnQueue(&Q,q->rchild);
}
}
}
return NULL;
}
ElemType LeftChild(BiTree T,ElemType e) //找到e的左孩子
{
BiTree b;
if(T){
b=Point(T,e);
if(b&&b->lchild)
return b->lchild->data;
}
return Nil;
}
ElemType RightChild(BiTree T,ElemType e) //找到e的左孩子
{
BiTree b;
if(T){
b=Point(T,e);
if(b&&b->rchild)
return b->rchild->data;
}
return Nil;
}
ElemType LeftSibing(BiTree T,ElemType e) //找出e的左兄弟
{
ElemType a;
BiTree b;
if(T){
a=Parent(T,e); //a为双亲
b=Point(T,a);
if(b->lchild&&b->rchild&&b->rchild->data==e)
return b->lchild->data;
}
return Nil;
}
ElemType RightSibing(BiTree T,ElemType e) //找出e的右兄弟
{
ElemType a;
BiTree b;
if(T){
a=Parent(T,e); //a为双亲
b=Point(T,a);
if(b->lchild&&b->rchild&&b->lchild->data==e)
return b->rchild->data;
}
return Nil;
}
Status InsertChild(BiTree p,int LR,BiTree c)//根据ch将c(右子树为空)插入到p的左或者右子树,原有p的左右子树成为c的右子树
{
if(p){
if(LR==0){ //ch为0插入到左
c->rchild=p->lchild;
p->lchild=c;
}
else{
c->rchild=p->rchild;
p->rchild=c;
}
return OK;
}
return ERROR;
}
Status DeleteChild(BiTree T,int LR) //将子树T根据LR删除
{
if(T){
if(LR==0){
DestroyTree(&(T->lchild));
T->lchild=NULL;
}
else{
DestroyTree(&(T->rchild));
T->rchild=NULL;
}
return OK;
}
return ERROR;
}
typedef BiTree SElemType;
#include"a-stack.h"
#include"b-stack.h"
Status InorderTraverse_1(BiTree T)//利用栈进行中序遍历
{
SqStack s;
SElemType e;
InitStack(&s);
while(T||!StackEmpty(s)){
if(T){
Push(&s,T);
T=T->lchild; //先进入最左结点路过的所有左结点压栈
}
else{
Pop(&s,&e); //最左的结点退栈
Visit(*e); //调用Visit
T=e->rchild; //进入最左的右子树,若无则继续退栈到双亲,然后再进入右孩子
}
}
printf("\n");
return OK;
}
Status InorderTraverse_2(BiTree T)//利用栈进行中序遍历
{
SqStack s;
BiTree e;
InitStack(&s);
Push(&s,T);
while(!StackEmpty(s)){
while(GetTop(s,&e)&&e)
Push(&s,e->lchild);
Pop(&s,&e); //退掉左空指针
if(!StackEmpty(s)){ //向右走一步
Pop(&s,&e);
Visit(*e);
Push(&s,e->rchild);
}
}
printf("\n");
return OK;
}
Status LevelOrderTraverse(BiTree T)//利用队列层序遍历
{
LinkQueue Q;
BiTree q;
if(T){
InitQueue(&Q);
EnQueue(&Q,T);
while(!QueueEmpty(Q)){
DeQueue(&Q,&q);
if(q){ //???不太懂为什么这边q可能会出现空指针,可能队列出现问题
Visit(*q);
if(q->lchild!=NULL) //每次退出队后的结点调用Visit后都将他的孩子压入队列尾
EnQueue(&Q,q->lchild);
if(T->rchild!=NULL)
EnQueue(&Q,q->rchild);
}
}
}
printf("\n");
return OK;
}
“a-stack.h”
#define STACK_INIT_SIZE 10
#define STACKINCREMENT 2
typedef struct SqStack
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
“b-stack.h”
Status InitStack(SqStack *S)
{
(*S).base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!(*S).base)
exit(0);
(*S).top=(*S).base;
(*S).stacksize=STACK_INIT_SIZE;
return OK;
}
Status DestroyStack(SqStack *S)
{
free((*S).base);
(*S).base=NULL;
(*S).top=NULL;
(*S).stacksize=0;
return OK;
}
Status ClearStack(SqStack *S)
{
(*S).top=(*S).base;
return OK;
}
Status StackEmpty(SqStack S)
{
if(S.top==S.base)
return TRUE;
else
return FALSE;
}
int StackLength(SqStack S)
{
return S.top-S.base;
}
Status GetTop(SqStack S,SElemType *e)
{
if(S.top>S.base)
{
*e=*(S.top-1);
return OK;
}
else
return ERROR;
}
Status Push(SqStack *S,SElemType e)
{
if((*S).top-(*S).base>=(*S).stacksize)
{
(*S).base=(SElemType *)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!(*S).base)
exit(0);
(*S).top=(*S).base+(*S).stacksize;
(*S).stacksize+=STACKINCREMENT;
}
*((*S).top)++=e;
return OK;
}
Status Pop(SqStack *S,SElemType *e)
{
if((*S).top==(*S).base)
return ERROR;
*e=*--(*S).top;
return OK;
}
Status StackTraverse(SqStack S,Status(*visit)(SElemType))
{
while(S.top>S.base)
visit(*S.base++);
printf("\n");
return OK;
}
“a-queue.h”
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front,rear;
}LinkQueue;
“b-queue.h”
Status InitQueue(LinkQueue *Q)
{
(*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode));
if(!(*Q).front)
exit(0);
(*Q).front->next=NULL;
return OK;
}
Status DestroyQueue(LinkQueue *Q)
{
while((*Q).front)
{
(*Q).rear=(*Q).front->next;
free((*Q).front);
(*Q).front=(*Q).rear;
}
return OK;
}
Status ClearQueue(LinkQueue *Q)
{
QueuePtr p,q;
(*Q).rear=(*Q).front;
p=(*Q).front->next;
(*Q).front->next=NULL;
while(p)
{
q=p;
p=p->next;
free(q);
}
return OK;
}
Status QueueEmpty(LinkQueue Q)
{
if(Q.front==Q.rear)
return TRUE;
else
return FALSE;
}
int QueueLength(LinkQueue Q)
{
int i=0;
QueuePtr p;
p=Q.front;
while(Q.rear!=p)
{
i++;
p=p->next;
}
return i;
}
Status GetHead_Q(LinkQueue Q,QElemType *e)
{
QueuePtr p;
if(Q.front==Q.rear)
return ERROR;
p=Q.front->next;
*e=p->data;
return OK;
}
Status EnQueue(LinkQueue *Q,QElemType e)
{
QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
if(!p)
exit(0);
p->data=e;
p->next=NULL;
(*Q).rear->next=p;
(*Q).rear=p;
return OK;
}
Status DeQueue(LinkQueue *Q,QElemType *e)
{
QueuePtr p;
if((*Q).front==(*Q).rear)
return ERROR;
p=(*Q).front->next;
*e=p->data;
(*Q).front->next=p->next;
if((*Q).rear==p)
(*Q).rear=(*Q).front;
free(p);
return OK;
}
Status QueueTraverse(LinkQueue Q,Status(*Vi)(QElemType))
{
QueuePtr p;
p=Q.front->next;
while(p)
{
Vi(p->data);
p=p->next;
}
printf("\n");
return OK;
}
“main.h”
#include"a.h"
#include"b.h"
int main()
{
BiTree T,t;
InitTree(&T);
CreateTree(&T);
printf("树的深度:%d\n",DepthTree(T));
PreTraverse(T);
printf("\n");
PostTraverse(T);
printf("\n");
InTraverse(T);
printf("\n");
InorderTraverse_1(T);
InorderTraverse_2(T);
LevelOrderTraverse(T);
printf("-----%d\n",Parent(T,5));
printf("-----%d---%d--\n",LeftChild(T,3),RightChild(T,3));
printf("-----%d---%d--\n",LeftSibing(T,5),RightSibing(T,4));
t=T->lchild->lchild;
printf("构造树t右子树为空\n");
CreateTree(&t);
InsertChild(T->lchild->lchild,1,t);
LevelOrderTraverse(T);
DeleteChild(T->rchild,1);
LevelOrderTraverse(T);
return 0;
}