+ -
当前位置:首页 → 问答吧 → C++ 霍夫曼树实现中函数编译的问题

C++ 霍夫曼树实现中函数编译的问题

时间:2011-12-26

来源:互联网

#pragma once
#include"BinaryTree.h"
class Huffman
{
public:
Huffman(void);
~Huffman(void);
friend bool operator<(Huffman&x1,Huffman&x2);
private:
int weight;
BinaryTree<int>tree;
};
bool operator<(Huffman&x1,Huffman&x2)
{
return x1.weight<x2.weight;
}

#pragma once
#include"MinHeap.h"
#include"Huffman.h"
#include<iostream>
using namespace std;
template<class T>
class BinaryTreeNode
{
public:
BinaryTreeNode(const T&e,BinaryTreeNode<T>*l,BinaryTreeNode<T>*r);
BinaryTreeNode(){}
~BinaryTreeNode<T>();
template<class T>
friend void pre(BinaryTreeNode<T>*);
private:
T data;
BinaryTreeNode<T>*leftchild;
BinaryTreeNode<T>*rightchild;
};
template<class T>
void pre(BinaryTreeNode<T>*t)
{
if(t)
{
cout<<t->data<<" ";
pre(t->leftchild);
pre(t->rightchild);
}
}

template<class T>
BinaryTreeNode<T>::BinaryTreeNode(const T&e,BinaryTreeNode<T>*l,BinaryTreeNode<T>*r)
{
data=e;
leftchild=l;
rightchild=r;
}
template<class T>
BinaryTreeNode<T>::~BinaryTreeNode()
{
}


//////////////////////////////////
template<class T>
class BinaryTree
{
public:
BinaryTree(void);
~BinaryTree(void);
void MakeTree(const T&e,BinaryTree<T>&l,BinaryTree<T>&r);
void PreOrder(BinaryTree<T>&);
BinaryTree<int>HuffmanTree(int [],int n);//a为频率,n为字符
private:
BinaryTreeNode<T>*root;//根节点
};
template<class T>
BinaryTree<T>::BinaryTree()
{
root=0;
}
template<class T>
BinaryTree<T>::~BinaryTree()
{
}
template<class T>
void BinaryTree<T>::PreOrder(BinaryTree<T>&x)
{
BinaryTreeNode<T>*t;
t=x.root;
pre(t);
}
template<class T>
void BinaryTree<T>::MakeTree(const T&e,BinaryTree<T>&l,BinaryTree<T>&r)
{
root=new BinaryTreeNode<T>(e,l.root ,r.root);
l.root=r.root=0;
}
template<class T>
BinaryTree<int> BinaryTree<T>::HuffmanTree(int a[],int n)
{
Huffman*h=new Huffman[n+1];
BinaryTree<int>z,zero;
for(int i=1;i<=n;i++)
{
z.MakeTree(i,zero,zero);
h[i].weight=a[i-1];
h[i].tree=z;
}
MinHeap<Huffman>H(1);
H.Initialize(h,n,n-1);
Huffman x,y;
for(int i=1;i<n;i++)
{
H.DeleteMin(x);
H.DeleteMin(y);
z.MakeTree(0,x.tree,y.tree);
x.weight+=y.weight;x.tree=z;
H.Insert(x);
}
H.DeleteMin(x);
H.Deactivate();
delete []h;
return x.tree;
}

#pragma once
#include"BinaryTree.h"
#include<iostream>
using namespace std;
#include<stdlib.h>
template<class T> 
class MinHeap 

public: 
MinHeap(int MinHeapSize = 10); 
~MinHeap() {delete [] heap;} 
int Size() const {return CurrentSize;} 
T Min() 
{
if (CurrentSize == 0) 
throw OutOfBounds(); 
return heap[1];

MinHeap<T>& Insert(const T& x); 
MinHeap<T>& DeleteMin(T& x); 
void Initialize(T a[], int size, int ArraySize); 
void Deactivate() {heap = 0;} 
void Output() const; 
//friend bool operator<(Huffman&x1,Huffman&x2);
private: 
int CurrentSize, MaxSize; 
T *heap; 
}; 
template<class T> 
MinHeap<T>::MinHeap(int MinHeapSize) 

MaxSize = MinHeapSize; 
heap = new T[MaxSize+1]; 
CurrentSize = 0; 


template<class T> 
MinHeap<T>& MinHeap<T>::Insert(const T& x) 

