最优二叉树以及huffman编码

来源:互联网 发布:合肥好的装修公司知乎 编辑:程序博客网 时间:2024/05/16 11:59

 这个程序比较容易写,不过可能严格来说,一些高手会觉得比较恶心,因为用了冒泡排序,所以按书上的说法,应该用堆排序,比较效率高!但是还没看到堆排序,就用比较熟悉的冒泡先充着!然后huffman编码也比较好写,主要利用递归就搞掂了,下面是程序(写这个程序本来用template模板写的,但是后来发现如果用模板写,就不可以很好的将头文件与定义文件分开,所以最后就没有用模板,而是用int和char来实现!把声明头文件与定义头文件分开,主要想对这个问题有一些概念的认识)

eg:

How many?
4
(frequence , alpha)
3 d 4 g 12 f 5 h
24 12 5 7 3 4 12
code..h: 00
code..d: 010
code..g: 011
code..f: 1
Press any key to continue

程序1main.cpp

#include"BestBiTree.h"

void main()
{
 int size(0);
 int x(0);
 char ch;
 string str;
 vector<Node*>data;
 cout<<"How many?"<<endl;
 cin>>size;
 cout<<"(frequence , alpha)"<<endl;
 for(int i = 0;i<size;i++)
 {
  cin>>x>>ch;
  Node *p = new Node(x,ch);
  data.push_back(p);
 }
 BestBiTree tree(data);
 tree.PrePrint(tree.Root());
 cout<<endl;
 tree.Code(data,tree.Root(),str);
}

程序2 声明头文件

#include<iostream>
#include<vector>
#include<string>
using namespace std;

class Node;
void Sort(vector<Node*>&data);

class BestBiTree;

class Node
{
 friend class BestBiTree;
 friend void Sort(vector<Node*>&data);
 private:
  int item;
  char alpha;
  Node *left;
  Node *right;
 public:
  inline Node(int x,char ch);
  ~Node(){}
};

class BestBiTree
{
 private:
  Node *root;
  Node *current;
 public:
  BestBiTree(vector<Node*>&data);
  void PrePrint(Node* cur);
  void Delete(Node* cur);
  Node* Root();
  void Code(vector<Node*>&data,Node *cur,string str);
  ~BestBiTree();
};

程序3 定义头文件

#include"BestBiTree.h"

inline Node::Node(int x,char ch)
{
 item = x;
 alpha = ch;
 left = NULL;
 right = NULL;
}

void Sort(vector<Node*>&data)
{
 Node* temp;
 for(int i = data.size();i>0;i--)
 {
  for(int j = 0;j<i-1;j++)
  {
   if(data[j+1]->item>data[j]->item)
   {
    temp = data[j];
    data[j] = data[j+1];
    data[j+1] = temp;
   }
  }
 }
}

BestBiTree::BestBiTree(vector<Node*>&data)

 int temp0,temp1; 
 while(data.size()>1)
 { 
  Sort(data);

  temp0 = data[data.size()-1]->item;
  temp1 = data[data.size()-2]->item;
 
  Node *proot = new Node(temp0+temp1,'*');
  proot->left = data[data.size()-1];
  proot->right = data[data.size()-2];

  data.pop_back(); 
  data.pop_back();
  data.push_back(proot);

 }
 root = data[0];
 current = root;
}

void BestBiTree::PrePrint(Node* cur)
{
 if(cur != NULL)
 {
  cout<<cur->item<<" ";
  PrePrint(cur->left);
  PrePrint(cur->right);
 }
}

BestBiTree::~BestBiTree()
{
 Delete(root);
}

void BestBiTree::Delete(Node* cur)
{
 if(cur != NULL)
 {
  if((cur->left == NULL)&&(cur->right == NULL))
  {
   Node *p;
   p = cur;
   delete p;
  }
  else
  {
   Delete(cur->left);
   Delete(cur->right);
  }
 }
}

Node* BestBiTree::Root()
{
 current = root;
 return current;
}

void BestBiTree::Code(vector<Node*>&data,Node *cur,string str)
{
 if((cur->left == NULL)&&(cur->right == NULL))
 {
  cout<<"code.."<<cur->alpha<<": "<<str<<endl;
 }
 else
 {
  str = str+'0';
  Code(data,cur->left,str);
  str = str.erase(str.size()-1,1);
  str = str+'1';
  Code(data,cur->right,str);
  str = str.erase(str.size()-1,1);
 }
}