二叉树与哈夫曼树
#include <stdio.h>
#include <stdlib.h>
#define Maxsize 20
//二叉链表的结构
typedef char datatype;
typedef struct BiNode
{
datatype data;
double weight;// 权值
int parent;//双亲结点
struct BiNode* lchild, * rchild;//孩子节点
struct BiNode* next;//哈曼夫树单链表指针
}bitree;
/*2.实验内容及要求:
二叉树如右所示,完成本次实验。
基础实验项目:
1.实现该二叉树的递归前序遍历算法;
2.实现该二叉树的递归中序遍历算法;
3.实现该二叉树的递归后序遍历算法;
*/
void PreOrder(bitree* root); //实现该二叉树的递归前序遍历算法;
void InOrder(bitree* root);// 实现该二叉树的递归中序遍历算法;
void PostOrder(bitree* root);//实现该二叉树的递归后序遍历算法;
void creatBitree();//以先序方式创建二叉树
void InPreOrder(bitree* root);//实现上述二叉树的非递归前序遍历算法;
void deleteTree(bitree* root);//删除二叉树
bitree* CreateHT(bitree* link);//创建哈夫曼树
void print(bitree ht[]);//输出哈夫曼树
void print(bitree* h);
bitree* CreateLinkList(int n); //根据叶子节点的权值生成一个升序单链表
void HuffCode(bitree* root);//后序遍历哈夫曼树并输出哈夫曼编码
void main()
{
bitree* root=NULL;
int x = 0;
printf("创建二叉树,请输入二叉树中的结点值(字符):\n");
creatBitree(&root);
printf("请输入:");
printf("\n二叉树的前序遍历序列为 : ");
if (root != NULL)
PreOrder(root);
printf("\n");
printf("\n二叉树的中序遍历序列为 : ");
if (root != NULL)
InOrder(root);
printf("\n");
printf("\n二叉树的后序遍历序列为 : ");
if (root != NULL)
PostOrder(root);
printf("\n");
printf("*****************************************\n\n");
printf("\n二叉树的非递归先序遍历序列为 : ");
if (root != NULL)
InPreOrder(root);
printf("\n");
/*printf("是否要删除二叉树来创建哈夫曼树?(y/n)\n");
int del;
scanf("%d", &del);
if (del = 'y')
{*/
deleteTree(root);
printf("原二叉树已删除!\n");
//bitree* root;
printf("创建哈夫曼树,给定数据集{3,2,5,7,8}\n");
printf("请输入叶子节点个数:\n");
int n;
scanf("%d", &n);
printf("请输入节点的权值:\n");
root = CreateLinkList(n);
printf("输出生成的树:\n");
print(root);
root=CreateHT(root);
//root = HuffTree(root);//生成哈夫曼树
/*printf("先序遍历输出哈夫曼树个结点的值:\n");
PreOrder(root);
printf("\n");
printf("中序遍历输出哈夫曼树个结点的值:\n");
InOrder(root);
printf("后序遍历输出哈夫曼树个节点的值:\n");
PostOrder(root);*/
printf("输出遍历哈夫曼树的节点值:\n");
HuffCode(root);
//print(boot);
//root = HuffTree(root);//生成哈夫曼树
//void CreateHT(bitree ht[],int n0);
//void print(bitree ht[]);//输出哈夫曼树
/* }
else
{
printf("不进行拓展实验操作,运行结束!\n感谢使用\n");
}*/
}
//以先序方式创建二叉树
void creatBitree(bitree** root)
{
char ch;
scanf_s("%c", &ch, sizeof(char));
if (ch != '#')
{
*root = (bitree*)malloc(sizeof(bitree));
(*root)->data = ch;
creatBitree(&(*root)->lchild);
creatBitree(&(*root)->rchild);
return root;
}
else
*root = NULL;
}
void PreOrder(bitree* root) //实现该二叉树的递归前序遍历算法;
{
if (root != NULL)
{
printf("%c", root->data);
PreOrder(root->lchild);
PreOrder(root->rchild);
}
}
void InOrder(bitree* root)// 实现该二叉树的递归中序遍历算法;
{
if (root != NULL)
{
InOrder(root->lchild);
printf("%c", root->data);
InOrder(root->rchild);
}
}
void PostOrder(bitree* root)//实现该二叉树的递归后序遍历算法;
{
if (root != NULL)
{
PostOrder(root->lchild);
PostOrder(root->rchild);
printf("%c", root->data);
}
}
void InPreOrder(bitree* root)//实现上述二叉树的非递归前序遍历算法;
{
bitree* stack[Maxsize];
int i = 0;
stack[0] = NULL;
while (root != NULL || i > 0)
if (root != NULL)
{
printf("%c", root->data); //输出节点信息
stack[++i] = root; //指针压栈
root = root->lchild;//先遍历左边
}
else {
root = stack[i--];//栈给指针
root = root->rchild;//遍历右边
}
}
void deleteTree(bitree* root)//删除二叉树
{
if (root!=NULL)
{
deleteTree(root->lchild);
deleteTree(root->rchild);
free(root);
return 1;
}
}
bitree* CreateLinkList(int n) //根据叶子节点的权值生成一个升序单链表
{
bitree* link, * p, * q, * s;
int i;
link = (bitree*)malloc(sizeof(bitree));//生成单链表的头节点
s = (bitree*)malloc(sizeof(bitree));//生成单链表第一个数据节点,即哈夫曼树的叶节点
//scanf("%d", &s->data);//输入叶子节点权值
s->lchild = NULL;
s->rchild = NULL;
s->next = NULL;
link->next = s;
for (i = 2; i <= n; i++)
{
s = (bitree*)malloc(sizeof(bitree));//生成一个数据节点
scanf("%d", &s->data);
s->lchild = NULL;
s->rchild = NULL;
q = link;//按照升序插入单链表
p = q->next;
while (p != NULL)
if (s->data > p->data)//查找插入位置后进行插入
{
q = p;
p = p->next;
}
else
{
q->next = s;
s->next = p;
break;
}
if (s->data > q->data)
{
q->next = s;
s->next = p;
}
return link;
}
}
void print(bitree* h)//输出单链表
{
bitree* p;
p = h->next;
while (p != NULL)
{
printf("%d,", p->data);
p = p->next;
}
printf("\n");
}
bitree* CreateHT(bitree* link)//创建哈夫曼树//BSTree_Link* HuffTree(BSTree_Link* link)//生成哈夫曼树
{
bitree* p, * q, * s;
while (link->next != NULL)
{
p = link->next;
q = p->next;
link->next = q->next;
s = (bitree*)malloc(sizeof(bitree));
s->data = p->data + q->data;
s->lchild = p;
s->lchild = q;
q = link;
p = q->next;
while (p != NULL)
if (s->data > p->data)
{
q = p;
p = p->next;
}
else
{
q->next = s;
s->next = p;
break;
}
if (q != link && s->data > q->data)
{
q->next = s;
s->next = p;
}
}
return s;
}
/*void print(bitree ht[])//输出哈夫曼树
{
int i = 0;
for (int i = 0; ; i++)
{
printf("%c: ", ht[i]);
printf("\n");
}
printf("\n");
}*/
void HuffCode(bitree* root)//后序遍历哈夫曼树并输出哈夫曼编码
{
bitree* q=NULL, * stack[Maxsize];
int b, i = -1, j = 0, k, code[Maxsize];
root->next = (bitree*)malloc(sizeof(bitree));
do
{
while (root != NULL)
{
if (root->lchild == NULL && root->rchild == NULL)
{
printf("叶节点信息:key=%3d,code:", root->data);
for (k = 0; k < j; k++)
printf("%d", code[k]);
printf("\n");
j--;
}
stack[++i] = root;
root = root->lchild;
code[j++] = 0;
}
b = 1;
while (i >= 0 && b)
{
root = stack[i];
if (root->rchild == q)
{
i--; j--;
q = root;
}
else
{
root = root->rchild;
code[j++] = 1;
b = 0;
}
}
} while (i >= 0);
}