数据结构作业-严蔚敏-5.3

一、题目描述

以二叉链表作为二叉树的存储结构,编写下列算法:

1)判别两棵树是否相等

2)交换二叉树每个结点的左孩子和右孩子

3)计算二叉树的最大宽度(二叉树的宽度是指二叉树所有层中结点个数的最大值)

二、解答

1)判别两棵树是否相等

算法思想

利用递归实现,递归结束的条件有三个:一是两棵树均为空,返回相等;二是只有一棵树为空,返回不等;三是根结点的数据域不等,返回不等。其他情况下则递归判断相应的孩子结点是否相等。

算法描述

int Compare(BiTree T1,BiTree T2)
{
    if(T1==NULL&&T2==NULL)
    {
        return 1;
    }
    else if(T1==NULL||T2==NULL)
    {
        return 0;
    }
    if(T1->data!=T2->data)
    {
        return 0;
    }
    int left=right=0;
    left=Compare(T1->lchild,T2->lchild);
    right=Compare(T1->rchild,T2->rchild);
    return left&&right;
    
}

具体代码

#include<stdio.h>
#include<stdlib.h>
/*二叉树结点*/
typedef struct BiTNode
{
	char data;
	struct BiTNode* lchild, * rchild;
}BiTNode,*BiTree;

/*先序遍历,创建二叉树*/
void CreatBiTree(BiTree& T)
{
	char ch;
	scanf("%c", &ch);
	getchar();
	if (ch == '#')
	{
		T = NULL;
	}
	else
	{
		T = (BiTNode*)malloc(sizeof(BiTNode));
		T->data = ch;
		printf("请输入%c的左子树:\n", ch);
		CreatBiTree(T->lchild);
		printf("请输入%c的右子树:\n", ch);
		CreatBiTree(T->rchild);
	}
}
/*先序打印二叉树*/
void InOrderPrint(BiTree T)
{
	if (T == NULL)
	{
		return;
	}
	else
	{
		printf("%c ", T->data);
		InOrderPrint(T->lchild);
		InOrderPrint(T->rchild);
	}
}
/*Compare函数,比较两二叉树是否相等*/
int Compare(BiTree T1, BiTree T2)
{
	if (T1 == NULL && T2 == NULL)//两树均为空
	{
		return 1;
	}
	else if (T1 == NULL || T2 == NULL)//一树为空,另一树不为空
	{
		return 0;
	}
	if (T1->data != T2->data)//两树对应结点的数据域不同
	{
		return 0;
	}
	int left = 0, right = 0;//比较左右子树
	left = Compare(T1->lchild, T2->lchild);
	right = Compare(T1->rchild, T2->rchild);
	return left && right;


}
int main()
{
	BiTree T1, T2;
	printf("创建第一个二叉树:\n");
	CreatBiTree(T1);
	InOrderPrint(T1);
	printf("\n创建第二个二叉树:\n");
	CreatBiTree(T2);
	InOrderPrint(T2);
	if (Compare(T1, T2))
	{
		printf("\n两二叉树相同\n");
	}
	else
	{
		printf("\n两二叉树不同\n");
	}
	return 0;
}

运行结果

在这里插入图片描述

2)交换二叉树每个结点的左孩子和右孩子

算法思想

如果某结点的左、右子树有一个为空,则返回,否则交换该结点的左右孩子,然后递归交换左右子树。

算法描述

void ChangeLR(BiTree &T)
{
    BiTree temp;
    if(T->lchild==NULL||T->rchild==NULL)
    {
        return;
    }
    else
    {
        temp=T->lchild;
        T->lchild=T->rchild;
        T->rchild=temp;
    }
    ChangeLR(T->lchild);
    ChangeLR(T-rchild);
}

具体代码

