实验报告3 树
1)顺序二叉树
#include <iostream> #include <stdlib.h> #include <stdio.h> #include <string> #include <string.h> #include <math.h> #define MAXSIZE 20 //顺序二叉树 using namespace std; typedef int Elemtype; typedef struct SqBinode { Elemtype data[MAXSIZE]; } SqBinode,SqBiTree; typedef struct { int level;//第几层 int order;//本层序号,(level,order)类似于(i,j) } position; void initBiTree(SqBiTree &bt) { for (int i=0; i<MAXSIZE; i++) { bt.data[i]=NULL; } } int createBiTree(SqBiTree &bt) { cout<<"无节点处请输入0,输入完毕请输入-999"<<endl; int i=0,n; cin>>n; while (n!=-999&&i<=MAXSIZE) { bt.data[i]=n; i++; if (i!=0&&bt.data[(i+1)/2-1]==NULL&&bt.data[i]!=NULL) { cout<<"存在双亲为空且自身为空且不为根节点的点!"<<endl; return 0; } cin>>n; } if (i>MAXSIZE) return 0; return 1; } int BiTreeEmpty(SqBiTree bt) { if (bt.data[0]==NULL) return 1; else return 0; } int BiTreeDepth(SqBiTree bt) { int n=0,i=0;//N为节点个数 for (i=0;i<MAXSIZE-1;i++) { if (bt.data[i]!=NULL) n++; } int k=0; do { k++; } while (pow(2,k-1)<=n); return k-1; } Elemtype Root(SqBiTree bt) { if (bt.data[0]) return bt.data[0]; else return 0; } void initPosition(position &p,int a,int b) { p.level=a; p.order=b; } void Value(SqBiTree bt,Elemtype &e,position p) { //根据E的位置P找到它 int n=pow(2,p.level-1)+p.order-2; e=bt.data[n]; } void Assign(SqBiTree &bt,position &p,Elemtype e) { int x=pow(2,p.level-1)+p.order-2; bt.data[x]=e; } void print(SqBiTree bt) { int i,j,k=0; for (i=1;i<=BiTreeDepth(bt); i++) { cout<<"第"<<i<<"层"; for (j=1; j<=pow(2,i-1); j++) { if (bt.data[k]!=NULL) cout<<"("<<j<<","<<bt.data[k]<<") "; k++; } cout<<endl; } } void valueP(int i,int j,position &p) { p.level=i; p.order=j; } int Parent(SqBiTree &bt,Elemtype e) { if (bt.data[0]==e) return NULL; int i=1; while (bt.data[i]!=e && i<=MAXSIZE-1) i++; return bt.data[(i+1)/2-1]; } int LeftChild(SqBiTree &bt,Elemtype e) { //1.叶子结点无左孩子 2.非叶子结点的左孩子是2*i int i=0; while (bt.data[i]!=e && i<=MAXSIZE-1) i++; //循环停止时应当是找到了值为E的结点,但不知道是叶子节点还是非叶子 if (bt.data[2*i+1]!=NULL) return bt.data[2*i+1]; else return NULL; } int RightChild(SqBiTree &bt,Elemtype e) { //1.叶子结点无左孩子 2.非叶子结点的左孩子是2*i int i=0; while (bt.data[i]!=e && i<=MAXSIZE-1) i++; //循环停止时应当是找到了值为E的结点,但不知道是叶子节点还是非叶子 if (bt.data[2*i+2]!=NULL) return bt.data[2*i+2]; else return NULL; } int LeftSibling(SqBiTree &bt,Elemtype e) { int i=0; if (!bt.data[0]) return NULL;//空树不用查找 if (bt.data[0]==e) return NULL;//根节点没有左兄弟 while (bt.data[i]!=e && i<=MAXSIZE-1) i++; //1.左兄弟为-1 2. 为最左侧的一列,没有左兄弟 if (i%2==0) return bt.data[i-1];//序号为偶节点才有左兄弟 else return NULL; } int RightSibling(SqBiTree &bt,Elemtype e) { int i=0; if (!bt.data[0]) return NULL;//空树不用查找 if (bt.data[0]==e) return NULL;//根节点没有左兄弟 while (bt.data[i]!=e && i<=MAXSIZE-1) i++; //1.左兄弟为-1 2. 为最左侧的一列,没有左兄弟 if (i%2!=0) return bt.data[i+1];//序号为偶节点才有左兄弟 else return NULL; } void Move(SqBiTree &bt,int k,SqBiTree &q,int g) { if (bt.data[2*k+1]!=NULL) //左孩子不空 Move(bt,2*k+1,q,2*g+1); if (bt.data[2*k+2]!=NULL)//右孩子不空 Move(bt,2*k+2,q,2*g+2); q.data[g]=bt.data[k]; bt.data[k]=NULL; } int InsertChild(SqBiTree &bt,Elemtype e,int LR,SqBiTree &c) { //1.找到E所在结点的序号 int i =0; while (bt.data[i]!=e &&i<=MAXSIZE-1 ) i++; int k=2*i+LR+1;//得到E结点的LR孩子的序号 if (bt.data[k])//如果LR结点存在,需要转移到C的右子树,也就是K结点的右子树 Move(bt,k,bt,2*k+2); Move(c,0,bt,k); return 1; } void del(SqBiTree &bt ,int k) { //删除bt的k结点作为根结点的非空树 if (!bt.data[2*k+1])//左子树非空 del(bt,2*k+1); if (!bt.data[2*k+2]) del(bt,2*k+2); bt.data[k]=NULL; } int DeleteChild(SqBiTree &bt,Elemtype e,int lr) { //删除e元素对应的左或右子树 //1 find the number of e int i=0; while (bt.data[i]!=e &&i<=MAXSIZE-1) i++; //2 找到要删除的左或右子树 int k =2*i+1+lr; if (bt.data[k]!=NULL) //非空则删除 del(bt,k); else { cout<<"不存在左或右子树,无法删除"<<endl; return 0; } } void PreOrder(SqBiTree &bt ,int i) { cout<<bt.data[i]<<" "; if (bt.data[2*i+1])//左子树非空 PreOrder(bt,2*i+1); if (bt.data[2*i+2])//右子树非空 PreOrder(bt,2*i+2); } int PreOrderTraverse(SqBiTree &bt) { int i=0; if (bt.data[i]) PreOrder(bt,i);//遍历左子树 else { cout<<"此树为空,不能遍历"<<endl; return 0; } return 1; } void InOrder(SqBiTree &bt ,int i) { if (bt.data[2*i+1])//左子树非空 PreOrder(bt,2*i+1); cout<<bt.data[i]<<" "; if (bt.data[2*i+2])//右子树非空 PreOrder(bt,2*i+2); } int InOrderTraverse(SqBiTree &bt) { int i=0; if (bt.data[i]) InOrder(bt,i);//遍历左子树 else { cout<<"此树为空,不能遍历"<<endl; return 0; } return 1; } void PostOrder(SqBiTree &bt ,int i) { if (bt.data[2*i+1])//左子树非空 PostOrder(bt,2*i+1); if (bt.data[2*i+2])//右子树非空 PostOrder(bt,2*i+2); cout<<bt.data[i]<<" "; } int PostOrderTraverse(SqBiTree &bt) { int i=0; if (bt.data[i]) PostOrder(bt,i);//遍历左子树 else { cout<<"此树为空,不能遍历"<<endl; return 0; } return 1; } int main() { cout<<"---顺序二叉树的基本操作实现 twomeng---"<<endl; cout<<"--------------------------------------"<<endl; cout<<"1 InsertChild()"<<endl; cout<<"2 DeleteChild()"<<endl; cout<<"3 PreOrderTraverse()"<<endl; cout<<"4 InOrderTraverse()"<<endl; cout<<"5 PostOrderTraverse()"<<endl; cout<<"6 Parent()"<<endl; cout<<"7 LeftChild()"<<endl; cout<<"8 RightChild()"<<endl; cout<<"9 leftSibling()"<<endl; cout<<"10 RightSibling()"<<endl; cout<<"11 Root()"<<endl; cout<<"12 Value()"<<endl; cout<<"13 Assign()"<<endl; cout<<"--------------------------------------"<<endl; ll1:cout<<"请输入您选择的函数序号:)"<<endl; int number; cin>>number; SqBiTree bt; initBiTree(bt); createBiTree(bt);//创建一个可以公用的二叉树bt Elemtype e;position p; switch(number){ case 1: SqBiTree c; initBiTree(c); createBiTree(c); InsertChild(bt,3,1,c); print(bt); break; case 2: DeleteChild(bt,3,1); print(bt); break; case 3: PreOrderTraverse(bt); break; case 4: InOrderTraverse(bt); break; case 5: PostOrderTraverse(bt); break; case 6: cout<<"输入E的值"<<endl; cin>>e; cout<<Parent(bt,e); break; case 7: cout<<"输入E的值"<<endl; cin>>e; cout<<LeftChild(bt,e); break; case 8: cout<<"输入E的值"<<endl; cin>>e; cout<<RightChild(bt,e); break; case 9: cout<<"输入E的值"<<endl; cin>>e; cout<<LeftSibling(bt,e); break; case 10: cout<<"输入E的值"<<endl; cin>>e; cout<<RightSibling(bt,e); break; case 11: cout<<Root(bt); break; case 12: cout<<"请输入P的位置(level,order)"<<endl; int a,b; cin>>a>>b; initPosition(p,a,b); Value(bt,e,p); cout<<e<<endl; break; case 13: cout<<"请输入P的位置(level,order)和E的值"<<endl; cin>>a>>b>>e; initPosition(p,a,b); Assign(bt,p,e); print(bt); break; } cout<<"您是否想要继续调用函数?yes/no"<<endl; string s;cin>>s; if (!s.compare("yes")) goto ll1; else return 0; }
链式二叉树
1.实验内容
1.输入字符序列,建立二叉链表。 1
2.中序遍历二叉树:递归算法。3
3.中序遍历二叉树:非递归算法。(最好也能实现先序,后序非递归算法)4
4.求二叉树的高度 。1
5.求二叉树的叶子个数。1
*6.将二叉链表视为森林的孩子兄弟链表,计算森林中叶子个数。1
*7.建立中序线索二叉树,并实现中序遍历。1
8.借助队列实现二叉树的层次遍历。1
9.在主函数中设计一个简单的菜单,分别调试上述算法。1
*10.综合训练:为N个权值设计哈夫曼编码。
#include <iostream> #include <stdlib.h> #include <stdio.h> #include <string> #include <string.h> #include <math.h> #define MAXSIZE 10 //链式二叉树 using namespace std; typedef char Elemtype; typedef struct BiTNode{ Elemtype data; struct BiTNode *left,*right; }BiTNode,*BiTree; void InitBiTree(BiTree &bt) { bt=NULL;//构造空的二叉树 } void CreateBiTree(BiTree &bt) { Elemtype e; scanf("%c",&e); if (e==' ') { bt=NULL;//如果输入空格则将该结点置空 } else { bt=(BiTree)malloc(sizeof(BiTNode)); bt->data=e; CreateBiTree(bt->left); CreateBiTree(bt->right); } } void PreOrderTraverse(BiTree &bt) { if (bt!=NULL) { printf("%c",bt->data); PreOrderTraverse(bt->left); PreOrderTraverse(bt->right); } } void InOrderTraverse(BiTree &bt) { if (bt)//如果是空则不用遍历左右子树,如果不空则遍历 { InOrderTraverse(bt->left); printf("%c",bt->data); InOrderTraverse(bt->right); } } void PostOrderTraverse(BiTree &bt ) { if (bt) { PostOrderTraverse(bt->left); PostOrderTraverse(bt->right); printf("%c",bt->data); } } void LevelOrderTraverse(BiTree &bt) { BiTree q[MAXSIZE];//指针数组 int front,rear; //初始化队列 front=rear=-1; if (bt) { rear=(rear+1)%MAXSIZE; q[rear]=bt;//安置根节点 //不断循环,直到队空为止 while (front!=rear) { //如果队不空,队头出队 front=(front+1)%MAXSIZE; printf("%c",q[front]->data); //左右孩子不空则入队 if (q[front]->left) { rear=(rear+1)%MAXSIZE; q[rear]=q[front]->left;//安置根节点 } if (q[front]->right) { rear=(rear+1)%MAXSIZE; q[rear]=q[front]->right;//安置根节点 } } } } int BiTreeEmpty(BiTree &bt) { if (!bt) return 1; } int BiTreeDepth(BiTree &bt) { int depth=0; int depthL,depthR; if (!bt) depth=0; else { depthL=BiTreeDepth(bt->left); depthR=BiTreeDepth(bt->right); depth=1+(depthL>depthR?depthL:depthR); } return depth; } Elemtype Root (BiTree &bt) { if (bt) { return bt->data; } else return 0; } Elemtype Value(BiTree &p) { //P是二叉树中某个节点 return p->data; } void Assign(BiTree &bt,Elemtype e) { bt->data=e; } Elemtype Parent(BiTree &bt,Elemtype e) { //e为二叉树bt中的某个节点,输出他的双亲 BiTree q[MAXSIZE],p; int rear,front; rear=front =-1 ; if (bt) { rear=(rear+1)%MAXSIZE; q[rear]=bt;//根节点入队 while (rear!=front) { //如果队不空则队头出队 front=(front+1)%MAXSIZE; p=q[front]; if (p && p->left->data ==e || p && p->right->data == e ) { //如果P本身不空并且有一个孩子等于E,则返回该双亲节点的值 return p->data; } //说明这次没有找到和E相等的节点,则把左孩子和右孩子送入队列 if (p->left) { rear=(rear+1)%MAXSIZE; q[rear]=p->left; } if (p->right) { rear=(rear+1)%MAXSIZE; q[rear]=p->right; } } } } BiTree findE(BiTree &bt,Elemtype e) { BiTree q[MAXSIZE],p; int rear,front; rear=front=-1; if (bt) { rear=(rear+1)%MAXSIZE; q[rear]=bt;//根入队 while (front!=rear) { front=(front+1)%MAXSIZE; p=q[front];//取出队头元素 if (p->data == e) { return p; } if (p->left) { rear=(rear+1)%MAXSIZE; q[rear]=p->left;//left child enqueue } if (p->right) { rear=(rear+1)%MAXSIZE; q[rear]=p->right;//left child enqueue } } } } Elemtype LeftChild( BiTree &bt,Elemtype e) { //找到指向E的指针 BiTree p=findE(bt,e); if (p &&p->left ) {//P不为空并且左孩子不为空 return p->left->data; } else return 0; } Elemtype RightChild( BiTree &bt,Elemtype e) { //找到指向E的指针 BiTree p=findE(bt,e); if (p &&p->right ) {//P不为空并且左孩子不为空 return p->right->data; } else return 0; } BiTree findP(BiTree &bt,Elemtype e) { //e为二叉树bt中的某个节点,输出他的双亲 BiTree q[MAXSIZE],p; int rear,front; rear=front =-1 ; if (bt) { rear=(rear+1)%MAXSIZE; q[rear]=bt;//根节点入队 while (rear!=front) { //如果队不空则队头出队 front=(front+1)%MAXSIZE; p=q[front]; if (p && p->left->data ==e || p && p->right->data == e ) { //如果P本身不空并且有一个孩子等于E,则返回该双亲节点的值 return p; } //说明这次没有找到和E相等的节点,则把左孩子和右孩子送入队列 if (p->left) { rear=(rear+1)%MAXSIZE; q[rear]=p->left; } if (p->right) { rear=(rear+1)%MAXSIZE; q[rear]=p->right; } } } } Elemtype LeftSibling(BiTree &bt,Elemtype e) { BiTree parent = findP(bt,e);//找到E元素的双亲指针 if (parent->left) { return parent->left->data; } } Elemtype RightSibling(BiTree &bt,Elemtype e) { BiTree parent = findP(bt,e);//找到E元素的双亲指针 if (parent->right) { return parent->right->data; } } int InsertChild(BiTree &p ,int lr,BiTree &c) {//插入更简单了!! if (p) { if (lr==0)//把C移到P的左子树上 { c->right=p->left; p->left=c; }else { c->right=p->right; p->right=c; } return 1; } else return 0;//P为空 } void clearBiTree(BiTree &bt) { //同样用递归! if (bt) { if (bt->left) clearBiTree(bt->left); if (bt->right) clearBiTree(bt->right); free(bt); bt=NULL; } } void DeleteChild(BiTree &p,int LR) { // 初始条件: 二叉树T存在,p指向T中某个结点,LR为0或1 // 操作结果: 根据LR为0或1,删除T中p所指结点的左或右子树 if (p) { if (LR == 1) { clearBiTree(p->left); }else { clearBiTree(p->right); } } } //非递归实现pre/in/post 遍历二叉树 //使用栈实现中序遍历 typedef BiTree Elemtype1; typedef struct { Elemtype1 elem[MAXSIZE]; int top; }SeqStack; void initSeqStack(SeqStack &s){ s.top=-1; } int stackEmpty(SeqStack &s){ if (s.top==-1) return 1; return 0;//或者返回 表达式的真值return s.top==-1; } int push(SeqStack &s,Elemtype1 e){ if (s.top>=MAXSIZE-1) return 0; else { s.top++; s.elem[s.top]=e; return 1; } } int pop(SeqStack &s,Elemtype1 &e){ if (s.top==-1) return 0; else { e=s.elem[s.top]; s.top--; return 1; } } int gettop(SeqStack &s,Elemtype1 &e){ if (s.top==-1) return 0; else { e=s.elem[s.top]; return 1; } } //中序遍历非递归算法 void InOrderTraverse2(BiTree &bt) { //精髓是把每个结点的地址存入栈中,通过push & pop实现过程 SeqStack s; initSeqStack(s); BiTree p=bt; while (p!=NULL || !stackEmpty(s)) { //当且仅当两者都空时结束循环 if (p) { push(s,p); p=p->left; } else { pop(s,p);//弹回根节点 printf("%c ",p->data);//第二次回到根节点时才打印输出 p=p->right; } } } //先序遍历非递归算法 void PreOrderTraverse2(BiTree p) { //这里不加&即为形参,便不用定义新的变量作为移动的指针了 SeqStack s; initSeqStack(s); do { if (p) { printf("%c ",p->data); push(s,p); p=p->left; } else { pop(s,p); p=p->right; } }while (p || !stackEmpty(s)); } //后序遍历非递归算法 void PostOrderTraverse2(BiTree p) { struct { BiTree pp;//pointer int tag;//标记位 }s[MAXSIZE];//定义一个结构体数组,即为一个栈s //这里struct之前不能加typedef ,因为s[]是结构体数组而不是别名 int top=0;//栈顶指针 while ( p || top>0) { while (p)//一直走到最左边 { top++; s[top].pp=p; s[top].tag=0; p=p->left; } if (top>0) { if (s[top].tag == 0) { //如果栈顶元素标志位为0,即为第二次遇到该结点元素 s[top].tag=1; p=s[top].pp; p=p->right;//继续向右孩子深入 } else { p=s[top].pp; printf("%c ",p->data);//如果是第二次遇到该节点则输出 top--; p=NULL;//不用往深处走了,直接退栈继续循环 } } } } //找到叶子结点个数,左右孩子都空 int findleaf(BiTree p,int &count1) { if (p) { if ( !p->left &&!p->right) count1++; findleaf(p->left,count1); findleaf(p->right,count1); } } int findrightleaf(BiTree p,int &count1) { if (p) { if (!p->right) count1++; findleaf(p->left,count1); findleaf(p->right,count1); } } void PreOrderfindall(BiTree &bt,int &count2) { if (bt!=NULL) { count2++; PreOrderfindall(bt->left,count2); PreOrderfindall(bt->right,count2); } } int findleafinforest(BiTree &bt) { //假设bt代表一个森林,求森林中叶子的个数 //利用理论:假设森林中有N个非终端结点,则二叉树中右指针域为空的结点个数为N+1 if (bt) { int count1 = 0; findrightleaf(bt,count1); //count即为二叉树中右指针域为空的结点的个数 int count2=0; PreOrderfindall(bt,count2); //count2即为二叉树中所有节点的个数,也就是森林总结点个数 return (count2-count1+1); } else return 0; } //建立中序线索二叉树并遍历 typedef enum PointerTag {link=0,thread=1};//link=0 指针,thread=1 线索 typedef struct BithrNode{ Elemtype data; struct BithrNode *left,*right; PointerTag ltag,rtag; }BithrNode,*BithrTree; int InOrderThreading(BithrTree &thrt,BithrTree bt) { void Inthreading(BithrTree &p,BithrTree &pre); //将普通二叉树线索化成thrt //1.建立头结点 thrt = (BithrTree)malloc(sizeof(BithrNode)); BithrTree pre; thrt->right=thrt; thrt->ltag=link; thrt->rtag=thread; if (!bt) thrt->left=thrt; else { thrt->left = bt; pre=thrt;//前驱指针指向头结点 Inthreading(bt,pre); //线索化二叉树 pre->right=thrt; pre->rtag=thread; thrt->right=pre; //线索化最后pre指向树中最后一个结点,进行最后的处理:连接树中最后一个结点与头结点,形成循环的线索树 } } void Inthreading(BithrTree &p,BithrTree &pre) { if (p) { Inthreading(p->left,pre); if (!p->left)//P的左孩子为空 { p->ltag=thread; p->left=pre; } if (!pre->right)//Pre的右孩子为空 { pre->rtag=thread; pre->right=p; } pre=p; Inthreading(p->right,pre); } } //遍历线索二叉树 int InOrderTraverseThrtree(BithrTree &thrt) { BithrTree p=thrt->left; while (p != thrt) { //线索树不为空时 while(p && p->ltag !=thread) { p=p->left; } printf("%c",p->data); while(p->rtag == thread && p->right != thrt) { //如果p->right==T,则不用继续往右走 p=p->right; printf("%c",p->data); } p=p->right;//没有右线索,只有右孩子 } } void CreateBithrTree(BithrTree &bt) { Elemtype e; scanf("%c",&e); if (e==' ') { bt=NULL;//如果输入空格则将该结点置空 } else { bt=(BithrTree)malloc(sizeof(BithrNode)); bt->data=e; CreateBithrTree(bt->left); CreateBithrTree(bt->right); } } int main() { cout<<"---二叉树的基本操作实现 twomeng---"<<endl; cout<<"--------------------------------------"<<endl; cout<<"1 InsertChild()"<<endl; cout<<"2 DeleteChild()"<<endl; cout<<"3 PreOrderTraverse()"<<endl; cout<<"4 InOrderTraverse()"<<endl; cout<<"5 PostOrderTraverse()"<<endl; cout<<"6 Parent()"<<endl; cout<<"7 LeftChild()"<<endl; cout<<"8 RightChild()"<<endl; cout<<"9 leftSibling()"<<endl; cout<<"10 RightSibling()"<<endl; cout<<"11 Root()"<<endl; cout<<"12 Value()"<<endl; cout<<"13 Assign()"<<endl; cout<<"14 LevelOrderTraverse()"<<endl; cout<<"15 BiTreeDepth()"<<endl; cout<<"16 findleaf()"<<endl; cout<<"17 PreOrderTraverse2()"<<endl; cout<<"18 InOrderTraverse2()"<<endl; cout<<"19 PostOrderTraverse2()"<<endl; cout<<"20 findleafinforest()"<<endl; cout<<"21 线索化二叉树并中序遍历输出"<<endl; cout<<"--------------------------------------"<<endl; ll1:cout<<"请输入您选择的函数序号:)"<<endl; int number; cin>>number; BiTree bt,p; InitBiTree(bt); Elemtype e;int count3 = 0; cout<<"请按照先序顺序输入一棵树!没有结点的地方请输入空格"<<endl; fflush(stdin); CreateBiTree(bt);//创建一个可以公用的二叉树bt; switch(number) { case 1: PreOrderTraverse(bt); BiTree c; InitBiTree(c); cout<<"请按照先序顺序输入一棵Insert树!没有结点的地方请输入空格"<<endl; fflush(stdin); CreateBiTree(c); LevelOrderTraverse(c); cout<<"输入完毕!"<<endl; cout<<"如果您想插入到左子树,输入0;如果您想插入到右子树,输入1 "<<endl; int x;cin>>x; InsertChild(bt,x,c); PreOrderTraverse(bt); break; case 2: PreOrderTraverse(bt); cout<<endl; cout<<"删除左子树,请输入1;删除右子树,请输入0"<<endl; cin>>x; DeleteChild(bt,x); PreOrderTraverse(bt); break; case 3: PreOrderTraverse(bt); break; case 4: InOrderTraverse(bt); break; case 5: PostOrderTraverse(bt); break; case 6: char ch; cout<<"请输入您要寻找的节点数值"<<endl; cin>>ch; cout<<Parent(bt,ch); break; case 7: cout<<"输入E的值"<<endl; cin>>e; cout<<LeftChild(bt,e); break; case 8: cout<<"输入E的值"<<endl; cin>>e; cout<<RightChild(bt,e); break; case 9: cout<<"输入E的值"<<endl; cin>>e; cout<<LeftSibling(bt,e); break; case 10: cout<<"输入E的值"<<endl; cin>>e; cout<<RightSibling(bt,e); break; case 11: cout<<Root(bt); break; case 12: p=bt->left; cout<<Value(p)<<endl; break; case 13: p=bt->left; cout<<"请输入您要赋的值"<<endl; cin>>e; Assign(p,e); cout<<"assign函数调用成功!其中的值现在为:"<<endl; cout<<p->data<<endl; break; case 14: LevelOrderTraverse(bt); break; case 15: cout<<BiTreeDepth(bt)<<endl; break; case 16: findleaf(bt,count3); cout<<count3<<endl; break; case 17: PreOrderTraverse2(bt); break; case 18: InOrderTraverse2(bt); break; case 19: PostOrderTraverse2(bt); break; case 20: cout<<findleafinforest(bt)<<endl; break; case 21: BithrTree bt; CreateBithrTree(bt); BithrTree thrt; cout<<"线索化二叉树成功!"<<endl; InOrderThreading(thrt,bt); InOrderTraverseThrtree(thrt); cout<<"遍历线索二叉树成功!"<<endl; break; } cout<<"您是否想要继续调用函数?yes/no"<<endl; string s;cin>>s; if (!s.compare("yes")) goto ll1; else return 0; }
我这个哈夫曼树貌似有点问题,结果不太对啊。。有空再调一调
哈夫曼测试数据:
8 5 29 7 8 14 23 3 11 未调试出来的哈夫曼:
#include <iostream> #include <stdlib.h> #include <stdio.h> #include <string> #include <string.h> #include <math.h> #define MAXSIZE 20 using namespace std; //哈夫曼编码 typedef struct { unsigned int weight; unsigned int parent,lchild,rchild; }HTNode,*HuffmanTree; typedef char* *Huffmancode;//定义一个指针数组存放编码 int min(HuffmanTree t,int i) { // 函数void select()调用 int j,flag; unsigned int k=UINT_MAX; // 取k为不小于可能的值 for(j=1;j<=i;j++) if(t[j].weight<k&&t[j].parent==0) k=t[j].weight,flag=j; t[flag].parent=1; return flag; } void select(HuffmanTree t,int i,int &s1,int &s2) { // s1为最小的两个值中序号小的那个 int j; s1=min(t,i); s2=min(t,i); if(s1>s2) { j=s1; s1=s2; s2=j; } } void HuffmanCoding(HuffmanTree &ht,Huffmancode &hc,int *w,int n) { int i; if (n<=1) return;//判断N(字符个数)的输入是否合法 int m;//哈夫曼树结点个数 m = 2*n-1; //哈夫曼树是一个数组,我们要先定义出来, 再初始化数组 ht = (HuffmanTree )malloc((m+1)*sizeof(HTNode));//0 单元未用 //给初始字符赋权值 HuffmanTree p; p=ht; p++; int *t;t=w; for (i=1,t++;i<=n;i++,p++,t++) { (*p).weight=*t; (*p).lchild=0; (*p).rchild=0; (*p).parent=0; } //给还没计算的结点赋值0 for (p=&ht[n+1],i=n+1;i<=m;i++,p++) { (*p).weight=0; (*p).lchild=0; (*p).rchild=0; (*p).parent=0; } //建立哈夫曼树 for(int i=n+1;i<=m;i++) { int s1,s2; select(ht,i-1,s1,s2);//最小的两个结点序号为s1,s2 ht[s1].parent=i; ht[s2].parent=i; ht[i].lchild=s1; ht[i].rchild=s2; ht[i].weight=ht[s1].weight+ht[s2].weight; } //show() // for (i=1 ; i<=m ; i++) // { // cout<< ht[i].weight <<" " <<ht[i].parent <<" "<<ht[i].lchild <<" "<<ht[i].rchild<<endl; // } //进行哈夫曼编码 int c,f; hc=(Huffmancode)malloc(sizeof(char *)*(n+1));//头指针向量 char *cd = (char *)malloc(sizeof(char)*n);//一个字符编码的数组指针 cd[n-1]='\0'; for (int i=1;i<=n;i++)//循环N个字符 { int start = n-1;//从叶节点开始往上编 for (c=i,f=ht[i].parent;f!=0;c=f,f=ht[f].parent) { //定义C是为了不动I,顺次往上找双亲,判断自己是双亲的左子树还是右子树 if (ht[f].lchild == c) cd[--start]='0'; else cd[--start]='1'; } for (int x = n-start;x<n;x++) cout<<cd[x]; hc[i]=(char *)malloc((n-start)*sizeof(char)); strcpy(hc[i],cd); //cout<<hc[i]<<endl; } } int main() { int *w,*ww; int n; cout<<"请输入字符数N"<<endl; cin>>n; w=(int *)malloc(sizeof(int)*(n+1));//0号单元未用 ww=w; int i; cout<<"请依次输入字符的权值"<<endl; for (ww++,i=1;i<=n;i++,ww++) { cin>> *ww; } HuffmanTree ht; Huffmancode hc; HuffmanCoding(ht,hc,w,n); Huffmancode q=hc; for (int k=1;k<=n;k++) puts(hc[k]); return 0; }