实验三
给定广义表表示的情况下实现二叉树的生成
#include <bits/stdc++.h>
#define MAXSIZE 200
using namespace std;
typedef char DataType;
typedef struct BiTnode { //结构
DataType data;
struct BiTnode *lchild, *rchild;
}*BiTree, BitNode;
int CreateBiTree(BiTree *T, DataType *str);//生成二叉树
void PreOrderTraverse(BiTree T); //先序遍历
int BTNodeDepth(BiTree b); //求二叉树b的深度
int Nodes(BiTree T); //叶子结点的个数
int TreeWidth(BiTree T);//树的宽度
int main() { //主函数
int n, len = 0;
char ch, str[MAXSIZE];
BiTree T;
cout << "请输入广义表,以‘@’结束:" << endl;
while ((ch = getchar()) != '\n') {
str[len++] = ch;
}
n = CreateBiTree(&T, str);
if (n == 1) {
cout << "创建成功!" << endl;
} else {
cout << "创建失败!" << endl;
}
puts("先序遍历:");
PreOrderTraverse(T);
puts("");
puts("树的深度:");
cout << BTNodeDepth(T) << endl;
puts("树的叶子节点数:");
cout << Nodes(T) << endl;
puts("树的宽度:");
cout << TreeWidth(T) << endl;
return 0;
}
int CreateBiTree(BiTree *T, DataType *str) {
BiTree S[MAXSIZE], p = NULL;
int top = 0, k = 0, j = 0;
char ch;
*T = NULL;
ch = str[j];
while (ch != '@') {
switch (ch) {
case '(':
S[top++] = p;
k = 1;
break;
case ')':
top--;
break;
case ',':
k = 2;
break;
default:
p = (BiTree)malloc(sizeof(BitNode));
p->data = ch;
p->lchild = p->rchild = NULL;
if (*T == NULL) {
*T = p;
} else {
switch (k) {
case 1:
S[top - 1]->lchild = p;
break;
case 2:
S[top - 1]->rchild = p;
break;
}
}
break;
}
ch = str[++j];
}
return 1;
}
void PreOrderTraverse(BiTree T) { //先序遍历
if (T == NULL) return ; //空二叉树
else {
printf("%c", T->data); //访问根结点
PreOrderTraverse(T->lchild); //递归遍历左子树
PreOrderTraverse(T->rchild); //递归遍历右子树
}
}
int BTNodeDepth(BiTree T) { //求二叉树b的深度
int lchilddep, rchilddep;
if (T == NULL)
return 0; //空树的高度为0
else {
lchilddep = BTNodeDepth(T->lchild); //求左子树的高度为lchilddep
rchilddep = BTNodeDepth(T->rchild); //求右子树的高度为rchilddep
return (lchilddep > rchilddep) ? (lchilddep + 1) : (rchilddep + 1);
}
}
int Nodes(BiTree T) { //叶子结点的个数
int num1, num2;
if (T == NULL)
return 0;
else if (T->lchild == NULL && T->rchild == NULL)
return 1;
else {
num1 = Nodes(T->lchild);
num2 = Nodes(T->rchild);
return (num1 + num2);
}
}
int TreeWidth(BiTree T) { //树的宽度
if (!T) return 0;
queue<BiTree> myQueue;
myQueue.push(T); // 将根结点入队列
int nWidth = 1; // 二叉树的宽度
int nCurLevelWidth = 1; // 记录当前层的宽度
BiTree pCur = NULL;
while (!myQueue.empty()) {// 队列不为空
while (nCurLevelWidth != 0) {
pCur = myQueue.front(); // 取出队首元素
myQueue.pop(); // 队首元素出队列
if (pCur->lchild != NULL) myQueue.push(pCur->lchild);
if (pCur->rchild != NULL) myQueue.push(pCur->rchild);
nCurLevelWidth--;
}
nCurLevelWidth = myQueue.size();
nWidth = nCurLevelWidth > nWidth ? nCurLevelWidth : nWidth;
}
return nWidth;
}
哈夫曼树
#include <bits/stdc++.h>
using namespace std;
const int N = 200;
const int MX = 0x3f3f3f3f;
typedef struct {
int weight;
int parent, lch, rch;
} HTNode, *HuffmanTree;
void Select(HuffmanTree HT, int n, int &s1, int &s2); //在HT[k](1≤k≤i-1)中选择两个其双亲域为0,且权值最小的结点,并返回它们在HT中的序号s1和s2
void CreatHuffmanTree (HuffmanTree &HT, int n); //建树
void CreatHuffmanCode(HuffmanTree HT, char *HC[], int n); //找其序列
int main() {
HuffmanTree ht;
int n;
cout << "input n: ";
cin >> n;
CreatHuffmanTree(ht, n);
char *hc[n + 1];
CreatHuffmanCode(ht, hc, n);
for (int i = 1; i <= n; i ++ ) {
cout << i << " : hfm: " << hc[i] << '\n';
}
return 0;
}
void Select(HuffmanTree HT, int n, int &s1, int &s2) {
int mx = MX;
for (int i = 1; i <= n; i ++ ) {
if (!HT[i].parent && HT[i].weight < mx) {
mx = HT[i].weight;
s1 = i;
}
}
mx = MX;
for (int i = 1; i <= n; i ++ ) {
if (i != s1 && !HT[i].parent && HT[i].weight < mx) {
mx = HT[i].weight;
s2 = i;
}
}
}
void CreatHuffmanTree (HuffmanTree &HT, int n) {
if (n <= 1)return;
int m = 2 * n - 1;
HT = new HTNode[m + 1]; //0号单元未用,HT[m]表示根结点
for (int i = 1; i <= m; ++i) {
HT[i].lch = 0;
HT[i].rch = 0;
HT[i].parent = 0;
}
for (int i = 1; i <= n; ++i) {
cout << "input " << i << " valuse : ";
cin >> HT[i].weight;
}
for (int i = n + 1; i <= m; ++i) {
int s1, s2;
Select(HT, i - 1, s1, s2);
HT[i].lch = s1;
HT[i].rch = s2 ; //s1,s2分别作为i的左右孩子
HT[s1].parent = i;
HT[s2] .parent = i;
HT[i].weight = HT[s1].weight + HT[s2] .weight;
//i 的权值为左右孩子权值之和
}
}
void CreatHuffmanCode(HuffmanTree HT, char *HC[], int n) {
//从叶子到根逆向求每个字符的赫夫曼编码,存储在编码表HC中分配n个字符编码的头指针矢量
char *cd = new char[n]; //分配临时存放编码的动态数组空间
cd[n - 1] = '\0'; //编码结束符
for (int i = 1; i <= n; ++i) { //逐个字符求赫夫曼编码
int start = n - 1;
int c = i;
int f = HT[i].parent;
while (f != 0) { //从叶子结点开始向上回溯,直到根结点
--start; //回溯一次start向前指一个位置
if (HT[f].lch == c) cd[start] = '0'; //结点c是f的左孩子,则生成代码0
else cd[start] = '1'; //结点c是f的右孩子,则生成代码1
c = f;
f = HT[f].parent; //继续向上回溯
} //求出第i个字符的编码
HC[i] = new char [n - start]; // 为第i 个字符编码分配空间
strcpy(HC[i], &cd[start]); //将求得的编码从临时空间cd复制到HC的当前行中
}
delete cd; //释放临时空间
}
没有什么能阻止我对知识的追求!!!

浙公网安备 33010602011771号