数据结构试验源码

来源:互联网 发布:号码追逐软件 编辑:程序博客网 时间:2024/05/18 01:27

 

数据结构课程的二叉树和哈弗曼实验

BTNode.h

template<class T>struct BTNode{BTNode(){lChild=rChild=NULL;}BTNode(const T& x){element=x;lChild=rChild=NULL;}BTNode(const T& x,BTNode<T>* l,BTNode<T>* r){element=x;lChild=l;rChild=r;}T element;BTNode<T>* lChild,*rChild;};
/////BinaryTree.h#include<iostream.h>#include "Node.h"#include<queue>template<class T>//BinaryTree's public and private functionsclass BinaryTree{public:BinaryTree(){ root=NULL; }//~BinaryTree( );bool IsEmpty()const{return root==NULL;}void Clear();bool Root(T& x)const;T GetRoot(T& x);void MakeTree(const T& x,BinaryTree<T>& left,BinaryTree<T>& right);void BreakTree(T& x,BinaryTree<T>& left,BinaryTree<T>& right);void PreOrder();void InOrder();void PostOrder();void LevelOrder();int Size();int Node1Sum();int Height();void ChangeChild();BTNode<T>* Copy(BTNode<T>* t);protected:BTNode<T> *root;private:void Clear(BTNode<T>* r);void PreOrder(BTNode<T>*t);void InOrder(BTNode<T>*t);void PostOrder(BTNode<T>*t);void LevelOrder(BTNode<T>*t);int Size(BTNode<T> * t);int Height(BTNode<T>* t);int Node1Sum(BTNode<T>* t,int sum);void ChangeChild(BTNode<T>* t);};//we can get the root code's elementtemplate<class T>T BinaryTree<T>::GetRoot(T& x){   x=root->element;   return x;}//this interface function can change the BinaryTree's left and right children through next private functiontemplate<class T>void BinaryTree<T>::ChangeChild(){ChangeChild(root);}template<class T>void BinaryTree<T>::ChangeChild(BTNode<T> *t){BTNode<T> *temp;if(t){temp=t->lChild;t->lChild=t->rChild;t->rChild=temp;}if(t->lChild)ChangeChild(t->lChild);if(t->rChild)ChangeChild(t->rChild);}//this interface can get the BinaryTree's height by using the next private functiontemplate<class T>int BinaryTree<T>::Height(){return Height(root);}template<class T>int BinaryTree<T>::Height(BTNode<T> *t){if(t){int h1=Height(t->lChild)+1;int h2=Height(t->rChild)+1;return h1>h2?h1:h2;}return 0;}//this interface can disguish whether have root nodetemplate<class T>bool BinaryTree<T>::Root(T& x)const{if(root){x=root->element;return true;}else return false;}//we can make a Binarytree by using this functiontemplate<class T>void BinaryTree<T>::MakeTree(const T& x, BinaryTree<T>& left,BinaryTree<T>& right){if(root||&left==&right) return;root=new BTNode<T>(x,left.root,right.root);left.root=right.root=NULL;}template<class T>void BinaryTree<T>::BreakTree(T& x,BinaryTree<T>& left,BinaryTree<T>& right){if(!root||&left==&right||left.root||right.root)return;x=root->element;left.root=root->lChild;right.root=root->rChild;delete root;root=NULL;}template<class T>void BinaryTree<T>::PreOrder(){PreOrder(root);}template<class T>void BinaryTree<T>::PreOrder(BTNode<T>* t){if(t){cout<<t->element;PreOrder(t->lChild);PreOrder(t->rChild);}}template<class T>void BinaryTree<T>::InOrder(){InOrder(root);}template<class T>void BinaryTree<T>::InOrder(BTNode<T>* t){if(t){InOrder(t->lChild);cout<<t->element;InOrder(t->rChild);}}template<class T>void BinaryTree<T>::PostOrder(){PostOrder(root);}template<class T>void BinaryTree<T>::PostOrder(BTNode<T>* t){if(t){PostOrder(t->lChild);PostOrder(t->rChild);cout<<t->element<<" ";}}template<class T>void BinaryTree<T>::LevelOrder(){LevelOrder(root);}template<class T>void BinaryTree<T>::LevelOrder(BTNode<T> *t){queue<BTNode<T>* > q;if(t)        q.push(t);    cout<<"LevelOrder:";    while(q.size()>0)    {        BTNode<T>* u=q.front();        q.pop();        cout<<u->element<<" ";        if(u->lChild)            q.push(u->lChild);        if(u->rChild)            q.push(u->rChild);    }}//get the BinaryTree's nodes' numbertemplate<class T>int BinaryTree<T>::Size(){return Size(root);}template<class T>int BinaryTree<T>::Size(BTNode<T> * t){if(!t)return 0;elsereturn Size(t->lChild)+Size(t->rChild)+1;}//copy a BinaryTreetemplate<class T>BTNode<T>* BinaryTree<T>::Copy(BTNode<T>* t){if(!t)return NULL;BTNode<T>* q=new BTNode<T>(t->element);q->lChild=Copy(t->lChild);q->rChild=Copy(t->rChild);return q;}//destory a treetemplate<class T>void BinaryTree<T>::Clear(){Clear(root);}template<class T>void BinaryTree<T>::Clear(BTNode<T>* r){if(r){Clear(r->lChild);Clear(r->rChild);Clear(r);}}//get the number of who has one child nodetemplate<class T>int BinaryTree<T>::Node1Sum(){return Node1Sum(root,0);}template<class T>int BinaryTree<T>::Node1Sum(BTNode<T> *t,int sum){if(t){if((t->lChild&&t->rChild==NULL)&&(t->rChild&&t->lChild==NULL)){sum++;}Node1Sum(t->lChild,sum);Node1Sum(t->rChild,sum);}return sum;}


 

