在好例子网,分享、交流、成长!
您当前所在位置:首页C/C++ 开发实例C/C++语言基础 → 二叉树 入门级示例源码

二叉树 入门级示例源码

C/C++语言基础

下载此实例
  • 开发语言:C/C++
  • 实例大小:0.01M
  • 下载次数:12
  • 浏览次数:239
  • 发布时间:2018-05-10
  • 实例类别:C/C++语言基础
  • 发 布 人:1421096344
  • 文件格式:.cpp
  • 所需积分:2
 相关标签:

实例介绍

【实例简介】

【实例截图】

from clipboard

【核心代码】


#include<stdio.h>
#include<stdlib.h>

#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OVERFLOW -2
#define INFEASIBLE -1
#define ERROR 0
#define FALSE 0
#define TRUE 1
#define OK 1

typedef int Status;
typedef char TElemType;

//---------二叉树的二叉线索存储表示-------
typedef enum {Link, Thread}PointerTag;  //Link==0:指针,Thread==1:线索 
typedef struct BiThrNode{
	TElemType data;
	struct BiThrNode  *lchild, *rchild;    //左右孩子指针
	PointerTag   LTag,RTag;            //左右标志
}BiThrNode, *BiThrTree;


typedef BiThrTree SElemType;
//------Stack的储存结构----------
typedef struct Stack
{
    SElemType *base;       //存储空间的基址,在栈构造之前和销毁之后,base的值为NULL
    SElemType *top;          //栈顶指针
    int stacksize;             //当前已分配的存储空间,以元素为单位
} SqStack;                         //顺序栈类型

//-------Stack的函数声明---------
Status InitStack(SqStack &S)          //构造一个空栈       
{    
    S.base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));  //分配存储空间
    if(!S.base)                   
	{   printf("分配存储失败!\n");
		exit(OVERFLOW); 
	}
	S.top = S.base;                        //S为空栈,S.top=S.base等于0
    S.stacksize = STACK_INIT_SIZE;         //栈的空间初始容量值
    return OK;       
}

Status GetTop(SqStack S,SElemType &e)     	//若栈不空,用 e返回栈顶元素 (注意这里的应用,后面会用到)
{
	if(S.top==S.base)
		return ERROR;
	e = *(S.top-1);
	return OK;
}

Status Push(SqStack &S,SElemType e)           //入栈
{   
    if(S.top-S.base >= S.stacksize)          //栈满,追加存储空间   
	{                                                 
		S.base = (SElemType*)realloc(S.base, 
                (S.stacksize   STACKINCREMENT)*sizeof(SElemType));        //通过realloc动态扩容
     
      if(!S.base)                    //判断扩容是否成功
	  {  
		  printf("存储空间不足,且扩展失败!");
		  exit(OVERFLOW); 
	  }
	  S.top = S.base S.stacksize;               //更新栈顶指针
      S.stacksize  = STACKINCREMENT;     //更新栈的存储空间大小
    }                 
    *S.top   = e;                                  //将元素入栈,使S.top加1
    return OK;           
}

Status Pop(SqStack &S, SElemType &e)      //栈顶元素出栈,赋给元素e
{    
	if(S.top==S.base)            //栈空
		return ERROR;    
    e = * --S.top;               //栈顶元素出栈,并将S.top减1
    return OK;
}//Pop


Status StackEmpty(SqStack S)           //判断栈是否为空 
{         
    if(S.top == S.base)
        return TRUE;
    else
        return FALSE;
}

 BiThrTree pre;  //全局变量始终指向刚刚访问过的节点
//---------二叉树函数实现----------
 Status CreateBiThrTree(BiThrTree &T)	//先序构造二叉树,字符表示树,空格字符表示空树
{   char ch;
	ch=getchar();
	if(ch=='#')T=NULL;
	else{
		if(!(T=(BiThrNode *)malloc(sizeof(BiThrNode))))
		  {   
				printf("存储分配失败!");
				exit(OVERFLOW);
		   }
		T->data = ch;                     //生成根节点
		CreateBiThrTree(T->lchild);   //构造左子树
		CreateBiThrTree(T->rchild);   //构造右子树
	}
	return OK;
}//CreatBiTree


Status visit(TElemType e) //访问节点
{ 
	printf("%c",e);
	return OK;
}

Status PreOrderTraverse(BiThrTree T,Status(*visit)(TElemType ))  //先序遍历
{
	if(T){
		if(visit(T->data))                               //访问根节点
			if(PreOrderTraverse(T->lchild,visit))          //先序遍历左子树
				if(PreOrderTraverse(T->rchild,visit))        //先序遍历右子树
					return OK;
		return ERROR;
	}
	else return OK;
}//PreOrderTraverse


Status InOrderTraverse(BiThrTree T, Status( *visit)(TElemType ))  // 中序遍历
{ 
   if (T) {
      InOrderTraverse(T->lchild, visit);            // 中序遍历左子树
      (*visit)(T->data);                        // 访问根结点
      InOrderTraverse(T->rchild, visit);            // 中序遍历右子树
   }
   return OK;
}

