赫夫曼树,二叉树的递归遍历,二叉树的递归遍历

数据结构---赫夫曼树
数据结构---二叉树递归遍历
数据结构---二叉树非递归遍历
#if 0
/**********************************************/
/************数据结构实验---赫夫曼树***********/
/**********************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct
{
	unsigned int weight;  //节点权值
	unsigned int parent, lchild, rchild; //节点的父指针,左//右孩子指针
}HTNode, *HuffmanTree;
 
typedef char **HuffmanCode;  //赫夫曼编码表
 
 
void CreateHuffmanTree(HuffmanTree &HT, unsigned int *w/*叶子节点权值*/, const int n); //生成一棵赫夫曼树
void HuffmanCoding(HuffmanTree HT, HuffmanCode &HC, const int n);      //对赫夫曼树进行编码
void PrintHuffmanCode(HuffmanCode HC, unsigned int *w, const int n);    //打印赫夫曼编码
void Select(HuffmanTree HT, int t, int&s1, int&s2); //寻找权值最小的两个节点
 
 
int main()
{
	HuffmanTree HT; //赫夫曼树HT
	HuffmanCode HC; //赫夫曼编码表HC
	int n, i; //n是赫夫曼树叶子节点数
	unsigned int* w; //w存放叶子节点权值 
	char j = 'y';
 
	//程序解说
	printf("构造赫夫曼树:\n");
	printf("输入叶子节点数目.\n例如:8\n");
	printf("然后输入每个叶子节点的权值.\n");
	printf("例如:5 29 7 8 14 23 3 11\n");
	printf("构造一棵哈夫曼树并显示赫夫曼编码.\n");
	while (j != 'N' && j != 'n')
	{
		printf("请输入叶子节点数目:");
		scanf("%d", &n); //输入叶子节点数
		if (n <= 1)
		{
			printf("该数不合理!\n");
			continue;
		}
		w = (unsigned int*)malloc(n * sizeof(unsigned int)); //开辟空间存放权值
		printf("请输入各叶子节点的权值:\n");
		for (i = 0; i < n; i++)
			scanf("%d", &w[i]);
		CreateHuffmanTree(HT, w, n);	//创建赫夫曼树
		HuffmanCoding(HT, HC, n);		//进行赫夫曼编码
		PrintHuffmanCode(HC, w, n);		//显示赫夫曼编码
		printf("赫夫曼树构造完毕,还要继续吗?(Y/N)");
		scanf(" %c", &j);
	}
	return 0;
}
 
 
void CreateHuffmanTree(HuffmanTree &HT, unsigned int *w/*叶子节点权值*/, const int n)
{
	int i, m;
	int s1, s2;		//存放节点权值最小的两个叶子
	HuffmanTree p;
	if (n <= 1) return;
	m = 2 * n - 1;  //n个叶子节点的赫夫曼树,有2*n-1  //个节点
	HT = (HuffmanTree)malloc((m + 1)*sizeof(HTNode)); //开辟2*n各节点空间,0号单元不用
	for (p = HT + 1, i = 1; i <= n; ++i, ++p, ++w) //原来的节点进行初始化
	{
		p->weight = *w;
		p->parent = 0;
		p->lchild = 0;
		p->rchild = 0;
	}
	for (; i <= m; ++i, ++p)//新开辟的节点进行初始化
	{
		p->weight = 0;
		p->parent = 0;
		p->lchild = 0;
		p->rchild = 0;
	}
	for (i = n + 1; i <= m; ++i)  //建赫夫曼树
	{
		Select(HT, i - 1, s1, s2);
		//从HT[1...i-1]中选择parent为0且weight  //最小的两个节点,其序号分别为s1和s2
		HT[s1].parent = i; HT[s2].parent = i; //修改s1和//s2节点的父指针parent
		HT[i].lchild = s1; HT[i].rchild = s2;
		HT[i].weight = HT[s1].weight + HT[s2].weight;  //修改权值
	}
}
void HuffmanCoding(HuffmanTree HT, HuffmanCode &HC, const int n)
{
	int i, c, f, start;
	char *cd;			//将有n个叶子节点的赫夫曼树HT进行编码,码存放在HC中
	//方法是从叶子到根逆向求每个叶子节点的赫夫曼编码
	HC = (HuffmanCode)malloc((n + 1)*sizeof(char *));
	cd = (char *)malloc(n*sizeof(char));  //开辟一个求编码的临时工作空间
	cd[n - 1] = '\0';          //字符串结束符
	for (i = 1; i <= n; ++i)      //逐个地求赫夫曼编码
	{
		start = n - 1;          //编码结束位置
		for (c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent) //从叶子到根逆向求编码
			if (HT[f].lchild == c)  cd[--start] = '0';          //若是左孩子编为'0'
			else cd[--start] = '1';                        //若是右孩子编为'1'
			HC[i] = (char *)malloc((n - start)*sizeof(char));  //为第i个编码分配空间
			strcpy(HC[i], &cd[start]);                  //将编码从cd复制到HC中
	}
	free(cd); //释放工作空间
}
void PrintHuffmanCode(HuffmanCode HC, unsigned int *w, int n)
{//显示有n个叶子节点的赫夫曼树的编码表
	int i;
	printf("HuffmanCode is :\n");
	for (i = 1; i <= n; i++)
	{
		printf(" %3d---", w[i - 1]);
		puts(HC[i]);
	}
	printf("\n");
}
void Select(HuffmanTree HT, int t, int&s1, int&s2)
{//在HT[1...t]中选择parent不为0且权值最小的两//个节点,其序号分别为s1和s2
	int i, m, n;
	m = n = 10000;
	for (i = 1; i <= t; i++)
	{
		if ((HT[i].parent == 0) && ((HT[i].weight<m) || (HT[i].weight<n)))
			if (m<n)
			{
				n = HT[i].weight; s2 = i;
			}
			else { m = HT[i].weight; s1 = i; }
	}
	if (s1>s2)  //s1放较小的序号
	{
		i = s1; s1 = s2; s2 = i;
	}
}
 