if (CurrentSize == MaxSize) 
{
cout<<"溢出!"<<endl;
system("pause");
}
//为x寻找应插入的位置 
//i从新的叶节点开始,并沿着树上升 
int i = ++CurrentSize; 
while (i != 1 && x < heap[i/2])  

heap[i] = heap[i/2]; // 将元素下移 
i /= 2; // 移向父节点 

heap[i] = x; 

return *this; 


template<class T> 
MinHeap<T>& MinHeap<T>::DeleteMin(T& x) 

if (CurrentSize == 0) 

cout<<"异常!"<<endl;
system("pause");
}
x = heap[1]; 

T y = heap[CurrentSize--]; //最后一个元素 

// 从根开始, 为y寻找合适的位置 
int i = 1, // 堆的当前节点 
ci = 2; // i的子节点 

while (ci <= CurrentSize)  

// 使heap[ci] 是i较小的子节点 
if (ci < CurrentSize  
&& heap[ci] > heap[ci+1])  
ci++; 

// 能把y放入heap[i]吗? 
if (y <= heap[ci])  
break; // 能 

// 不能 
heap[i] = heap[ci]; // 子节点上移 
i = ci; // 下移一层 
ci *= 2; 


heap[i] = y; 

return *this; 


template<class T> 
void MinHeap<T>::Initialize(T a[], int size, int ArraySize) 
{ //size为数组a的元素的个数,ArraySize为数组从a[1]算起的元素个数
delete [] heap; 
heap=new T[size+1];
for(int i=1;i<=size;i++)
heap[i]=a[i];
CurrentSize = size; 
MaxSize = ArraySize; 

// 产生一个最小堆 
for (int i = CurrentSize/2; i >= 1; i--)  

T y = heap[i]; // 子树的根 

// 寻找放置y的位置 
int c = 2*i; // c 的父节点是y的目标位置 

while (c <= CurrentSize)  

// 使heap[c]是较小的子节点 
if (c < CurrentSize && 
heap[c] > heap[c+1]) c++; 

// 能把y放入heap[c/2]吗? 
if (y <= heap[c]) break; // 能 
// 不能 
heap[c/2] = heap[c]; // 子节点上移 
c *= 2; // 下移一层 

heap[c/2] = y; 



template<class T> 
void MinHeap<T>::Output() const 

cout << "The " << CurrentSize 
<< " elements are"<< endl; 
for (int i = 1; i <= CurrentSize; i++) 
cout << heap[i] << " "; 
cout << endl; 
}  

// 压缩.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include"BinaryTree.h"

int _tmain(int argc, _TCHAR* argv[])
{
int a[5]={5,4,3,2,1};
BinaryTree<int>b,c;
c=b.HuffmanTree(a,5);
b.PreOrder(c);
return 0;
}

错误如下:
1>------ 已启动全部重新生成: 项目: 压缩, 配置: Debug Win32 ------
1> stdafx.cpp
1> 压缩.cpp
1>d:\my documents\visual studio 2010\projects\压缩\压缩\huffman.h(11): error C2143: 语法错误 : 缺少“;”(在“<”的前面)
1>d:\my documents\visual studio 2010\projects\压缩\压缩\huffman.h(11): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int
1>d:\my documents\visual studio 2010\projects\压缩\压缩\huffman.h(11): error C2238: 意外的标记位于“;”之前
1> MinHeap.cpp
1>d:\my documents\visual studio 2010\projects\压缩\压缩\huffman.h(11): error C2143: 语法错误 : 缺少“;”(在“<”的前面)
1>d:\my documents\visual studio 2010\projects\压缩\压缩\huffman.h(11): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int
1>d:\my documents\visual studio 2010\projects\压缩\压缩\huffman.h(11): error C2238: 意外的标记位于“;”之前
1> Huffman.cpp
1> BinaryTree.cpp
1>d:\my documents\visual studio 2010\projects\压缩\压缩\huffman.h(11): error C2143: 语法错误 : 缺少“;”(在“<”的前面)
1>d:\my documents\visual studio 2010\projects\压缩\压缩\huffman.h(11): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int
1>d:\my documents\visual studio 2010\projects\压缩\压缩\huffman.h(11): error C2238: 意外的标记位于“;”之前
1> 正在生成代码...
========== 全部重新生成: 成功 0 个,失败 1 个,跳过 0 个 ==========
我就搞不懂了,明明包了一个头文件“BinaryTree.h”,为什么编译器老师报我的错误,及时将BinaryTree变为Huffman的友元类,加上template<class T>同样存在问题,求高手指点啊。我现在都被这个问题烦死了啊。