#ifndef S_HFMTREE#define S_HFMTREE////HfmTree.h#include "BTree.h"#include "prioQueue.h"#include<fstream.h>template<class T>class HfmTree:public BinaryTree<T>{public:operator T () const {return weight;}T getW(){return weight;}void putW(const T& x){weight=x;}void SetNull(){root=NULL;}void CreateHfmTree(T w[],int n);bool MakeCode(char ch[],T w[],BTNode<T>* p[],char* code[],int n);bool CalCoding(char ch[], T w[], BTNode<T>* p[], char* code[], int n);BTNode<T>* TranCoding(char *code)const;T AntiCoding();private:T weight;void MakeCode(BTNode<T> *r,int n,char ch[],T w[],BTNode<T>* p[],char **code,bool b[],int top,char stack[]);void CalCoding(BTNode<T>* r, char ch[], T w[], BTNode<T>* p[], char* code[], bool b[], char stack[], int top, int n);BTNode<T>* TranCoding(BTNode<T>* r, char *code) const;T AntiCoding(char *code[]);};template<class T>T HfmTree<T>::AntiCoding(){AntiCoding();}template<class T>T HfmTree<T>::AntiCoding(char *code[]){char *stack=char ch[10];}//创造一颗hfmtreetemplate<class T>void HfmTree<T>::CreateHfmTree(T w[],int n){PrioQueue <HfmTree<T> > pq(n);HfmTree<T> x,y,z,zero;for(int i=0;i<n;i++){z.MakeTree(w[i],x,y);z.putW(w[i]);pq.Append(z);z.SetNull();}for(i=1;i<n;i++){pq.Serve(x);pq.Serve(y);z.MakeTree(x.getW()+y.getW(),x,y);z.putW(x.getW()+y.getW());pq.Append(z);z.SetNull();}pq.Serve(z);root=z.root;weight=z.weight;}//翻译编码template<class T>BTNode<T>* HfmTree<T>::TranCoding(char *code)const{if(NULL == root || '\0' == *code)return NULL;if(NULL == root->lChild && NULL == root->rChild)return root;if('0' == *code && NULL != root->lChild)return TranCoding(root->lChild,code+1);if('1' == *code && NULL != root->lChild)return TranCoding(root->rChild,code+1);return NULL;}template <class T>BTNode<T>* HfmTree<T>::TranCoding(BTNode<T>* r, char *code) const{if(NULL == r->lChild && NULL == r->rChild)return r;if('0' == *code && NULL != r->lChild)return TranCoding(r->lChild,code+1);if('1' == *code && NULL != r->rChild)return TranCoding(r->rChild,code+1);return NULL;}//生成编码template <class T>bool HfmTree<T>::CalCoding(char ch[], T w[], BTNode<T>* p[], char* code[], int n){bool* b = new bool[n];char* stack = new char[n];for(int i=0; i<n; i++){b[i] = true;}if(IsEmpty())return false;if(NULL == root->lChild && NULL == root->rChild)return false;CalCoding(root,ch,w,p,code,b,stack,-1,n);delete[] b;delete[] stack;return true;}template <class T>void HfmTree<T>::CalCoding(BTNode<T>* r, char ch[], T w[], BTNode<T>* p[], char* code[], bool b[], char stack[], int top, int n){if(NULL==r->lChild && NULL==r->rChild) // leaf node{int i;for(i=0; i<n; i++)if(r->element==w[i] && b[i])break;b[i] = false;p[i] = r;cout<<ch[i]<<" : ";code[i] = new char[top+1+1];for(int j=0; j<top+1; j++){cout<<stack[j];code[i][j] = stack[j];}cout<<endl;code[i][j] = '\0';}else // unleaf node{if(NULL != r->lChild){stack[++top] = '0';CalCoding(r->lChild, ch, w, p, code, b, stack, top, n);--top;}if(NULL != r->rChild){stack[++top] = '1';CalCoding(r->rChild, ch, w, p, code, b, stack, top, n);--top;}}}#endif


 

