哈夫曼树
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 100typedef struct {int weight;int lchild, rchild, parent;
} HTNode;typedef HTNode HT[MAXLEN];
int n;void CreatHFMT(HT T);
void InitHFMT(HT T);
void InputWeight(HT T);
void SelectMin(HT T, int i, int *p1, int *p2);
void PrintHFMT(HT T);
void hfnode(HT T, int i, int j);
void haffmannode(HT T);int main() {HT HT;CreatHFMT(HT);PrintHFMT(HT);haffmannode(HT);return 0;
}void CreatHFMT(HT T) {int i, p1, p2;InitHFMT(T);InputWeight(T);for (i = n; i < 2 * n - 1; i++) {SelectMin(T, i - 1, &p1, &p2);T[p1].parent = T[p2].parent = i;T[i].lchild = p1;T[i].rchild = p2;T[i].weight = T[p1].weight + T[p2].weight;}
}void InitHFMT(HT T) {int i;printf("\n请输入共有多少个权值(小于100):");scanf("%d", &n);for (i = 0; i < 2 * n - 1; i++) {T[i].weight = 0;T[i].lchild = -1;T[i].rchild = -1;T[i].parent = -1;}
}void InputWeight(HT T) {int w, i;for (i = 0; i < n; i++) {printf("输入第%d个权值:", i + 1);scanf("%d", &w);getchar();T[i].weight = w;}
}void SelectMin(HT T, int i, int *p1, int *p2) {long min1 = 888888, min2 = 888888;int j;for (j = 0; j <= i; j++) {if (T[j].parent == -1) {if (min1 > T[j].weight) {min1 = T[j].weight;*p1 = j;}}}for (j = 0; j <= i; j++) {if (T[j].parent == -1) {if (min2 > T[j].weight && j != (*p1)) {min2 = T[j].weight;*p2 = j;}}}
}void PrintHFMT(HT T) {int i;printf("哈夫曼树的各边显示:\n");for (i = 0; i < 2 * n - 1; i++) {if (T[i].lchild != -1) {printf("(%d,%d),(%d,%d)\n", T[i].weight, T[T[i].lchild].weight, T[i].weight, T[T[i].rchild].weight);}}
}void hfnode(HT T, int i, int j) {j = T[i].parent;if (T[j].rchild == i) {printf("1");} else {printf("0");}if (T[j].parent != -1) {hfnode(T, j, i);}
}void haffmannode(HT T) {int i, j;printf("\n输入权值的对应哈夫曼编码:\n");for (i = 0; i < n; i++) {printf("%d的编码为: ", T[i].weight);hfnode(T, i, -1); // -1 表示递归的初始状态printf("\n");}printf("\n ");
}
运行结果
二叉树
#include <stdio.h>
#include <malloc.h>
#define MAX 100
int count = 0; /*定义计算结点个数的变量*/
typedef struct tnode
{char data;struct tnode* lchild, * rchild;
}BT;BT* CreateBTree()
{BT* t;char ch;scanf("%c", &ch);getchar();if (ch == '0')t = NULL;else{t = (BT*)malloc(sizeof(BT));t->data = ch;printf("请输入%c结点的左孩子结点:", t->data);t->lchild = CreateBTree();printf("请输入%c结点的右孩子结点:", t->data);t->rchild = CreateBTree();}return t;
}void ShowBTree(BT* T) /*用广义表表示法显示二叉树*/
{if (T != NULL) /*当二叉树非空时*/{printf("%c", T->data); /*输入该结点数据域*/if (T->lchild != NULL) /*若其左子树非空*/{printf("("); /*输入左括号*/ShowBTree(T->lchild); /*递归调用该函数输出其左子树各结点*/if (T->rchild != NULL) /*若其右子树非空*/{printf(","); /*输出逗号*/ShowBTree(T->rchild); /*递归调用该函数输出其右子树各结点*/}printf(")");}elseif (T->rchild != NULL) /*二叉树左子树为空,右子树不为空时*/{printf("("); /*输入左括号*/ShowBTree(T->lchild); /*递归调用该函数输出其左子树各结点*/if (T->rchild != NULL) /*若其右子树非空*/{printf(","); /*输出逗号*/ShowBTree(T->rchild); /*递归调用该函数输出其右子树各结点*/}printf(")");}}
}void PreOrder(BT* T) /* 先序遍历二叉树T*/
{if (T == NULL) return; /* 递归调用的结束条件*/else{printf("%c", T->data); /* 输出结点的数据域*/PreOrder(T->lchild); /* 先序递归遍历左子树*/PreOrder(T->rchild); /* 先序递归遍历右子树*/}
}void InOrder(BT* T) /* 中序遍历二叉树T*/
{if (T == NULL) return; /* 递归调用的结束条件*/else{InOrder(T->lchild); /* 中序递归遍历左子树*/printf("%c", T->data); /* 输出结点的数据域*/InOrder(T->rchild); /* 中序递归遍历右子树*/}
}void PostOrder(BT* T) /* 后序遍历二叉树T*/
{if (T == NULL) return; /* 递归调用的结束条件*/else{PostOrder(T->lchild); /* 后序递归遍历左子树*/PostOrder(T->rchild); /* 后序递归遍历右子树*/printf("%c", T->data); /* 输出结点的数据域*/}
}void LevelOrder(BT* T) /*按层次遍历二叉树T*/
{int f, r; /*定义队头队尾指针*/BT* p, * q[MAX]; /*定义循环队列,存放结点指针*/p = T;if (p != NULL) /*若二叉树非空,则根结点地址入队*/{f = 1; q[f] = p; r = 2;}while (f != r) /*队列不空时*/{p = q[f];printf("%c", p->data); /*访问队首结点的数据域*/if (p->lchild != NULL) /*将队首结点的左孩子入队*/{q[r] = p->lchild; r = (r + 1) % MAX;}if (p->rchild != NULL) /*将队首结点的右孩子入队*/{q[r] = p->rchild; r = (r + 1) % MAX;}f = (f + 1) % MAX;}
}void Leafnum(BT* T) /*求二叉树叶子结点数*/
{if (T) /*若树不为空*/{if (T->lchild == NULL && T->rchild == NULL)count++; /*全局变量count为计数值,其初值为0*/Leafnum(T->lchild); /*递归统计T的左子树叶子结点数*/Leafnum(T->rchild); /*递归统计T的右子树叶子结点数*/}
}void Nodenum(BT* T)
{if (T) /*若树不为空*/{count++; /*全局变量count为计数值,其初值为0*/Nodenum(T->lchild); /*递归统计T的左子树结点数*/Nodenum(T->rchild); /*递归统计T的右子树结点数*/}
}int TreeDepth(BT* T) /*求二叉树深度*/
{int ldep = 0, rdep = 0; /*定义两个整型变量,用以存放左、右子树的深度*/if (T == NULL)return 0;else{ldep = TreeDepth(T->lchild); /*递归统计T的左子树深度*/rdep = TreeDepth(T->rchild); /*递归统计T的右子树深度*/if (ldep > rdep)return ldep + 1;elsereturn rdep + 1;}
}void MenuTree() /*显示菜单子函数*/
{printf("\n 二叉树子系统");printf("\n =================================================");printf("\n| 1——建立一个新二叉树 |");printf("\n| 2——广义表表示法显示 |");printf("\n| 3——先序遍历 |");printf("\n| 4——中序遍历 |");printf("\n| 5——后序遍历 |");printf("\n| 6——层次遍历 |");printf("\n| 7——求叶子结点数目 |");printf("\n| 8——求二叉树总结点数目 |");printf("\n| 9——求树深度 |");printf("\n| 0——返回 |");printf("\n ================================================");printf("\n请输入菜单号(0-9):");
}main()
{BT* T = NULL;char ch1, ch2, a;ch1 = 'y';while (ch1 == 'y' || ch1 == 'Y'){MenuTree();scanf("%c", &ch2);getchar();switch (ch2){case '1':printf("请按先序序列输入二叉树的结点:\n");printf("说明:输入结点后按回车('0'表示后继结点为空):\n");printf("请输入根结点:");T = CreateBTree();printf("二叉树成功建立!"); break;case '2':printf("二叉树广义表表示法如下:");ShowBTree(T); break;case '3':printf("二叉树的先序遍历序列为:");PreOrder(T); break;case '4':printf("二叉树的中序遍历序列为:");InOrder(T); break;case '5':printf("二叉树的后序遍历序列为:");PostOrder(T); break;case '6':printf("二叉树的层次遍历序列为:");LevelOrder(T); break;case '7':count = 0; Leafnum(T);printf("该二叉树有%d个叶子。", count); break;case '8':count = 0; Nodenum(T);printf("该二叉树共有%d个结点。", count); break;case '9':printf("该二叉树的深度是%d。", TreeDepth(T)); break;case '0':ch1 = 'n'; break;default:printf("输入有误,请输入0-9进行选择!");}if (ch2 != '0'){printf("\n按回车键继续,按任意键返回主菜单!\n");a = getchar();if (a != '\xA'){getchar(); ch1 = 'n';}}}
}
运行结果