二叉树的练习

二叉树的遍历

#include <stdbool.h>
#include <stdio.h>  
#include <malloc.h>

typedef struct BiTNode{
  int data;
	struct BiTNode *lchild,*rchild;  
  int ltag,rtag;
}BitNode,*BitTree;

//为了能够实现层次遍历所准备的队列
typedef struct Queue{
 	BitNode * data[20];
  int size;
  int front,rear;
}Que,*Queue;

//函数声明
void InitQueue(Queue*);
bool EnQueue(Queue,BitNode*);
bool OutQueue(Queue,BitNode**);
bool Empty(Queue );
void MyVisit(BitNode * node);
void creatNodeGen(BitTree *ptree,int data);
void PreOrder(BitTree tree);
bool TreeInsert(BitNode *father,int k,int data);
void InOrder(BitTree);
void PostOrder(BitTree);
void LevelOrder(BitTree);
void print_Queue(Queue);
void InThread(BitTree);
void InThreadVisit(BitNode *);

//全局变量
BitNode *pre=NULL;  					//线索化时的前驱指针

//初始化队列
void InitQueue(Queue * Q){
  Queue p=(Queue)malloc(sizeof(Que));
	p->size=0;
  p->front=0;
  p->rear=0;
  *Q=p;
}
//入队
bool EnQueue(Queue Q,BitNode * pnode){
  if(Q->size==20)return false;
  if(pnode==NULL)return false;
  Q->data[Q->front]=pnode;
  Q->front=(Q->front+1)%20;
  Q->size++;
  return true;
}
//出队
bool OutQueue(Queue Q,BitNode **pnode){
	if(Empty(Q))return false; 
	*pnode=Q->data[Q->rear];
  Q->rear=(Q->rear+1)%20;
  Q->size--;
  return true;
}
//得到是否为空
bool Empty(Queue Q){
  if(Q->size==0)return true;
  return false;
}

/*void print_Queue(Queue Q){
  int size=Q->size;
  int i=Q->rear;
	printf("队列的size为:%d \n",size);
  printf("队列头:%d 队列尾:%d \n",Q->front,Q->rear);
 	while (size--){
    printf("从 尾 数的%d个元素为%x\n",i,(int)Q->data[i]);
  	i=(i+1)%20;
  }
}*/
  
  
//创建根结点
void creatNodeGen(BitTree* ptree,int data){
	BitNode * q = (BitNode *) malloc (sizeof(BitNode));
  q->lchild=q->rchild=NULL;
  q->ltag=q->rtag=0;
	q->data=data;
  *ptree=q;
}


//插入节点,输入值分别是 要插入的节点的父节点的地址、插入左1右2 data
bool TreeInsert(BitNode *father,int k,int data){
	if(father==NULL||(father->lchild!=NULL&&k==1)||(father->rchild!=NULL&&k==2))return false;	
  BitNode * q = (BitNode *)malloc(sizeof(BitNode));
  q->rchild=q->lchild=NULL;
  q->ltag=q->rtag=0;
  q->data=data;
  if(k==1)father->lchild=q;
  else father->rchild=q;
	return true;
}
//从根结点先序遍历树 传入指向根节点的指针
void PreOrder(BitTree tree){
  if(tree==NULL)return;
  MyVisit(tree);
  PreOrder(tree->lchild);
  PreOrder(tree->rchild);
}

//从根结点中序遍历二叉树
void InOrder(BitTree tree){
	if(tree!=NULL){
		InOrder(tree->lchild);
    MyVisit(tree);
    InOrder(tree->rchild);
  }
}

//从根结点后续遍历二叉树
void PostOrder(BitTree tree){
  if(tree!=NULL){
    PostOrder(tree->lchild);
    PostOrder(tree->rchild);
    MyVisit(tree);
  }
}
//利用队列 层次遍历二叉树
void LevelOrder(BitTree tree){
  
	Queue Q;
  BitNode *q;
  
  InitQueue(&Q);
  
  EnQueue(Q,tree);
  while(OutQueue(Q,&q)){
  	EnQueue(Q,q->lchild);
    EnQueue(Q,q->rchild);
    MyVisit(q);
  }  
}
//访问某一地址的节点
void MyVisit(BitNode * node){
	printf("%d\n",node->data); 
}

//二叉树的 中序线索化  //其实就是中序遍历,但访问时使用下面的InThreadVisit函数完成对左右空孩子指针的线索化
void InThread(BitTree tree){
	if(tree!=NULL){
    InThread(tree->lchild);
    InThreadVisit(tree);
    InThread(tree->rchild);
	}
}

//中序线索化时使用的访问函数 (可以与上面的InThread函数合为一个函数,但不易逐行理解)
void InThreadVisit(BitNode * node){
  if(node->lchild==NULL){
    node->lchild=pre;
    node->ltag=1;
  }
  if(pre!=NULL&&pre->rchild==NULL){
    pre->rchild=node;
    pre->rtag=1;
  }
  pre=node;
}


int main(){
  

 	BitTree tree=NULL;
  
  creatNodeGen(&tree,3);
  
  TreeInsert(tree,1,5);
  TreeInsert(tree,2,6);
  TreeInsert(tree->lchild,1,2);
  TreeInsert(tree->lchild,2,4);
  TreeInsert(tree->lchild->lchild,1,1);
  TreeInsert(tree->rchild,2,7);
  TreeInsert(tree->rchild->rchild,1,8);
  
  PreOrder(tree);
  printf("以上是先序遍历\n");
  
  InOrder(tree);          
  printf("以上是中序遍历\n");
  
  PostOrder(tree);
  printf("以上是后序遍历\n");
  
  LevelOrder(tree);
  printf("以上是层次遍历\n");
  
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值