Status PostOrderTraverse (BiThrTree T, Status( *visit)(TElemType ))           // 后序遍历二叉树 
                 
{ 
   if (T) {
     PostOrderTraverse(T->lchild, visit); //后序遍历左子树
     PostOrderTraverse(T->rchild, visit);//后序遍历右子树
      (*visit)(T->data);            // 访问根结点
   }
   return OK;
}

Status PreOrderTraverse_nr(BiThrTree T,Status(*visit)(TElemType e))            //非递归前序遍历 
{
    BiThrTree p;  
	p = T;        
   	SqStack S;                 // 声明栈S 
    InitStack(S); 
  
    while (!StackEmpty(S)|| p)        //边遍历边打印,并存入栈中,以后需要借助这些根节点进入右子树
    {   
       if(p)
        {
           if(!visit(p->data))return ERROR;
            Push(S,p);
            p = p->lchild;
        }
        else                            //当p为空时,说明根和左子树都遍历完了,该进入右子树了 
        {
            Pop(S,p);     //s.pop();
            p = p->rchild;
        }//else
    }//while
    return OK;
}

Status InOrderTraverse_nr(BiThrTree T,Status(*visit)(TElemType e))  //非递归中序遍历(nr,nonrecursively,非递归地)
{
    BiThrTree p;  
	p = T;        
   	SqStack S;                 // 声明栈S 
    InitStack(S); 
  
    while (!StackEmpty(S)|| p)        //边遍历边打印,并存入栈中,以后需要借助这些根节点进入右子树
    {   
       if(p)
        {
          
            Push(S,p);
            p = p->lchild;
        }
        else                            //当p为空时,说明根和左子树都遍历完了,该进入右子树了 
        {
            Pop(S,p);    
            if(!visit(p->data))return ERROR;
            p = p->rchild;
        }//else
    }//while
    return OK;
}//InOrderTrayerse_nr


Status PostOrderTraverse_nr(BiThrTree T,Status(*visit)(TElemType e))//非递归后序遍历
{
   	SqStack S;                 // 声明栈S 
    InitStack(S); 
      
    BiThrTree pCur, pLastVisit;   //pCur:当前访问节点,pLastVisit:上次访问节点     
   
    pCur = T;
    pLastVisit = NULL;       
    
    while (pCur)        //先把pCur移动到左子树最下边 
    {
        Push(S,pCur);       
        pCur = pCur->lchild;
    }
    while (!StackEmpty(S))
    {
        //走到这里,pCur都是空,并已经遍历到左子树底端(看成扩充二叉树,则空,亦是某棵树的左孩子)
        Pop(S,pCur);        
		 
        if (pCur->rchild == NULL || pCur->rchild == pLastVisit) //一个根节点被访问的前提是:无右子树或右子树已被访问过
        {
            if(!visit(pCur->data))return ERROR;        //访问结点 
           
            pLastVisit = pCur;           //修改最近被访问的节点
        }
        /*这里的else语句可换成带条件的else if:
        else if (pCur->lchild == pLastVisit)//若左子树刚被访问过,则需先进入右子树(根节点需再次入栈)
        因为:上面的条件没通过就一定是下面的条件满足。仔细想想!
        */
        else
        {
            
            Push(S,pCur);     //根节点再次入栈
           
            pCur = pCur->rchild;    //进入右子树,且可肯定右子树一定不为空   
            while (pCur)
            {
                Push(S,pCur);
                pCur = pCur->lchild;
            }
        }
    }
    return OK;
}


Status CountLeaf(BiThrTree T)            //返回指针T所指二叉树中所有叶子结点个数 
{       
	int m,n;
   if (!T ) return 0;
   if (!T->lchild && !T->rchild) return 1;
   else{
       m = CountLeaf( T->lchild);  
       n = CountLeaf( T->rchild); 
       return (m n);   
   } //else
} // CountLeaf


Status Depth(BiThrTree T)                 // 返回二叉树的深度
{            
	int  depthLeft=0,depthRight=0,depthval=0;
   if ( !T )   
    depthval = 0;
   else 
     {
     depthLeft = Depth( T->lchild );
     depthRight= Depth( T->rchild );
     depthval = 1   (depthLeft > depthRight  ?
                               depthLeft : depthRight);
     } 
   return depthval;
}



Status InThreading(BiThrTree p)            //中序线索化
{
	if(p)
	{
		InThreading(p->lchild);   //左子树线索化

		if(!p->lchild)           //若没有左孩子
		{
			p->LTag = Thread;        //当前结点前驱线索
		    p->lchild = pre;       //左孩子指针指向前驱
		} 
		else 
			p->LTag = Link;

		if(!pre->rchild)         //前驱没有右孩子
		{pre->RTag = Thread;      //后继线索
		 pre->rchild = p;        //前驱的右孩子指针指向后继(当前节点p)
		}else
			p->RTag = Link;

		pre = p;                 //保持pre指向p的前驱
		InThreading(p->rchild);  //右子树线索化
	}
	return OK;
}// InThreading