作者: chuand_dao   发布时间: 2011-12-26

好复杂啊 求高手啊!!!

作者: lantingyaoyi   发布时间: 2011-12-26

几个头文件互相包含了……

作者: riyueming184   发布时间: 2011-12-26

设计上很多问题,我改了下,至于逻辑上的问题,你自己改吧:
C/C++ code
#pragma once
#include"MinHeap.h"
//#include"Huffman.h"
#include<iostream>
using namespace std;
template<class T>
class BinaryTreeNode
{
public:
    BinaryTreeNode(const T&e,BinaryTreeNode<T>*l,BinaryTreeNode<T>*r);
    BinaryTreeNode(){}
    ~BinaryTreeNode<T>();
    template<class T>
    friend void pre(BinaryTreeNode<T>*);
private:
    T data;
    BinaryTreeNode<T>*leftchild;
    BinaryTreeNode<T>*rightchild;
};
template<class T>
void pre(BinaryTreeNode<T>*t)
{
    if(t)
    {
        cout<<t->data<<" ";
        pre(t->leftchild);
        pre(t->rightchild);
    }
}

template<class T>
BinaryTreeNode<T>::BinaryTreeNode(const T&e,BinaryTreeNode<T>*l,BinaryTreeNode<T>*r)
{
    data=e;
    leftchild=l;
    rightchild=r;
}
template<class T>
BinaryTreeNode<T>::~BinaryTreeNode()
{
}


//////////////////////////////////
template<class T>
class BinaryTree
{
public:
    BinaryTree(void);
    ~BinaryTree(void);
    void MakeTree(const T& e,BinaryTree<T>& l,BinaryTree<T>& r);
    void PreOrder(/*BinaryTree<T>&*/);

private:
    BinaryTreeNode<T>*root;//根节点
};
template<class T>
BinaryTree<T>::BinaryTree()
{
    root=0;
}
template<class T>
BinaryTree<T>::~BinaryTree()
{
}
template<class T>
void BinaryTree<T>::PreOrder(/*BinaryTree<T>&x*/) //传入参数目的是什么?
{
    /*BinaryTreeNode<T>*t;
    t=x.root;*/
    if (root)
    {
        pre(root);
    }
    
}
template<class T>
void BinaryTree<T>::MakeTree(const T&e,BinaryTree<T>&l,BinaryTree<T>&r)
{
    root=new BinaryTreeNode<T>(e,l.root ,r.root);
    l.root=r.root=0;
}


C/C++ code
#pragma once
#include"BinaryTree.h"

class Huffman
{
public:
    Huffman(void){weight = 0;};
    ~Huffman(void){};
    friend bool operator<(const Huffman& x1,const Huffman& x2);
    friend bool operator==(const Huffman& x1,const Huffman& x2);
    friend bool operator!=(const Huffman& x1,const Huffman& x2);
    friend bool operator<=(const Huffman& x1,const Huffman& x2);
    friend bool operator>(const Huffman& x1,const Huffman& x2);
    friend bool operator>=(const Huffman& x1,const Huffman& x2);
    int weight;
    BinaryTree<int> tree;
};
bool operator<(const Huffman& x1,const Huffman& x2)
{
    return x1.weight<x2.weight;
}
bool operator<=(const Huffman& x1,const Huffman& x2)
{
    return x1.weight<=x2.weight;
}
bool operator==(const Huffman& x1,const Huffman& x2)
{
    return x1.weight==x2.weight;
}
bool operator!=(const Huffman& x1,const Huffman& x2)
{
    return !(x1.weight==x2.weight);
}
bool operator>(const Huffman& x1,const Huffman& x2)
{
    return !(x1 <= x2 );
}
bool operator>=(const Huffman& x1,const Huffman& x2)
{
    return !(x1 < x2 );
}
//这个定义为全局函数
//a为频率,n为字符

BinaryTree<int> HuffmanTree(int a[],int n)
{
    Huffman *h=new Huffman[n+1];
    BinaryTree<int>z,zero;
    for(int i=1;i<=n;i++)
    {
        z.MakeTree(i,zero,zero);
        h[i].weight=a[i-1];//要直接访问应该定义为公有成员
        h[i].tree=z;
    }
    MinHeap<Huffman>H(1);
    H.Initialize(h,n,n-1);
    Huffman x,y;
    for(int i=1;i<n;i++)
    {
        H.DeleteMin(x);
        H.DeleteMin(y);
        z.MakeTree(0,x.tree,y.tree);
        x.weight+=y.weight;x.tree=z;
        H.Insert(x);
    }
    H.DeleteMin(x);
    H.Deactivate();
    delete [] h;
    return x.tree;
}

