二叉树的二叉链表存储结构的建立及操作的实现

什么是二叉树呢?

二叉树是n(n>=0)个结点的有限集,它或为空树(n=0),或由一个根结点和两棵分别称为左子树和右子树的互不相交的二叉树构成(递归定义)
特点:
1)每个结点至多有二棵子树(即不存在度大于2的结点)
2)二叉树的子树有左、右之分,且其次序不能任意颠倒
在这里插入图片描述

二叉树的二叉链表存储结构的定义

typedef struct BiTNode { // 结点结构
    TElemType      data;
    struct BiTNode  *lchild, *rchild;   // 左右孩子指针
} BiTNode, *BiTree;

构建二叉树

//构建二叉树

void CreateBiTree(BiTree &T)
{//按先序次序输入二叉树中结点的值,创建二叉链表表示的二叉树T
	
	TElemType n;
	scanf("%d",&n);
	if(n==0)//递归结束条件
	{
		T=NULL;	
	}
	else
	{
		T = new BiTNode;//生成根节点
		T->data = n;
		CreateBiTree(T->lchild);//递归创建左子树
		CreateBiTree(T->rchild);//递归创建右子树
	}
}

遍历二叉树

先序遍历

若二叉树为空树,则空操作;否则,
(1)访问根结点;
(2)先序遍历左子树;
(3)先序遍历右子树。

递归算法

void PreOrderTraverse (BiTree T)
{ // 先序遍历二叉树 ,假设遍历是输出结点的值
   if (T) 
    {
       printf(T->data); // 访问根结点 , visit(T->data);  
       PreOrderTraverse(T->lchild ); //先序遍历左子树
       PreOrderTraverse(T->rchild );//先序遍历右子树
     }
}

非递归算法

void PreOrderTraverse (BiTree T)
{ // 先序遍历二叉树的非递归算法
  InitStack(S);   Push(S,T);
  while (! StackEmpty(S))
   {  while(GetTop(S, P)&&P)
        {printf(P->data); Push(S, P->lchild);}
      Pop(S,P)//空指针出栈
      if(! StackEmpty(S)) 
        {  Pop(S,P);  
           Push(S,P->rchild);
        }//if
   }//while
Destroy(S);
 }// PreOrderTraverse

中序遍历

若二叉树为空树,则空操作;否则,
(1)中序遍历左子树;
(2)访问根结点;
(3)中序遍历右子树。

递归算法

void InOrderTraverse (BiTree T  )
{ // 中序遍历二叉树 
   if (T) 
    {
       InOrderTraverse(T->lchild ); //中序遍历左子树
        printf (T->data);            // 访问根结点     
        InOrderTraverse(T->rchild ); //中序遍历右子树
    }    
}// InOrderTraverse

非递归算法

void InOrderTraverse (BiTree T   )    //P124
{ // 中序遍历二叉树 的非递归算法
  InitStack(S);   Push(S,T);
  while (! StackEmpty(S))
   {  while(GetTop(S, P)&&P) Push(S, P->lchile);
       Pop(S,P);       //空指针出栈
       if(! StackEmpty(S))  
        {  Pop(S,P); 
            printf (P->data);   //访问结点
           Push(S,P->rchild);
        }//if
   }//while
 Destroy(S);
}// InOrderTraverse

后序遍历

若二叉树为空树,则空操作;否则,
(1)后序遍历左子树;
(2)后序遍历右子树;
(3)访问根结点。

递归算法

void  PostOrderTraverse (BiTree T)
{ // 后序遍历二叉树 
   if (T)
    {  
      PostOrderTraverse(T->lchild ); //后序遍历左子树
       PostOrderTraverse(T->rchild );//后序遍历右子树
      printf (T->data);            // 访问根结点
     }
}//PostOrderTravers

非递归算法

void PostOrderTraverse (BiTree  T)
{ // 后序遍历二叉树 的非递归算法
  InitStack(S);  //栈元素的类型为
   Pt=T; 
   while(Pt||StackEmpty(S))
     {  
       if (Pt)    { Push(S,(Pt,0)); Pt=Pt->lchild; }
       else  { Pop(S,P) ; 
                  if( P.Tag==0)
                      { P.Tag=1;Push(S,P); Pt=P.Bit->rchild;}
                  else {printf(P.Bit->data) ; Pt==NULL;}
                 }
     }
 Destroy(S);
}// PostOrderTraverse

求二叉树的深度

//求二叉树的深度
int Depth(BiTree T)
{
	TElemType m,n;
	if(T==NULL)
		return 0;
	else
	{
		m = Depth(T->lchild);
		n = Depth(T->rchild);
		return (m > n ? m : n)+1;
	}
}

求二叉树中结点个数

//求二叉树中结点个数
int NodeCount(BiTree T)
{
	if(T==NULL)
		return 0;
	else
		return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}

求二叉树中叶子结点个数

