AI 摘要

本篇文章主要介绍了在头歌数据结构实验04中关于树和二叉树的学习内容。第一关中,通过建立二叉链表实现了二叉树的先序、中序和后序遍历。具体包括先序建立二叉树和递归算法实现遍历。第二关则是基于二叉链表的二叉树结点个数统计,包括度为0、1、2的结点个数统计。通过递归算法对二叉树的结点进行统计。整体实验内容涵盖了二叉树的相关操作和统计。

第1关:基于二叉链表的二叉树的遍历

任务描述

设二叉树中每个结点的元素均为一个字符,按先序遍历的顺序建立二叉链表,编写三个递归算法分别实现二叉树的先序、中序和后序遍历。

编程要求

输入

多组数据。每组数据一行,为二叉树的前序序列(序列中元素为‘0’时,表示该结点为空)。当输入只有一个“0”时,输入结束。

输出

每组数据输出三行,为二叉树的先序、中序和后序序列。

测试说明

平台会对你编写的代码进行测试:

测试输入: abcd00e00f00ig00h00 abd00e00cf00g00 0

预期输出: abcdefigh dcebfagih decfbghia abdecfg dbeafcg debfgca

#include<iostream>
#include<string.h>
using namespace std;
int flag;
typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{//先序建立二叉树
	if(S[i]=='0')
		T=NULL;
	else
	{
		T=new BiTNode;
		T->data=S[i];
		CreateBiTree(T->lchild,S,++i);
		CreateBiTree(T->rchild,S,++i);
	}
}
void PreOrderTraverse(BiTree T)
{//二叉树的先序遍历
/**************begin************/
     if(T)
     {
         cout<<T->data;
         PreOrderTraverse(T->lchild);
         PreOrderTraverse(T->rchild);
     }

    /**************end************/
}
void InOrderTraverse(BiTree T)
{//二叉树的中序遍历
/**************begin************/

if(T)
     {
         
         InOrderTraverse(T->lchild);
         cout<<T->data;
        InOrderTraverse(T->rchild);
     }

    /**************end************/
}
void PostOrderTraverse(BiTree T)
{//二叉树的后序遍历
/**************begin************/
if(T)
     {
        
         PostOrderTraverse(T->lchild);
         PostOrderTraverse(T->rchild);
          cout<<T->data;
     }


    /**************end************/
}
int main()
{
	char S[100];
	while(cin>>S)
	{
		if(strcmp(S,"0")==0) break;
		int i=-1;
	  	BiTree T;
		CreateBiTree(T,S,++i);
		PreOrderTraverse(T);
		cout<<endl;
  	    InOrderTraverse(T);
		cout<<endl;
		PostOrderTraverse(T);
		cout<<endl;
	}
	return 0;
}

第2关:基于二叉链表的二叉树结点个数的统计

任务描述

设二叉树中每个结点的元素均为一个字符,按先序遍历的顺序建立二叉链表,编写三个递归算法对二叉树的结点(度为0、1、2)个数进行统计。

编程要求

输入

多组数据。每组数据一行,为二叉树的前序序列(序列中元素为‘0’时,表示该结点为空)。当输入只有一个“0”时,输入结束。

输出

每组数据输出一行,每行三个数分别为二叉树的度为0、1、2的结点个数。每两个数用空格分隔。

测试说明

平台会对你编写的代码进行测试:

测试输入: abcd00e00f00ig00h00 abd00e00cf00g00 0

预期输出: 5 0 4 4 0 3

#include<iostream>
#include<string.h>
using namespace std;
int a,b,c;//a、b、c分别表示度为0、1、2的结点个数
typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T,char S[],int &i)
{//先序建立二叉树
	if(S[i]=='0')
		T=NULL;
	else
	{
		T=new BiTNode;
		T->data=S[i];
		CreateBiTree(T->lchild,S,++i);
		CreateBiTree(T->rchild,S,++i);
	}
}
void Count(BiTree T)
{//二叉树结点个数的统计
/**************begin************/
if (T == NULL) // 基本情况:空树
        return;

    if (T->lchild == NULL && T->rchild == NULL) // 度为0的节点
        a++;
    else if (T->lchild != NULL && T->rchild != NULL) // 度为2的节点
        c++;
    else // 度为1的节点
        b++;

    // 递归调用
    Count(T->lchild);
    Count(T->rchild);
        
     

    /**************end************/
}
int main()
{
	char S[100];
	while(cin>>S)
	{
	    if(strcmp(S,"0")==0) break;
		a=b=c=0;
      	int i=-1;
	  	BiTree T;
		CreateBiTree(T,S,++i);
		Count(T);
		cout<<a<<" "<<b<<" "<<c<<endl;
	}
	return 0;
}