Status InOrderThreading(BiThrTree &Thrt, BiThrTree T)   //中序遍历二叉树T,并将其中序线索化,Thrt指向头结点。
{
    
	if(!(Thrt = (BiThrTree)malloc(sizeof(BiThrNode))))
	{
		printf("分配内存失败!\n");
		
		exit(OVERFLOW);
	}
	Thrt->LTag = Link;
	Thrt->RTag = Thread;      //建立头结点

	Thrt->rchild = Thrt;     //左指针回指
	if(!T)
		Thrt->lchild = Thrt;   //若二叉树为空,则左指针回指
	else
	{
		Thrt->lchild = T;
		pre = Thrt;

		InThreading(T);     //中序遍历进行中序线索化
		pre->rchild = Thrt;
		pre->RTag  = Thread;  //最后一个结点线索化
		Thrt->rchild = pre;
	}
	return OK;
}//InOrderThreading

     
Status InOrderTraverse_Thr(BiThrTree T, Status (*Visit)(TElemType)) //中序遍历二叉线索书T的非递归算法
{                                                                     //T指向头结点,头结点的左链lchild指向根节点	                                  
	BiThrTree p2; 
	p2=T->lchild;      //p指向根节点
	while(p2!=T)       //空树或遍历结束时,p==T
	{
		while(p2->LTag==Link)
			p2=p2->lchild;     //直到最左
		if(!visit(p2->data))   //访问其左子树为空的结点
			return ERROR;    
		while(p2->RTag==Thread && p2->rchild != T)//如果该结点的后继不是头结点,访问它的后继结点
		{
			p2 = p2->rchild;     //p2->RTag线索, p2->rchild指向其后继
			visit(p2->data);  //访问后继结点
		}
		p2 = p2->rchild;    //更新当前结点
	}
	return OK;
}//InOrderTraverse_Thr
void display()//登陆界面 
{    int n,m=1;
     BiThrTree T;
	 BiThrTree Thrt;
		  printf("     ◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇\n"); 
		  printf("     ◆     欢迎使用 B126二叉树    ◆\n"); 
		  printf("     ◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇\n\n");  
		  printf("         测试二叉树:AB#CD###EFGH##K####\n");  
		  printf("请按先序次序输入树(#代表空树):\n");
	      CreateBiThrTree(T); 
		  do{
	printf("★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆\n");  
	printf("☆请输入你想操作的序号:                   ★\n");  
	printf("★             0)退出                     ☆\n");  
	printf("☆             1)先序遍历                 ★\n");  
	printf("★             2)先序遍历(非递归)       ☆\n");
	printf("☆             3)中序遍历                 ★\n"); 
	printf("★             4)中序遍历(非递归)       ☆\n");
	printf("☆             5)后序遍历                 ★\n");
	printf("★             6)后序遍历(非递归)       ☆\n");
	printf("☆             7)统计叶子结点个数         ★\n");
	printf("★             8)计算二叉树的深度         ☆\n");
	printf("☆             9)中序线索树二叉树         ★\n");    
	printf("★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆\n");    
	scanf("%d",&n);
	if(n<0||n>9)   
	{
		printf("您输入的序号不正确,请重新输入:\n");  
		scanf("%d",&n); 
	}
	switch(n)
	{
		case 0:printf("Goodbye!\n");m =0 ;exit(0);break;   
	    case 1:{printf("先序遍历一棵树:\n");PreOrderTraverse(T,visit);printf("\n");break;} 
		case 2:{printf("先续遍历一棵树(非递归实现): \n");PreOrderTraverse_nr(T,visit);printf("\n");break;}
	    case 3:{printf("中续遍历一棵树: \n");InOrderTraverse(T,visit);printf("\n");break; }  
	    case 4:{printf("中续遍历一棵树(非递归实现): \n");InOrderTraverse_nr(T,visit);printf("\n");break;}
	    case 5:{printf("后续遍历一棵树: \n");PostOrderTraverse (T,visit);printf("\n"); break;}
		case 6:{printf("后续遍历一棵树(非递归实现): \n");PostOrderTraverse_nr(T,visit);printf("\n");break;}
		case 7:{printf("统计叶子结点个数 \n");printf("%d\n",CountLeaf (T));break;}
		case 8:{printf("计算二叉树的深度:\n");printf("%d\n", Depth(T));break;}
	    case 9:{printf("输出中序线索树二叉树的内容:\n");InOrderThreading(Thrt, T);InOrderTraverse_Thr(Thrt,visit);printf("\n");break;}
	}

		  }
	while(m!=0);
		  
}

// 

int main()
{
	//BiThrTree T;
    //BiThrTree Thrt;
	 display();
	
    
   

	return 0;
}


标签:

实例下载地址

二叉树 入门级示例源码

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警