首页 > 代码库 > 二叉树的基本操作(含Huffman树)
二叉树的基本操作(含Huffman树)
大二时候写的烂代码,翻出来复习复习(o(╯□╰)o)
代码:
#include <stdio.h> #include <stdlib.h> #define Max_Size 100 struct Binode{ char res; struct Binode *lchild,*rchild; }; struct Binode* First_Creat_Bitree(){//建立一棵二叉树 char ch; struct Binode *p; scanf("%c",&ch); if(ch==‘ ‘) p=NULL; else{ p=(struct Binode *)malloc(sizeof(struct Binode)); p->res=ch; p->lchild=First_Creat_Bitree(); p->rchild=First_Creat_Bitree(); } return p; } void PreOrder_Travel_Bitree(struct Binode *p){//按先序遍历二叉树 if(p){ printf("%c ",p->res); PreOrder_Travel_Bitree(p->lchild); PreOrder_Travel_Bitree(p->rchild); } } int max(int a,int b){ return (a>b)?a:b; } int Get_High(struct Binode *p){//求一棵二叉树的高度 if(p==NULL) return 0; else return max(Get_High(p->lchild),Get_High(p->rchild))+1; } int Get_Leaf_Node(struct Binode *p){//求二叉树的叶子节点个数 if(p==NULL) return 0; else if(p->lchild==NULL&&p->rchild==NULL) return 1; else return Get_Leaf_Node(p->lchild)+Get_Leaf_Node(p->rchild); } struct Qnode{ //队列的基本操作 struct Binode *data; //入队的指针 struct Qnode *next; }; struct Link_Queue{ struct Qnode *front; struct Qnode *rear; }; void Init_Link_Queue(struct Link_Queue &s){ s.front=s.rear=(struct Qnode*)malloc(sizeof(struct Qnode)); if(s.front==NULL) printf("开辟内存失败\n"); s.front->next=NULL; } void Enter_Link_Queue(struct Link_Queue &s,struct Binode *ch){ struct Qnode *p; p=(struct Qnode*)malloc(sizeof(struct Qnode)); p->data=http://www.mamicode.com/ch; p->next=NULL; s.rear->next=p; s.rear=p; } void Delete_Link_Queue(struct Link_Queue &s){ struct Qnode *p; if(s.front==s.rear) printf("队列已空\n"); p=s.front->next; s.front->next=p->next; if(p==s.rear) s.rear=s.front; free(p); } int Empty_Link_Queue(struct Link_Queue &s){ if(s.front==s.rear) return 1; else return 0; } void Level_Order_Travel(struct Binode *p){//层序遍历一棵二叉树 struct Link_Queue s; struct Binode *tmp1,*tmp2; Init_Link_Queue(s); Enter_Link_Queue(s,p); while(!Empty_Link_Queue(s)){ printf("%c ",s.front->next->data->res); tmp1=s.front->next->data->lchild;//出队列前将其左右儿子保存 tmp2=s.front->next->data->rchild; Delete_Link_Queue(s); if(tmp1) Enter_Link_Queue(s,tmp1);//判断左右儿子是否为空,非空则入队列 if(tmp2) Enter_Link_Queue(s,tmp2); } } struct Sq_Stack{ //栈的基本操作 struct Binode **base;//入栈的是指针,因此栈顶指针与基址指针为二级指针 struct Binode **top; int stack_size; }; void Init_Sq_stack(struct Sq_Stack &s){ s.base=(struct Binode** )malloc(Max_Size*sizeof(struct Binode * )); if(!s.base) printf("内存开辟失败\n"); s.top=s.base; s.stack_size=Max_Size; } void Push_Sq_Stack(struct Sq_Stack &s,struct Binode *p){ *(s.top)=p; s.top++; } void Pop_Sq_Stack(struct Sq_Stack &s){ if(s.base==s.top) printf("栈已空\n"); else s.top--; } int Empty_Sq_Stack(struct Sq_Stack &s){ if(s.base==s.top) return 1; else return 0; } struct Binode* Get_Top(struct Sq_Stack &s){ struct Binode *p; p=*(s.top-1); return p; } void InOrder_Travel(struct Binode *p){//中序遍历二叉树的非递归算法 struct Sq_Stack s; struct Binode *tmp,*tmp1; Init_Sq_stack(s); Push_Sq_Stack(s,p); while(!Empty_Sq_Stack(s)){ while(Get_Top(s)){ tmp=Get_Top(s); Push_Sq_Stack(s,tmp->lchild); } Pop_Sq_Stack(s); if(!Empty_Sq_Stack(s)){ printf("%c ",Get_Top(s)->res); tmp1=Get_Top(s);//出栈前将其右儿子保存 Pop_Sq_Stack(s); Push_Sq_Stack(s,tmp1->rchild);//右儿子入栈 } } } int main() { struct Binode *p; int high; int num; printf("建立一颗二叉树并用先序遍历将其输出\n"); p=First_Creat_Bitree(); PreOrder_Travel_Bitree(p); printf("\n"); printf("求二叉树的高度\n"); high=Get_High(p); printf("%d \n",high); printf("求该二叉树的叶子节点个数\n"); num=Get_Leaf_Node(p); printf("%d \n",num); printf("二叉树的层序遍历\n"); Level_Order_Travel(p); printf("\n"); printf("二叉树的中序遍历:非递归\n"); InOrder_Travel(p); printf("\n"); return 0; }
测试结果:
代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define inf 99999999 struct HuffmanNode{ int weight; int lchild,rchild,parent; }; void Select(struct HuffmanNode *p,int n,int& num1,int& num2){ int i; int min1,min2; min1=inf; for(i=1;i<=n;i++){ //在还没有被选择的节点中,选择最小的节点 if(p[i].parent==0&&p[i].weight<min1){ min1=p[i].weight; } } for(i=1;i<=n;i++){ if(p[i].parent==0&&p[i].weight==min1){//找到该节点的序号 num1=i; p[i].parent=1;//将其父母置为非空,表明这个节点已经被选 break; } } min2=inf; for(i=1;i<=n;i++){ //在还没有被选择的节点中,选择次小的节点 if(p[i].parent==0&&p[i].weight<min2){ min2=p[i].weight; } } for(i=1;i<=n;i++){ if(p[i].parent==0&&p[i].weight==min2){ //找到该节点的序号 num2=i; p[i].parent=1;//将其父母置为非空,表明这个节点已经被选 break; } } } void Huffman_Coding(int n,struct HuffmanNode* &head,char** &HC){ int m,i,s1,s2;//构造赫夫曼树 if(n<1) printf("无法构造赫夫曼树\n"); m=2*n-1; head=(struct HuffmanNode *)malloc((m+1)*sizeof(struct HuffmanNode));//0号元素不用 for(i=1;i<=m;i++){ if(i<=n) scanf("%d",&head[i].weight); else head[i].weight=0; head[i].lchild=0; head[i].rchild=0; head[i].parent=0; } for(i=n+1;i<=m;i++){ Select(head,i-1,s1,s2); head[s1].parent=i; head[s2].parent=i; head[i].lchild=s1; head[i].rchild=s2; head[i].weight=head[s1].weight+head[s2].weight; } char *cd; int start,c,f; //对赫夫曼树进行编码 HC=(char **)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=head[i].parent;f!=0;c=f,f=head[f].parent){ if(head[f].lchild==c) cd[--start]=‘0‘; else cd[--start]=‘1‘; } HC[i]=(char *)malloc((n-start)*sizeof(char)); strcpy(HC[i],&cd[start]); } free(cd); } int main() { int n,i; struct HuffmanNode *head; char **HC; printf("请输入赫夫曼树的节点个数\n"); scanf("%d",&n); Huffman_Coding(n,head,HC); printf("输出赫夫曼树的编码\n"); for(i=1;i<=n;i++){ printf("%s\n",HC[i]); } return 0; }
测试结果:
二叉树的基本操作(含Huffman树)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。