C/C++ code
#pragma once
#include<iostream>
using namespace std;
#include<stdlib.h>
template<class T>  
class MinHeap  
{  
public:  
    MinHeap(int MinHeapSize = 10);  
    ~MinHeap() {delete [] heap;}  
    int Size() const {return CurrentSize;}  
    T Min()  
    {
        if (CurrentSize == 0)  
            throw OutOfBounds();  
        return heap[1];
    }  
    MinHeap<T>& Insert(const T& x);  
    MinHeap<T>& DeleteMin(T& x);  
    void Initialize(T a[], int size, int ArraySize);  
    void Deactivate() {heap = 0;}  
    void Output() const;  
    //friend bool operator<(Huffman&x1,Huffman&x2);
private:  
    int CurrentSize, MaxSize;  
    T *heap;  
};  
template<class T>  
MinHeap<T>::MinHeap(int MinHeapSize)  
{  
    MaxSize = MinHeapSize;  
    heap = new T[MaxSize+1];  
    CurrentSize = 0;  
}  

template<class T>  
MinHeap<T>& MinHeap<T>::Insert(const T& x)  
{  
    if (CurrentSize == MaxSize)  
    {
        cout<<"溢出!"<<endl;
        system("pause");
    }
    //为x寻找应插入的位置  
    //i从新的叶节点开始,并沿着树上升  
    int i = ++CurrentSize;  
    while (i != 1 && x < heap[i/2])   
    {  
        heap[i] = heap[i/2]; // 将元素下移  
        i /= 2; // 移向父节点  
    }  
    heap[i] = x;  

    return *this;  
}  

template<class T>  
MinHeap<T>& MinHeap<T>::DeleteMin(T& x)  
{  
    if (CurrentSize == 0)  
    {  
        cout<<"异常!"<<endl;
        system("pause");
    }
    x = heap[1];  

    T y = heap[CurrentSize--]; //最后一个元素  

    // 从根开始, 为y寻找合适的位置  
    int i = 1, // 堆的当前节点  
        ci = 2; // i的子节点  

    while (ci <= CurrentSize)   
    {  
        // 使heap[ci] 是i较小的子节点  
        if (ci < CurrentSize   
            && heap[ci] > heap[ci+1])   
            ci++;  

        // 能把y放入heap[i]吗?  
        if (y <= heap[ci])   
            break; //// 不能  
        heap[i] = heap[ci]; // 子节点上移  
        i = ci; // 下移一层  
        ci *= 2;  
    }  

    heap[i] = y;  

    return *this;  
}  

template<class T>  
void MinHeap<T>::Initialize(T a[], int size, int ArraySize)  
{ //size为数组a的元素的个数,ArraySize为数组从a[1]算起的元素个数
    delete [] heap;  
    heap=new T[size+1];
    for(int i=1;i<=size;i++)
        heap[i]=a[i];
    CurrentSize = size;  
    MaxSize = ArraySize;  

    // 产生一个最小堆  
    for (int i = CurrentSize/2; i >= 1; i--)   
    {  
        T y = heap[i]; // 子树的根  

        // 寻找放置y的位置  
        int c = 2*i; // c 的父节点是y的目标位置  

        while (c <= CurrentSize)   
        {  
            // 使heap[c]是较小的子节点  
            if (c < CurrentSize &&  
                heap[c] > heap[c+1]) c++;  

            // 能把y放入heap[c/2]吗?  
            if (y <= heap[c]) break; //// 不能  
            heap[c/2] = heap[c]; // 子节点上移  
            c *= 2; // 下移一层  
        }  
        heap[c/2] = y;  
    }  
}  

template<class T>  
void MinHeap<T>::Output() const  
{  
    cout << "The " << CurrentSize  
        << " elements are"<< endl;  
    for (int i = 1; i <= CurrentSize; i++)  
        cout << heap[i] << " ";  
    cout << endl;  
}   


C/C++ code
#include "stdafx.h"
#include "Huffman.h"
#include"BinaryTree.h"



int _tmain(int argc, _TCHAR* argv[])
{
    int a[5]={5,4,3,2,1};
    BinaryTree<int>b;
    b = HuffmanTree(a,5);
    b.PreOrder();
    return 0;
}

作者: riyueming184   发布时间: 2011-12-26