#elif 0
 
/****************************************/
/**********数据结构---二叉树递归遍历*****/
/****************************************/
#include<iostream>
using namespace std;
typedef struct node//定义节点
{
	struct node *lchild;
	struct node *rchild;
	char data;
}BiTreeNode, *BiTree;
 
//按照先序顺序建立二叉树
void createPreBiTree(BiTree &T)
{
	char c;
	cin >> c;
	if ('#' == c)             //当遇到#时,令树的根节点为NULL
		T = NULL;
	else
	{
		T = new BiTreeNode;
		T->data = c;
		createPreBiTree(T->lchild);
		createPreBiTree(T->rchild);
	}
}
 
//按照中序建立二叉树
void createMinBiTree(BiTree &T)
{
	char c;
	cin >> c;
	if ('#' == c)
		T = NULL;
	else
	{
		T = new BiTreeNode;
		createMinBiTree(T->lchild);
		T->data = c;
		createMinBiTree(T->rchild);
	}
}
 
//按照后序建立二叉树
void createPostBiTree(BiTree &T)
{
	char c;
	cin >> c;
	if ('#' == c)
		T = NULL;
	else
	{
		T = new BiTreeNode;
		createPostBiTree(T->lchild);
		createPostBiTree(T->rchild);
		T->data = c;
	}
}
 
 
//前序遍历二叉树并打印
void preTraverse(BiTree T)
{
	if (T)
	{
		cout << T->data << " ";
		preTraverse(T->lchild);
		preTraverse(T->rchild);
	}
}
//中序遍历二叉树并打印
void midTraverse(BiTree T)
{
	if (T)
	{
		midTraverse(T->lchild);
		cout << T->data << " ";
		midTraverse(T->rchild);
	}
}
//后续遍历二叉树并打印
void postTraverse(BiTree T)
{
	if (T)
	{
		postTraverse(T->lchild);
		postTraverse(T->rchild);
		cout << T->data << " ";
	}
}
int main()
{
	BiTree T;
	createPreBiTree(T);
	cout << "二叉树创建完成!" << endl;
	cout << "先序遍历二叉树:" << endl;
	preTraverse(T);
	cout << endl;
	cout << "中序遍历二叉树:" << endl;
	midTraverse(T);
	cout << endl;
	cout << "后序遍历二叉树:" << endl;
	postTraverse(T);
	return 0;
}
 
#elif 1
 
/******************************************************/
/***********数据结构实验---二叉树非递归遍历************/
/******************************************************/
 
 
#include <iostream>
#include<string.h>
#include<stack> //STL模板库栈
using std::stack;//模板栈定义在std命名空间里
using std::cout;
using std::endl;
 
typedef struct node	//二叉树节点
{
	char data;
	struct node *lchild, *rchild;
}BinTree;
 
