6-1 二叉树的递归遍历
分数 50
作者 启迪-数据结构教研组
单位 广西科技大学
要求使用递归算法实现二叉树的先序遍历、中序遍历和后序遍历。
函数接口定义:
void PreorderTraversal(BinTree BT) /* 二叉树的先序遍历 */
void InorderTraversal(BinTree BT) /* 二叉树的中序遍历 */
void PostorderTraversal(BinTree BT) /* 二叉树的后序遍历 */
其中,BinTree
的结构定义为:
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
要求3个函数分别按照访问顺序打印出结点的内容,字符之间无空格
裁判测试程序样例:
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef struct TNode * BinTree; /* 二叉树类型 */
typedef char ElementType;
struct TNode{ /* 树结点定义 */
ElementType Data; /* 结点数据 */
BinTree Left; /* 指向左子树 */
BinTree Right; /* 指向右子树 */
};
void PreorderTraversal(BinTree BT) ; /* 二叉树的先序遍历 */
void InorderTraversal(BinTree BT); /* 二叉树的中序遍历 */
void PostorderTraversal(BinTree BT); /* 二叉树的后序遍历 */
//按先序次序输入二叉树中结点的值(一个字符),@表示空树,构造二叉链表表示二叉树T
BinTree CreatBinTree()
{
ElementType ch;
BinTree T;
scanf("%c",&ch); /*按先序次序输入树的结点,空树输入@*/
if(ch == '@')
T = NULL;
else {
T = (BinTree)malloc(sizeof(struct TNode));
T->Data = ch;
T->Left = CreatBinTree();
T->Right = CreatBinTree();
}
return T;
}
int main()
{
BinTree BT;
BT = CreatBinTree();
if(BT == NULL){
printf("\n空树!\n");
}else{
printf("先序遍历的结果为:");
PreorderTraversal(BT);
printf("\n");
printf("中序遍历的结果为:");
InorderTraversal(BT);
printf("\n");
printf("后序遍历的结果为:");
PostorderTraversal(BT);
}
return 0;
}
/* 请在这里填写答案 */
输入样例:
ABC@@DE@G@@F@@@
输出样例:
先序遍历的结果为:ABCDEGF
中序遍历的结果为:CBEGDFA
后序遍历的结果为:CGEFDBA
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码实现
/* 请在这里填写答案 */
void PreorderTraversal(BinTree BT)
{
if (BT != NULL)
{
printf("%c", BT->Data);
PreorderTraversal(BT->Left);
PreorderTraversal(BT->Right);
}
}/* 二叉树的先序遍历 */
void InorderTraversal(BinTree BT)
{
if (BT != NULL)
{
InorderTraversal(BT->Left);
printf("%c", BT->Data);
InorderTraversal(BT->Right);
}
}
/* 二叉树的中序遍历 */
void PostorderTraversal(BinTree BT)
{
if (BT != NULL)
{
PostorderTraversal(BT->Left);
PostorderTraversal(BT->Right);
printf("%c", BT->Data);
}
}
6-2 统计二叉树结点个数
分数 20
作者 韦璐
单位 广西科技大学
统计二叉树中所有结点的个数
函数接口定义:
在这里描述函数接口。例如:
int NodeCount( BinTree BT );
其中 BinTree
的结构定义为:
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
裁判测试程序样例:
在这里给出函数被调用进行测试的例子。例如:
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef struct TNode * BinTree; /* 二叉树类型 */
typedef char ElementType;
struct TNode{ /* 树结点定义 */
ElementType Data; /* 结点数据 */
BinTree Left; /* 指向左子树 */
BinTree Right; /* 指向右子树 */
};
int PrintLeaves( BinTree BT );
//按先序次序输入二叉树中结点的值(一个字符),@表示空树,构造二叉链表表示二叉树T
BinTree CreatBinTree()
{
ElementType ch;
BinTree T;
scanf("%c",&ch); /*按先序次序输入树的结点,空树输入@*/
if(ch == '@')
T = NULL;
else {
T = (BinTree)malloc(sizeof(struct TNode));
T->Data = ch;
T->Left = CreatBinTree();
T->Right = CreatBinTree();
}
return T;
}
/* 请在这里填写答案 */
int main()
{
BinTree BT;
int count;
BT = CreatBinTree();
if(BT == NULL){
printf("\n空树!\n");
}else{
count = NodeCount(BT);
printf("该二叉树中所有结点个数为:%d",count);
}
return 0;
}
输入样例:
在这里给出一组输入。例如:
ABD@@EG@@@C@F@@
输出样例:
在这里给出相应的输出。例如:
该二叉树中所有结点个数为:7
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码实现
直接求解:
int NodeCount(BinTree BT) {
if (BT == NULL) return 0;
return NodeCount(BT->Left) + NodeCount(BT->Right) + 1;
}
通过节点数求解:
int deg_two = 0, deg_one = 0, deg_leaf = 0;
int NodeCount(BinTree BT)
{
if (BT == NULL) return 0;
if (BT->Left == NULL && BT->Right == NULL)
deg_leaf++;
if ((BT->Left!= NULL && BT->Right == NULL) || (BT->Right != NULL && BT->Left == NULL))
deg_one++;
if (BT->Right && BT->Left)
deg_two++;
NodeCount(BT->Left);
NodeCount(BT->Right);
return deg_leaf + deg_one + deg_two;
}
6-3 哈夫曼编码
分数 30
作者 YJ
单位 西南石油大学
编写函数实现哈夫曼编码。输入结点个数(保证个数>1)及各结点的权值,为各结点进行编码。
函数接口定义:
CreateHuffman_tree(HuffmanTree &HT,int n);/*建立n个叶子结点的哈夫曼树*/
Huffman_code(HuffmanTree HT,HuffmanCode &HC,int n);//求哈夫曼编码
其中 HT
为哈夫曼树,n
为叶子结点个数, HC
为哈夫曼编码。
裁判测试程序样例:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
typedef struct hnode
{ int weight;
int lchild,rchild,parent;
}HTNode,*HuffmanTree;/*定义二叉树的存储结点*/
typedef char **HuffmanCode;
void Select(HTNode HT[],int len,int &s1,int &s2)//选出权值最小的两个结点,下标通过s1和s2传出去
{
int i,min1=32767,min2=32767;
for(i=1;i<=len;i++)
{
if(HT[i].weight<min1&&HT[i].parent==0)
{
s2=s1;
min2=min1;
min1=HT[i].weight;
s1=i;
}
else if(HT[i].weight<min2&&HT[i].parent==0)
{ min2=HT[i].weight;
s2=i;
}
}
}
void CreateHuffman_tree(HuffmanTree &Ht,int n);/*建立哈夫曼树*/
void Huffman_code(HuffmanTree HT,HuffmanCode &HC,int n);/*哈夫曼树编码*/
int main()
{
HuffmanTree HT;
HuffmanCode HC;
int i, n;
scanf("%d",&n);
CreateHuffman_tree(HT, n);/*建立哈夫曼树*/
Huffman_code(HT,HC,n);/*哈夫曼树编码*/
for(i=1;i<=n;i++)/*输出字符、权值及编码*/
printf("编码是:%s\n",HC[i]);
return 0;
}
/* 请在这里填写答案 */
输入样例:
3
1 2 3
输出样例:
编码是:10
编码是:11
编码是:0
代码演示
void CreateHuffman_tree(HuffmanTree &HT, int n) {
if (n <= 1) return;
int m = 2 * n - 1;
HT = (HTNode *)malloc((m + 1) * sizeof(HTNode));
for (int i = 1; i <= m; ++i) {
HT[i].weight = 0;
HT[i].parent = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
}
for (int i = 1; i <= n; ++i) {
scanf("%d", &HT[i].weight);
}
for (int i = n + 1; i <= m; ++i) {
int s1, s2;
Select(HT, i - 1, s1, s2);
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
}
void Huffman_code(HuffmanTree HT, HuffmanCode &HC, int n) {
HC = (char **)malloc((n + 1) * sizeof(char *));
char *buff = (char *)malloc(n * sizeof(char));
for (int i = 1; i <= n; ++i) {
int k = 0;
int child = i;
int parent = HT[child].parent;
while (parent != 0) {
if (HT[parent].lchild == child)
buff[k] = '0';
else
buff[k] = '1';
k++;
child = parent;
parent = HT[child].parent;
}
for (int j = 0; j < k / 2; j++) {
char temp = buff[j];
buff[j] = buff[k - j - 1];
buff[k - j - 1] = temp;
}
buff[k] = '\0';
HC[i] = (char *)malloc((k + 1) * sizeof(char));
strcpy(HC[i], buff);
}
free(buff);
}
做法2
void CreateHuffman_tree(HuffmanTree& HT, int n) {
if (n <= 1) return;
int m = 2 * n - 1;
HT = (HTNode*)malloc((m + 1) * sizeof(HTNode));//为节点申请一片连续的空间
for (int i = 1; i <= m; ++i) {
HT[i].weight = 0;
HT[i].parent = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
}//初始化所有节点
for (int i = 1; i <= n; ++i) {
scanf("%d", &HT[i].weight);
}//为所有节点初始化权重
for (int i = n + 1; i <= m; ++i) {
int s1, s2;
Select(HT, i - 1, s1, s2);
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}//开始创建哈夫曼树,寻找两个最小的节点合并成一个新节点,把新节点设置到第n+1个后面,同时扩大遍历范围
}
void Huffman_code(HuffmanTree HT, HuffmanCode& HC, int n) {
HC = (char**)malloc((n + 1) * sizeof(char*));//申请一片连续的空间用于存放每个节点的编码
char* buff = (char*)malloc(n * sizeof(char));//申请每个节点的的编码空间
for (int i = 1; i <= n; ++i) {//遍历哈夫曼树中的每个叶子节点
int k = 0;
int child = i;
int parent = HT[child].parent;
while (parent != 0) {//这个循环是在生成从叶子节点到根节点的路径编码。
if (HT[parent].lchild == child)
buff[k] = '0';
else
buff[k] = '1';
k++;
child = parent;//从叶子节点向上走
parent = HT[child].parent;
}
//因为是在叶子节点向上遍历,所以遍历出来的顺序是反的,要逆置编码
for (int j = 0; j < k / 2; j++) {
char temp = buff[j];
buff[j] = buff[k - j - 1];
buff[k - j - 1] = temp;
}
buff[k] = '\0';
HC[i] = (char*)malloc((k + 1) * sizeof(char));//将buff中的编码交给hc
strcpy(HC[i], buff);
}
free(buff);
}