二叉树的相关操作,先、中、层次遍历二叉树

基于链式存储的二叉树的操作

1:遍历:先序(根-左-右) 中序(左-根-右),后序(左-右-根)
先序遍历:第一个访问的结点:根结点;最后一个访问的结点:最右下角那个结点
中序和后序开头第一个访问的结点:最左下角那个结点
后序:最后一个:根结点
2:后序遍历序列和层次遍历序列相同的非空二叉树是:只有根节点的树
3:一棵有124个叶子结点的完全二叉树最多有(248)个结点
解:某一层次的叶子总数公式:n=2^(k-1) 得出k=8层;
从1层到i层的结点总数公式:n=2^i-1; 故而1-7层总数=(128)-1=127
而第7层的结点数2^6=64; 设最后一层(第8层)的结点数为n8;n8为偶数 124=n8+64-n/2 得n8=120; n8为奇数:124=n8+64-(n+1)/2 得n8=121
故而总结点数=121+127=248
4:具有1000个结点的完全二叉树次底层的叶子结点数:(11
解:2^10-1=1023 ,1-9层的结点总数:2的9次方-1=511;故而有10层 1000-511=489,第10层总数=489,第9层有孩子的结点数:(489+1)/2=245,第9层总结点数2的8次方=256 故而9层的叶子结点=256-245=11
5:先序和后序正好相反的非空二叉树是:(左单支和右单支树)
6:先序和中序相同的树的特征是:各结点均无左孩子
7:任何一棵二叉树至少有一个度为2的结点(X

typedef int TElemtype;
typedef char Elemtype; 
#define Increament  100
#define Status int 
#define Error  -1
#define ok     0 
#define True   1
#define BiInit_Size  100
#define MaxSize 100//队列用 
//#define Link    0
//#define Thread  1 

typedef struct BiTNode{//二叉树的二叉链表 
	TElemtype data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
typedef BiTree BElemtype;

//-------树所用队列-----------// 
typedef struct QDataNode{
	BiTNode data;
}QDataNode,*BiQDataLink;
typedef struct BiHNode{
	QDataNode *front;
	QDataNode *rear;
}BiHNode,*BiQLink; 

//-------树所用队列-----------// 
//----------------------先序遍历式递归创建二叉树---------------------//
void CCreateBiTree(BiTree *T){
      TElmetype ch;
      printf("输入树之元素");
      scanf("%d",&ch);
      if(ch==0) *T=NULL;
      else{
      *T=(BiTNode *)malloc(sizeof(BiTNode));
      (*T)->data=ch;
      CCreateBiTree(&(*T)->lchild);
      CCreateBiTree(&(*T)->lchild));
      }
}

输入 1 2 3 0 0 4 5 0 6 0 0 7 0 0 0
在这里插入图片描述

//-----------------------------先序遍历--------------//
Status PreVisitBiTree(BiTNode *T){
  if(T!=NULL){
  	printf("%d ",T->data);//根
  	PreVisitBiTree(T->lchild);//左
    PreVisitBiTree(T->rchild);//右
  }
}
//--------------------------------“后序”求树深--------//
int depthval=0,depthleft=0,depthright=0;
Status LastTraverseBiDepth(BiTNode *T){
      if(!T) return 0;//空树
      if (!T->lchild && !T->rchild) return 1;//树根
      
      depthleft=LastTraverseBiDepth(T->lchild);//左
      depthright=LastTraverseBiDepth(T->rchild);//右
      depthval=1+(depthleft>=depthrihgt?depthleft:depthright);//总
      return depthval;
}
//---------------------------------叶子结点数-------//
//思想:其左子树与右子树皆空 则为叶子结点
int count=0;
Status Allleftcount(BiTree T){
       if(T){
       if((!T->lchild) && (!T->rchild)) count++;
       	Allleafcount(T->lchild);
	   	Allleafcount(T->rchild);
      }
}

//----------------------------层次遍历---------------------//
Status Init_BiQueue(BiQLink *Q){
	(*Q)=(BiQLink)malloc(sizeof(BiHNode));
	(*Q)->rear=(*Q)->front=(BiQDataLink)malloc(sizeof(QDataNode)*(MaxSize));
	if(!(*Q)->front) return Error;
	return ok; 
}
Status EnBiQueue(BiQLink *Q,BiTree T){
	if((*Q)->rear-(*Q)->front==MaxSize-1) return Error;//因为第一个结点不用
	(*Q)->rear++;
	(*Q)->rear->data=*T;
	return ok; 
}
Status DeBiQueue(BiQLink *Q,BiTree *T){
	if((*Q)->front==(*Q)->rear) return Error;//大哥 不能再退了
	(*Q)->front++;
	*(*T)=(*Q)->front->data;
  	return ok; 
	
}
Status IsBiQueueEmpty(BiQLink *Q){
	if((*Q)->rear==(*Q)->front) return True;
	else return 0; 
}
//-层次遍历要利用先进先出的特性,故而选queue做辅助-----//
Status floorTraverse(BiTree T){//层次遍历
    BiQLink *Q;
    Q=(BiQLink)malloc(sizeof(BiHNode));
    Init_BiQueue(Q);	
    EnBiQueue(Q,T);//先要进一个
    	while(!IsBiQueueEmpty(Q)){
    	DeBiQueue(Q,&T);//一直出队就好了 
    	printf("<->%2d",T->data);
    	if(T->lchild!=NULL) EnBiQueue(Q,T->lchild);//其有左孩,左孩进队 
    	if(T->rchild!=NULL) EnBiQueue(Q,T->rchild);// 
		}	
}//先进-循环内出队打印

//-------------------总测试----------------------//
void BiTreetest(){
	BiTNode *T;//在其处创建的是指针 故而下面的就不需要取值符号  若是BiTNode T后面就需要指针 
//	T=(BiTNode *)malloc(sizeof(BiTNode));
	CCreateBiTree(&T);
	PreVisitBiTree(T);//此时的T已经是地址(指针)
    LastTraverseBiDepth(T); 
    Allleafcount(T);
//    f63(T,)
	printf("\二叉树树深度%d",depthval);
	printf("\n叶子节点个数:%d",count);
	printf("\n层次遍历结果为:");
	floorTraverse(T);
    return 0;
}

在这里插入图片描述

中序遍历非递归算法
要用到栈
typedef struct BiStack{
	BElemtype *top;//树指针型的指针
	BElemtype *base;
	TElemtype  stacksize;//上面宏定义有
}BiStack; 
Status InitBiStack(BiStack *s){//栈指针
       s->base=(BiStack *)malloc(BiInit_Size*sizeof(BiStack));
       if(!s->base) return Error;
       s->top=s->base;
       s->stacksize=BiInit_Size;
       return ok;
}
Status BiPush(BiStack *s,BElemtype e){//进来个树形指针
       if(s->top-s->base=s->stacksize){
         s->base=(BElemtype *)realloc(s->base,sizeof(BElemtype)*(BiInit_Size+Increament));
         s->top=s->base+s->stacksize;
         s->stacksize+=Increament;
      }
      *(s-top)=e;
      s->top++;
      return ok;
}
Status IsBiStackEmpty(BiStack *s){
      if(s->base==s->top) return 1;//确实是空
      else return 0;//不空
}
Status BiPop(BiStack *s,BElemtype *p){//退栈 指向树形指针的指针
       if(s->base==s->top) return Error;
       s->top--;
       *p=*(s->top);//*(指向树形指针的指针)=树形指针
       return ok;
}
BiTree GoFarLeft(BiTree T,BiStack *s){//走到最后一个**左结点**的函数
       if(!T) return NULL;
       while(T->lchild){
       BiPush(s,T);//若其有左子树 则当前结点T入栈
       T=T->lchild;
       }
       return T;//此时的T为最左下脚那个没有左子树的结点

}
Status InOrderBiTraverse(BiTree T){
       BiStack s;InitBiStack(&s);
       BiTree t=NULL;
       t=(BiTNode *)malloc(sizeof(BiTNode));
       t=GoFarLeft(T,&s);
       while(t){
       printf("正在遍历的元素%d",t->data);//中序遍历的打印函数在while里面
       if(t->rchild) t=GoFarLeft(t->rchild,&s);//如果该结点有右子树,则从该结点的右子树出发,走到该右子树的最左下角结点
       else if(!IsBiStackEmpty(&s)) BiPop(&s,&t);// 如果木有右子树且不空 则出栈
       else {break;}
       }
}
BiTree PreGoFarLeft(BiTree T,BiStack *s){//先序遍历的打印函数在 此函数里面
       printf("%d",T->data);
       while(T->lchild){
       BiPush(s,T);
       T=T->lchild;
       printf("%d",T->data);
       }//走到最左下角结点
       return T;

}
//-----------------------------------先序遍历非递归---------------------//
Status PreOrderTraverse(){//思想:每次都:“一有机会就向左疯狂输出”
     BiStack s;InitBiStack(&s);
     BiTree t=NULL;
     t=(BiTree)malloc(sizeof(BiTNode));
     t=GoFarLeft(T,&s);//先序和中序都要先跑到最左下角
     while(t){
      if(t->rchild) t=PreGoFarLeft(t->rchild,&s);
      else if(!IsBiStackEmpty(&s)) BiPop(&s,&t);
      else break;
     }  
}

void MyInorderTraverseTest(){
	BiTree T;//在其处创建的是指针 故而下面的就不需要取值符号  若是BiTNode T后面就需要指针 
	CCreateBiTree(&T);

	printf("-----------二叉树中序遍历非递归算法--------\n");
	InorderBiTraverse(T);
	printf("\n----------先序遍历-----------------------\n");
	PreOrderTraverse(T); 

	return ok;
}

结果如下:
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值