//PrioQueue.h#include "resultcode.h"template<class T>class PrioQueue{public:PrioQueue(int mSize=20);~PrioQueue(){delete[] q;}bool IsEmpty() const{return n==0;}bool IsFull() const{return n==maxSize;}void Append(const T &x);void Serve(T &x);void Output();private:void AdjustDown(int r,int j);void AdjustUp(int j);T *q;int n,maxSize;};template<class T>PrioQueue<T>::PrioQueue(int mSize){maxSize=mSize;n=0;q=new T[maxSize];}template<class T>void PrioQueue<T>::Append(const T &x){if(IsFull()) throw Overflow;q[n++]=x;AdjustUp(n-1);}template<class T>void PrioQueue<T>::Serve(T &x){if(IsEmpty()) throw Underflow;x=q[0];q[0]=q[--n];AdjustDown(0,n-1);}template<class T>void PrioQueue<T>::AdjustDown(int i,int j){int child=2*i+1;T temp=q[i];while(child<=j){if((child<j)&&(q[child]>q[child+1]))child++;if(temp<=q[child])break;q[(child-1)/2]=q[child];child=2*child+1;}q[(child-1)/2]=temp;temp.SetNull();}template<class T>void PrioQueue<T>::AdjustUp(int j){int i=j;T temp=q[i];while(i>0&&temp<q[(i-1)/2]){q[i]=q[(i-1)/2];i=(i-1)/2;}q[i]=temp;temp.SetNull();}template<class T>void PrioQueue<T>::Output(){for(int i=0;i<n;i++){cout<<q[i]<<" ";}}


 