typedef struct node1
{
	BinTree *btnode;
	bool isFirst;
}BTNode;
 
 
void creatBinTree(char *s, BinTree *&root)  //创建二叉树,s为形如A(B,C(D,E))形式的字符串 
{
	int i;
	bool isRight = false;
	stack<BinTree*> s1;          //存放结点 
	stack<char> s2;              //存放分隔符
	BinTree *p, *temp;
	root->data = s[0];
	root->lchild = nullptr;
	root->rchild = nullptr;
	s1.push(root);
	i = 1;
	while (i<strlen(s))
	{
		if (s[i] == '(')
		{
			s2.push(s[i]);
			isRight = false;
		}
		else if (s[i] == ',')
		{
			isRight = true;
		}
		else if (s[i] == ')')
		{
			s1.pop();
			s2.pop();
		}
		else if (isalpha(s[i]))
		{
			p = (BinTree *)malloc(sizeof(BinTree));
			p->data = s[i];
			p->lchild = nullptr;
			p->rchild = nullptr;
			temp = s1.top();
			if (isRight == true)
			{
				temp->rchild = p;
				cout << temp->data << "的右孩子是" << s[i] << endl;
			}
			else
			{
				temp->lchild = p;
				cout << temp->data << "的左孩子是" << s[i] << endl;
			}
			if (s[i + 1] == '(')
				s1.push(p);
		}
		i++;
	}
}
 
void display(BinTree *root)        //显示树形结构 
{
	if (root != nullptr)
	{
		cout << root->data;
		if (root->lchild != nullptr)
		{
			cout << '(';
			display(root->lchild);
		}
		if (root->rchild != nullptr)
		{
			cout << ',';
			display(root->rchild);
			cout << ')';
		}
	}
}
 
void preOrder1(BinTree *root)     //递归前序遍历 
{
	if (root != nullptr)
	{
		cout << root->data << " ";
		preOrder1(root->lchild);
		preOrder1(root->rchild);
	}
}
 
void inOrder1(BinTree *root)      //递归中序遍历
{
	if (root != nullptr)
	{
		inOrder1(root->lchild);
		cout << root->data << " ";
		inOrder1(root->rchild);
	}
}
 
void postOrder1(BinTree *root)    //递归后序遍历
{
	if (root != nullptr)
	{
		postOrder1(root->lchild);
		postOrder1(root->rchild);
		cout << root->data << " ";
	}
}
 
void preOrder2(BinTree *root)     //非递归前序遍历 
{
	stack<BinTree*> s;
	BinTree *p = root;
	while (p != nullptr || !s.empty())
	{
		while (p != nullptr)
		{
			cout << p->data << " ";
			s.push(p);
			p = p->lchild;
		}
		if (!s.empty())
		{
			p = s.top();
			s.pop();
			p = p->rchild;
		}
	}
}
 
void inOrder2(BinTree *root)      //非递归中序遍历
{
	stack<BinTree*> s;
	BinTree *p = root;
	while (p != nullptr || !s.empty())
	{
		while (p != nullptr)
		{
			s.push(p);
			p = p->lchild;
		}
		if (!s.empty())
		{
			p = s.top();
			cout << p->data << " ";
			s.pop();
			p = p->rchild;
		}
	}
}
 
void postOrder2(BinTree *root)    //非递归后序遍历
{
	stack<BTNode*> s;
	BinTree *p = root;
	BTNode *temp;
	while (p != nullptr || !s.empty())
	{
		while (p != nullptr)              //沿左子树一直往下搜索,直至出现没有左子树的结点 
		{
			BTNode *btn = (BTNode *)malloc(sizeof(BTNode));
			btn->btnode = p;
			btn->isFirst = true;
			s.push(btn);
			p = p->lchild;
		}
		if (!s.empty())
		{
			temp = s.top();
			s.pop();
			if (temp->isFirst == true)     //表示是第一次出现在栈顶 
			{
				temp->isFirst = false;
				s.push(temp);
				p = temp->btnode->rchild;
			}
			else                        //第二次出现在栈顶 
			{
				cout << temp->btnode->data << " ";
				p = nullptr;
			}
		}
	}
}
 
void postOrder3(BinTree *root)     //非递归后序遍历
{
	stack<BinTree*> s;
	BinTree *cur;                      //当前结点 
	BinTree *pre = nullptr;                 //前一次访问的结点 
	s.push(root);
	while (!s.empty())
	{
		cur = s.top();
		if ((cur->lchild == nullptr&&cur->rchild == nullptr) ||
			(pre != nullptr && (pre == cur->lchild || pre == cur->rchild)))
		{
			cout << cur->data << " ";  //如果当前结点没有孩子结点或者孩子节点都已被访问过 
			s.pop();
			pre = cur;
		}
		else
		{
			if (cur->rchild != nullptr)
				s.push(cur->rchild);
			if (cur->lchild != nullptr)
				s.push(cur->lchild);
		}
	}
}
 
 
int main(int argc, char *argv[])
{
	char s[100];
	while (scanf("%s", s) == 1)
	{
		BinTree *root = (BinTree *)malloc(sizeof(BinTree));
		creatBinTree(s, root);
		display(root);
		cout << endl;
		preOrder2(root);
		cout << endl;
		inOrder2(root);
		cout << endl;
		postOrder2(root);
		cout << endl;
		postOrder3(root);
		cout << endl;
	}
	return 0;
}
 
#endif

 

 

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

淮城一只猫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值