#include<stdio.h>
#include<stdlib.h>
/*二叉树结点*/
typedef struct BiTNode
{
	char data;
	struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;

/*先序遍历,创建二叉树*/
void CreatBiTree(BiTree& T)
{
	char ch;
	scanf("%c", &ch);
	getchar();
	if (ch == '#')
	{
		T = NULL;
	}
	else
	{
		T = (BiTNode*)malloc(sizeof(BiTNode));
		T->data = ch;
		printf("请输入%c的左子树:\n", ch);
		CreatBiTree(T->lchild);
		printf("请输入%c的右子树:\n", ch);
		CreatBiTree(T->rchild);
	}
}
/*先序打印二叉树*/
void InOrderPrint(BiTree T)
{
	if (T == NULL)
	{
		return;
	}
	else
	{
		printf("%c ", T->data);
		InOrderPrint(T->lchild);
		InOrderPrint(T->rchild);
	}
}
/*交换二叉树的左右孩子*/
void ChangeLR(BiTree& T)
{
	BiTree temp;
	if (T->lchild == NULL || T->rchild == NULL)
	{
		return;
	}
	else
	{
		temp = T->lchild;
		T->lchild = T->rchild;
		T->rchild = temp;
	}
	ChangeLR(T->lchild);
	ChangeLR(T->rchild);
}
int main()
{
	BiTree T1;
	printf("创建一个二叉树:\n");
	CreatBiTree(T1);
	printf("二叉树为:\n");
	InOrderPrint(T1);
	printf("交换左右孩子之后的二叉树为:\n");
	ChangeLR(T1);
	InOrderPrint(T1);
	return 0;
}

运行结果

在这里插入图片描述

3)计算二叉树的最大宽度

算法思想

计算二叉树最大的宽度可采用层次遍历的方法,利用队列来实现。首先判断是否为空树,如果为空树,则宽度为0;不为空,则分别记录局部的宽度和当前的最大宽度,逐层遍历结点,如果结点有孩子结点,则将孩子结点加入队尾;每层遍历完毕后,若局部宽度打于当前的最大宽度,则修改最大宽度。

算法描述

int Width(BiTree T)
{
    if(T==NULL)
    {
        return 0;
    }
    else
    {
        BiTree Q[];//Q是队列,元素为二叉树结点指针,容量足够大
        front=1;//队头指针
        rear=1;//队尾指针
        last=1;//同层最右结点在队列中的位置
        temp=0;//局部宽度
        maxw=0//最大宽度
        Q[rear]=T;//根结点入队
        while(front<=last)
        {
            p=Q[front++];
            temp++;//同层元素加1
            if(p->lchild!=NULL)
            {
                Q[++rear]=p->lchild;//左孩子入队
            }
            if(p->rchild!=NULL)
            {
                Q[++rear]=p->rchild;//右孩子入队
            }
            if(front>last)//一层结束
            {
                last=rear;//last指向下层最右元素
                if(temp>maxw)
                {
                    maxw=temp;//更新当前最大宽度
                }
                temp=0;
            }
        }
        return maxw;
    }
}

具体代码

#include<stdio.h>
#include<stdlib.h>
/*二叉树结点*/
typedef struct BiTNode
{
	char data;
	struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;

/*先序遍历,创建二叉树*/
void CreatBiTree(BiTree& T)
{
	char ch;
	scanf("%c", &ch);
	getchar();
	if (ch == '#')
	{
		T = NULL;
	}
	else
	{
		T = (BiTNode*)malloc(sizeof(BiTNode));
		T->data = ch;
		printf("请输入%c的左子树:\n", ch);
		CreatBiTree(T->lchild);
		printf("请输入%c的右子树:\n", ch);
		CreatBiTree(T->rchild);
	}
}
/*先序打印二叉树*/
void InOrderPrint(BiTree T)
{
	if (T == NULL)
	{
		return;
	}
	else
	{
		printf("%c ", T->data);
		InOrderPrint(T->lchild);
		InOrderPrint(T->rchild);
	}
}
int Width(BiTree T)
{
    if (T == NULL)
    {
        return 0;
    }
    else
    {
        BiTree Q[100], p;//Q是队列,元素为二叉树结点指针,容量足够大
        int front = 1;//队头指针
        int rear = 1;//队尾指针
        int last = 1;//同层最右结点在队列中的位置
        int temp = 0;//局部宽度
        int maxw = 0;//最大宽度
        Q[rear] = T;//根结点入队
        while (front <= last)
        {
            p = Q[front++];
            temp++;//同层元素加1
            if (p->lchild != NULL)
            {
                Q[++rear] = p->lchild;//左孩子入队
            }
            if (p->rchild != NULL)
            {
                Q[++rear] = p->rchild;//右孩子入队
            }
            if (front > last)//一层结束
            {
                last = rear;//last指向下层最右元素
                if (temp > maxw)
                {
                    maxw = temp;//更新当前最大宽度
                }
                temp = 0;
            }
        }
        return maxw;
    }
}
int main()
{
	BiTree T1;
	printf("创建一个二叉树:\n");
	CreatBiTree(T1);
	printf("二叉树为:\n");
	InOrderPrint(T1);
    int x = Width(T1);
    printf("二叉树的最大宽度为:%d", x);
	return 0;
}

运行结果
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值