第3关:基于二叉链表的二叉树高度的计算

任务描述

设二叉树中每个结点的元素均为一个字符,按先序遍历的顺序建立二叉链表,,编写递归算法计算二叉树的高度。

编程要求

输入

多组数据。每组数据一行,为二叉树的前序序列(序列中元素为‘0’时,表示该结点为空)。当输入只有一个“0”时,输入结束。

输出

每组数据分别输出一行,为二叉树的高度。

测试说明

平台会对你编写的代码进行测试:

测试输入: abcd00e00f00ig00h00 abd00e00cf00g00 0

预期输出: 4 3

#include<iostream>

#include <string.h>

using namespace std;

typedef struct BiTNode

{

    char data;

    struct BiTNode *lchild,*rchild;

}BiTNode,*BiTree;

void CreateBiTree(BiTree &T,char S[],int &i)

{//先序建立二叉树

    if(S[i]=='0')

        T=NULL;

    else

    {

        T=new BiTNode;

        T->data=S[i];

        CreateBiTree(T->lchild,S,++i);

        CreateBiTree(T->rchild,S,++i);

    }

}

int Depth(BiTree T)

{//二叉树高度的计算

/**************begin************/

    // 如果树为空,高度为0

    if(T==NULL)

     return 0;

    // 计算左子树的高度

     int left=Depth(T->lchild);

    // 计算右子树的高度

     int right=Depth(T->rchild);

    // 返回左右子树中较大的高度,并加上根节点本身的高度1

     return 1+std::max(left,right);

    /**************end************/

}

int main()

{

    char S[100];

    while(cin>>S)

    {

        if(strcmp(S,"0")==0) break;

        int i=-1;

        BiTree T;

        CreateBiTree(T,S,++i);

        cout<<Depth(T)<<endl;

    }

    return 0;

}

第4关:二叉树的WPL计算

补充:(什么是WPL)

WPL(带权路径长度)是指二叉树中所有叶节点的路径长度与其权值的乘积之和。在一棵二叉树中,如果从根节点到叶节点的路径长度为 d,该叶节点的权值为 w,则该叶节点的带权路径长度为 d * w。而二叉树的 WPL 则是所有叶节点的带权路径长度之和。

WPL 的计算可以用于度量二叉树的紧凑程度。WPL 越小,表示树的叶子节点分布越接近树的根部,树的结构越紧凑。而 WPL 越大,表示叶子节点的分布更分散,树的结构越松散。

在一些问题中,需要比较不同构建的二叉树之间的性能,WPL 可以作为一个评价标准。例如,在哈夫曼编码中,构建的二叉树的 WPL 被用来评估编码方案的效率。

任务描述

二叉树的带权路径长度(WPL)是二叉树中所有叶结点的带权路径长度之和。给定一棵二叉树T, 采用二叉链表存储,结点结构为:left weight right,其中叶结点的weight域保存该结点的非负权值。设root为指向T的根结点的指针,请设计求T的WPL的算法。

编程要求

输入

多组数据,每组数据一行,为一个二叉树的先序序列(序列中元素为0时,表示该结点为空,每两个元素之间用空格隔开)。当输入只有一个0时,输入结束。

输出

每组数据输出一行,为该二叉树的WPL。

测试说明

平台会对你编写的代码进行测试:

测试输入:

1 1 0 0 1 0 0

1 2 1 0 0 0 0

0

预期输出:

2

2

#include<iostream>
using namespace std;
typedef struct BiTNode
{
	int weight;
	struct BiTNode *left,*right;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T)
{//先序建立二叉树
	int x;
	cin>>x;
	if(x==0) T=NULL;
	else
    {
		T=new BiTNode;
		T->weight=x;
		CreateBiTree(T->left);
		CreateBiTree(T->right);
	}
}
int WPL(BiTree &T,int d)
{//求二叉树T的带权路径长度
/**************begin************/
   
// 如果节点为空,返回0
    if (T == NULL)
        return 0;
    
    // 如果是叶子节点,返回该节点的权值乘以深度
    if (T->left == NULL && T->right == NULL)
        return T->weight * d;

    // 递归计算左子树和右子树的带权路径长度,并累加
    return WPL(T->left, d + 1) + WPL(T->right, d + 1);

    /**************end************/
}
int main()
{
	while(1)
    {
		BiTree T;
		CreateBiTree(T);
		if(!T) break;
		int d=0;          //调用时T指向二叉树的根结点,d为0
		cout<<WPL(T,d)<<endl;
	}
	return 0;
}
届ける言葉を今は育ててる
最后更新于 2024-05-18