//求二叉树中叶子结点个数
int LeaveCount(BiTree T)
{
	if(T==NULL)
		return 0;
	else if(!T->lchild&&!T->rchild)//只要有一个子树为空,就返回1
		return 1;
	else
		return (LeaveCount(T->lchild)+LeaveCount(T->rchild));
}

求二叉树中度为1的结点个数

//求二叉树中度为1的结点个数
int NodeCount_1(BiTree T)
{
	if(T==NULL)
		return 0;
	else if(!T->lchild&&T->rchild||T->lchild&&!T->rchild)
		return (NodeCount_1(T->lchild)+NodeCount_1(T->rchild))+1;
	else
		return (NodeCount_1(T->lchild)+NodeCount_1(T->rchild));
}

主函数实现

int main(){
	BiTree T;
	int option,depth,Lcount,Ncount,N_1count;
	while(true){
		printf("\n--二叉树的二叉链表--\n--功能如下--\n");
		printf("1.构建\n2.中序遍历\n3.求深度\n4.求叶子结点个数\n5.求结点个数\n6.求度为1的结点个数\n7.退出\n请输入序号:");
		scanf("%d",&option);
		switch(option){
			case 1:
				CreateBiTree(T);
				printf("二叉树创建成功。\n");
				break;
			case 2:
				InOrderTraverse(T);
				break;
			case 3:
				depth=Depth(T);
				printf("二叉树的深度为:%d\n",depth);
				break;
			case 4:
				Lcount=LeaveCount(T);
				printf("二叉树的叶子结点个数为:%d\n",Lcount);
				break;
			case 5:
				Ncount=NodeCount(T);
				printf("二叉树的结点个数为:%d\n",Ncount);
				break;
			case 6:
				N_1count=NodeCount_1(T);
				printf("二叉树的度为1的结点个数为:%d\n",N_1count);
				break;
			case 7:
				exit(0);
			default:
				printf("输入的指令有误,请重新输入!\n");
		}
	
	}
}
  • 12
    点赞
  • 99
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,我可以回答您有关于二叉树相关操作实现的问题。 1. 二叉树二叉链表存储结构是什么? 二叉树二叉链表存储结构是将每个节点表示为一个结构体,包含三个指针域和一个数据域。其中,左右指针分别指向该节点的左子树和右子树,父指针指向该节点的父节点(非必需),数据域保存该节点的值。 2. 如何实现二叉链表的创建和遍历算法? 二叉链表的创建可以通过递归实现,先序遍历可以递归实现,中序和后序遍历也可以通过递归实现。代码示例如下: ``` // 二叉树结构体定义 typedef struct BiTNode { int data; struct BiTNode *lchild, *rchild; } BiTNode, *BiTree; // 创建二叉树 void CreateBiTree(BiTree *T) { int ch; scanf("%d", &ch); if (ch == -1) { *T = NULL; } else { *T = (BiTree)malloc(sizeof(BiTNode)); (*T)->data = ch; CreateBiTree(&(*T)->lchild); CreateBiTree(&(*T)->rchild); } } // 先序遍历 void PreOrderTraverse(BiTree T) { if (T == NULL) { return; } printf("%d ", T->data); PreOrderTraverse(T->lchild); PreOrderTraverse(T->rchild); } // 中序遍历 void InOrderTraverse(BiTree T) { if (T == NULL) { return; } InOrderTraverse(T->lchild); printf("%d ", T->data); InOrderTraverse(T->rchild); } // 后序遍历 void PostOrderTraverse(BiTree T) { if (T == NULL) { return; } PostOrderTraverse(T->lchild); PostOrderTraverse(T->rchild); printf("%d ", T->data); } ``` 3. 如何实现二叉树求结点个数、求高度、求叶子结点数和交换左右子树的算法? 二叉树求结点个数可以通过递归实现,每次从左右子树中递归计算节点个数,然后加上根节点即可。求高度同样可以通过递归实现,每次从左右子树中递归计算高度,然后加上1即可。求叶子结点数可以通过递归实现,每次从左右子树中递归计算叶子结点数,然后加上当前节点是否为叶子节点即可。交换左右子树可以通过递归实现,先分别递归交换左右子树,然后交换当前节点的左右子树。 代码示例如下: ``` // 求结点个数 int GetNodeCount(BiTree T) { if (T == NULL) { return 0; } return GetNodeCount(T->lchild) + GetNodeCount(T->rchild) + 1; } // 求高度 int GetHeight(BiTree T) { if (T == NULL) { return 0; } int lheight = GetHeight(T->lchild); int rheight = GetHeight(T->rchild); return (lheight > rheight ? lheight : rheight) + 1; } // 求叶子结点数 int GetLeafCount(BiTree T) { if (T == NULL) { return 0; } if (T->lchild == NULL && T->rchild == NULL) { return 1; } return GetLeafCount(T->lchild) + GetLeafCount(T->rchild); } // 交换左右子树 void Swap(BiTree T) { if (T == NULL) { return; } BiTree tmp = T->lchild; T->lchild = T->rchild; T->rchild = tmp; Swap(T->lchild); Swap(T->rchild); } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HTUer的编程之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值