【二叉树系列】二叉树课程大作业
来源:互联网 发布:长期成本 知乎 编辑:程序博客网 时间:2024/05/16 13:05
本博客将以代码的形式详细讲解二叉树的所有算法,包括创建二叉树,二叉树的三种遍历方式,二叉树的各种属性算法,如:求高度,求叶子节点数,求节点数,以及二叉树最常见的应用哈夫曼树,代码如下:
# include<stdio.h># include<string.h># include<conio.h># include<stdlib.h># define N 1# define M 2*N-1typedef char * HC[N+1];typedef struct bt{char x;struct bt *lchild;struct bt *rchild;}bt,*pbt;typedef struct {int parent;int weight, lchild, rchild;}HT[M+1];void creatbt(pbt *root){char ch=getchar();if(ch==' ')*root=NULL;else{*root=(pbt)malloc(sizeof(bt));(*root)->x=ch;creatbt(&((*root)->lchild));creatbt(&((*root)->rchild));}}void preorder(pbt root){if(root!=NULL){printf("%c",root->x);preorder(root->lchild);preorder(root->rchild);}}void inorder(pbt root){if(root!=NULL){inorder(root->lchild);printf("%c",root->x);inorder(root->rchild);}}void postorder(pbt root){if(root!=NULL){postorder(root->lchild);postorder(root->rchild);printf("%c",root->x);}}int btdepth(pbt root,int h){static int depth=0;if(root!=NULL){if(h>depth) depth=h;btdepth(root->lchild,h+1);btdepth(root->rchild,h+1);}return depth;}int nodenum(pbt root){static int n=0;if(root!=NULL){ n++;nodenum(root->lchild);nodenum(root->rchild);}return n;}int leafnum(pbt root){static int n=0;if(root!=NULL){leafnum(root->lchild);leafnum(root->rchild);if((root->lchild==NULL)&&(root->rchild==NULL))n++;}return n;}void select(HT ht,int n,int *x,int *y){int i,min1=100,min2=200;for(i=1;i<=n;i++){if(ht[i].parent==0&&ht[i].weight<min1){min1=ht[i].weight;*x=i;}}for(i=1;i<=n;i++){if(ht[i].parent==0&&ht[i].weight<min2&&i!=*x){min2=ht[i].weight;*y=i;}}}void hafuman(HT ht,int w[],int n){int i,k,m,x,y;for(i=1;i<=n;i++){ht[i].weight=w[i];ht[i].parent=ht[i].lchild=ht[i].rchild=0;}m=2*n-1;for(i=n+1;i<=m;i++){ht[i].parent=ht[i].lchild=ht[i].rchild=0;}for(i=n+1;i<=m;i++){select(ht,i-1,&x,&y);//选择parent为0且权值最小的结点ht[i].weight=ht[x].weight+ht[y].weight;ht[i].lchild=x;ht[i].rchild=y;ht[x].parent=ht[y].parent=i;}}void hafumancode(HT ht,HC hc,int n){int i,c,p,start;char * cd=(char *)malloc(n*sizeof(char));cd[n-1]='\0';//此处的cd用来存储当前哈夫曼码,可供循环利用,相当于一个暂存器for(i=1;i<=n;i++)//求n个叶子结点的哈夫曼码{start=n-1;c=i;//因为下面会循环更新孩子结点,所以不能用i(否则第一次for循环后i可能就不再是1),可将i的值提前赋给cp=ht[i].parent;while(p!=0)//只要p不是根结点{start--;//此语句用来循环更新存储下标if(ht[p].lchild==c)//cd[i]='0';//错误。注意应从叶子结点开始向上推cd[start]='0';else//cd[i]='1';cd[start]='1';c=p;//此语句用来循环更新孩子结点p=ht[p].parent;}hc[i]=(char *)malloc((n-start)*sizeof(char));strcpy(hc[i],&cd[start]);}free(cd);for(i=1;i<=n;i++){//printf("%d的哈夫曼码为%s\n",ht[i],hc[i]);错误,ht[i]为结构数组,应写其成员printf("%d的哈夫曼码为%s\n",ht[i].weight,hc[i]);}}void main(){int n;pbt root;printf("\t\t-----------------------------------------\n");printf("\t\t1.创建二叉树 2.遍历二叉树\n");printf("\t\t3.二叉树的属性 4.哈夫曼树\n");printf("\t\t5.退出\n");printf("\t\t-----------------------------------------\n");while(1){printf("请选择功能模块(1-5)\n");scanf("%d",&n);//char ch=getche();getchar();switch(n){case 1:{printf("请以先序扩展创建二叉树(空结点用空格代替)\n");creatbt(&root);}break;case 2:{printf("遍历二叉树\n");printf("\t\t[1]先序遍历\n");printf("\t\t[2]中序遍历\n");printf("\t\t[3]后序遍历\n");printf("\t\t[4]返回主菜单\n");while(1){int n;printf("请选择(1-4):\n");scanf("%d",&n);if(1==n)preorder(root);if(2==n)inorder(root);if(3==n)postorder(root);//else//不能这样写,因为这个else只能与上一个if配对,所以当n!=3时break都会执行if(n==4)break;} }break;case 3:{int h=1,n;printf("二叉树属性\n");printf("\t\t[1]二叉树高度\n");printf("\t\t[2]二叉树结点数\n");printf("\t\t[3]二叉树叶子结点\n");printf("\t\t[4]返回主菜单\n");while(1){printf("请选择:(1-4)\n");scanf("%d",&n);if(1==n)printf("该二叉树的高度为%d\n",btdepth(root,h));if(2==n)printf("该二叉树的结点数为%d\n",nodenum(root));if(3==n)printf("该二叉树的叶子结点数为%d\n",leafnum(root));if(n==4)break;}}break;case 4:{HT ht;HC hc;int n,i;printf("请输入叶子结点的个数\n");scanf("%d",&n);int * w=(int *)malloc((n+1)*sizeof(int));//此语句必须位于scanf的下面for(i=1;i<=n;i++){printf("请输入第%d个叶子结点的权值\n",i);scanf("%d",&w[i]);}hafuman(ht,w,n);hafumancode(ht,hc,n);}break;case 5:exit(1);}}}
程序运行结果如下:
注意对于同一个二叉树,哈夫曼码的结果不唯一,上述输出只是一种情况。
2 0
- 【二叉树系列】二叉树课程大作业
- 数据结构OJ作业 二叉树
- 作业五 二叉树II
- 二叉树系列---基础
- 二叉树系列---recover_binary_search_tree
- 二叉树系列---symmetric_tree
- 二叉树系列
- 二叉树系列之一:二叉树
- 二叉树系列---构造二叉查找树
- 二叉树系列---层次遍历二叉树
- 大数据及人工智能基础知识复习系列1 二叉树及二叉搜索树
- 数据结构和算法系列课程(01)--- 排序二叉树和红黑树
- 二叉树概念大总结
- 二叉树系列问题1
- leetcode 二叉树系列搞定
- 【算法系列-4】二叉树
- 二叉树系列---path-sum
- 二叉树系列---same-tree
- Unity(C#.net)网络通信问题解决(服务器开启失败,Socket下的“由于目标机器积极拒绝,无法连接”异常)
- 11个好蛋,1个坏蛋,如何用一个天平一只比。用3次称,找出坏蛋
- Java笔记---云服务使用中的报错
- Struts2学习笔记
- CSS vertical-aglin属性基本应用
- 【二叉树系列】二叉树课程大作业
- Team Queue. id:540
- 如何阅读caffe代码
- poj 3984
- 1010 of greedy strategy
- 【水题】HDU 5646
- c++友元函数及运算符重载
- 任何经历,都是一种积累
- HTML整站规划笔记