// main.cpp//---------------------------------------------------------//----------------------------------------------------------// Include file//----------------------------------------------------------#include<fstream>#include<iostream.h>#include "HfmTree.h"using namespace std;//----------------------------------------------------------// External functions//----------------------------------------------------------void HCode(const char c[], char *code[], const int n);void TranCoding(const HfmTree<int> &ht, char c[], BTNode<int> *np[], char* code[]);void ShowFile();void HIntext();//----------------------------------------------------------// Helper functions//----------------------------------------------------------/* visit function for tracing the tree *//* Menu for main */void MMenu(){cout<<"\n\t主菜单:\n";cout<<"\t1\t二叉树的基本操作\n";cout<<"\t2\t哈夫曼系统\n";cout<<"\t0\t退出\n";cout<<"\n\t请输入选择:";}//----------------------------------------------------------// Binary tree contral//----------------------------------------------------------/* Menu for BTreeCtrl */void BTMenu(){cout<<"\n\t二叉树菜单\n";cout<<"\t1\t二叉树的高度\n";cout<<"\t2\t二叉树的节点数\n";cout<<"\t3\t二叉树度为一的节点数\n";cout<<"\t4\t二叉树根节点的值\n";cout<<"\t5\t二叉树是否为空\n";cout<<"\t6\t交换二叉树的左右子树\n";cout<<"\t7\t先序遍历\n";cout<<"\t8\t中序遍历\n";cout<<"\t9\t后序遍历\n";cout<<"\ta\t层次遍历\n";cout<<"\n\tb\t创建二叉树\n";cout<<"\tc\t删除二叉树\n";cout<<"\t0\t退出\n";cout<<"\n\t请输入选择:";}/* Create a binary tree  * n is indentation */void CreateBTree(BinaryTree<char> &bt, int n){char temp;BinaryTree<char> bt1,bt2;// indentationfor(int i=0; i<n; i++)cout<<"    ";// elementcout<<"L"<<n+1<<": 节点数据的值(如果此节点为NULL,请输入#):";cin>>temp;if('#' == temp)return ;// left childfor(i=0; i<n; i++)cout<<"    ";cout<<"左子树:\n";CreateBTree(bt1,n+1);// right childfor(i=0; i<n; i++)cout<<"    ";cout<<"右子树:\n";CreateBTree(bt2,n+1);// make treebt.MakeTree(temp,bt1,bt2);}/* Contral for Binary tree test */void BTreeCtrl(){char ch;BinaryTree<char> bt;char temp;do{BTMenu();cin>>ch;switch(ch){case '1':cout<<"二叉树的高度为:"<<bt.Height()<<endl;break;case '2':cout<<"二叉树的节点数为:"<<bt.Size()<<endl;break;case '3':cout<<"二叉树度为一的节点数为:"<<bt.Node1Sum()<<endl;break;case '4':if(bt.Root(temp))cout<<"二叉树根节点为:"<<temp<<endl;elsecout<<"二叉树为空!\n";break;case '5':if(bt.IsEmpty())cout<<"二叉树为空\n";elsecout<<"二叉树非空\n";break;case '6':bt.ChangeChild();cout<<"二叉树左右子树已交换。\n";break;case '7':cout<<"先序遍历:\n";bt.PreOrder();break;case '8':cout<<"中序遍历:\n";bt.InOrder();break;case '9':cout<<"后序遍历:\n";bt.PostOrder();break;case 'a':cout<<"层次遍历:\n";bt.LevelOrder();break;case 'b':cout<<"请按提示输入数据。\n";CreateBTree(bt,0);cout<<"建树成功!\n";break;case 'c':bt.Clear();cout<<"二叉树已删除!\n";break;default:ch = '0';}}while('0' != ch);}//----------------------------------------------------------// HfmTree contral//----------------------------------------------------------/* Menu for HTreeCtrl */void HTMenu(){cout<<"\n\t哈夫曼树菜单\n";cout<<"\t1\t创建哈夫曼树\n";cout<<"\t2\t先序和中序遍历哈夫曼树\n";cout<<"\t3\t生成编码\n";cout<<"\t4\t编码\n";cout<<"\t5\t译码\n";cout<<"\t6\t打印\n";cout<<"\t0\t退出\n";cout<<"\n\t请输入选择:";}/* Clear the array */template <class T>inline void ClearArray(T a[],int n){if(NULL != a)for(int i=0; i<n; i++)a[i] = NULL;}/* delete the array's elements */template <class T>inline void DeleteArray(T a[],int n){if(NULL != a && NULL != a[0])for(int i=0; i<n; i++)delete[] (a[i]);}/* Create tree */void CreateHTree(int &num, int* &wp, char* &cp, HfmTree<int> &ht){cout<<"请输入要编码的字符数:";cin>>num;if(num <= 0){cout<<"输入错误!\n";return ;}if(NULL != wp)delete[] wp;if(NULL != cp)delete[] cp;wp = new int[num];cp = new char[num];cout<<"请按提示输入数据\n";cout<<"请输入字符"<<endl;for(int i=0; i<num; i++){cin>>cp[i];}cout<<"请输入每个字符的权值"<<endl;for(i=0;i<num;i++){cin>>wp[i];}ht.CreateHfmTree(wp, num);}/* Contral for HfmTree */void HTreeCtrl(){char ch;int num = 0;int *wp = NULL;char *cp = NULL;char **code = NULL;BTNode<int> **np = NULL;HfmTree<int> ht;do{HTMenu();cin>>ch;switch(ch){case '1':CreateHTree(num,wp,cp,ht);np = new BTNode<int>* [num];code = new char* [num];ClearArray(np,num);ClearArray(code,num);cout<<"建树完成!\n";break;case '2':cout<<"先序遍历:\n";ht.PreOrder();cout<<"中序遍历:\n";ht.InOrder();//getch();break;case '3':DeleteArray(np,num);DeleteArray(code,num);if(ht.IsEmpty()){cout<<"请先创建哈夫曼树树!\n";break;}ht.CalCoding(cp, wp, np, code, num);cout<<"编码生成完毕\n";break;case '4':if(0 == num || NULL == code && NULL == code[0]){cout<<"请先创建哈夫曼树,并生成编码!\n";break;}HIntext();HCode(cp,code,num);cout<<"编码完毕\n";break;case '5':TranCoding(ht, cp, np, code);cout<<"译码完毕\n";break;case '6':ShowFile();break;default:ch = '0';}}while('0' != ch);}//----------------------------------------------------------// Main function//----------------------------------------------------------int main(){char ch;cout<<"\n实验二\n";cout<<"\nB11040805 陈佳佳"<<endl;do{MMenu();cin>>ch;switch(ch){case '1':// BianryTreeBTreeCtrl();break;case '2':// HfmTreeHTreeCtrl();break;default:ch = '0';}}while('0' != ch);return 0;}void HIntext(){char ch;FILE *fp;fp=fopen("D:\\textfile.txt","w");if(!fp){printf("文件不能打开");}//cout<<"输入要编码的字符"<<endl;printf("Enter a text end with '#'\n");ch=getchar();while(ch!='#'){fputc(ch,fp);ch=getchar();}fclose(fp);}void HCode(const char cp[],char* code[] ,int n){char ch;FILE *fp,*fpc;fp=fopen("D:\\textfile.txt","r");if(!fp){printf("文件不能打开");}//char chc;//FILE *fpc;fpc=fopen("D:\\codefile.txt","w");if(!fpc){printf("文件不能打开");}while((ch=fgetc(fp))!=EOF){for(int i=0;i<n;i++){if(ch==cp[i]){fputs(code[i],fpc);}}}fclose(fp);fclose(fpc);}void TranCoding(const HfmTree<int> &ht, char c[], BTNode<int> *np[], char* code[]){char ch;FILE *fpr,*fpc;fpr=fopen("D:\\resultfile.txt","w");fpc=fopen("D:\\codefile.txt","r");if(!fpr){printf("resultfile文件不能打开");}if(!fpc){printf("codefile文件不能打开");}BTNode<int> *btnp;char *pcode = new char[100];char *p = pcode;while((ch=fgetc(fpc))!=EOF){*p=ch;p++;}*p = '\0';p = pcode;while('\0' != *p){btnp = ht.TranCoding(p);// find the number of the charectorint i = -1;while( btnp != np[++i] )NULL;//fout<<c[i];fputc(c[i],fpr);int j = -1;while('\0' != code[i][++j])NULL;p += j;}delete[] pcode;fclose(fpr);fclose(fpc);}void ShowFile(){char ch;FILE *fpr,*fpc,*fp;fp=fopen("D:\\textfile.txt","r");fpr=fopen("D:\\resultfile.txt","r");fpc=fopen("D:\\codefile.txt","r");if(!fpr){printf("resultfile文件不能打开");}if(!fpc){printf("codefile文件不能打开");}if(!fp){cout<<"textfile文件不能打开"<<endl;}cout<<"textfile.txt"<<endl;while((ch=fgetc(fp))!=EOF){putchar(ch);}cout<<endl;cout<<"codefile.txt"<<endl;while((ch=fgetc(fpc))!=EOF){putchar(ch);}cout<<endl;cout<<"resultfile.txt"<<endl;while((ch=fgetc(fpr))!=EOF){putchar(ch);}cout<<endl;fclose(fp);fclose(fpr);fclose(fpc);}



 

原创粉丝点击