二叉树与哈夫曼树

二叉树与哈夫曼树

#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);
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

惑星撞地球

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

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

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

打赏作者

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

抵扣说明:

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

余额充值