버프맨 트리와 버프맨 인코딩

왜 그런지 모르겠지만, 내가 쓴 코드는 모두 구리고 길다.
직접 부호:
#include <iostream>
#include <cstdarg>
using namespace std;
class Node{
public:
    int weight;
    int parent, lChildren, rChildren;
    Node(int weight, int parent, int lChildren, int rChildren):
            weight(weight), parent(parent), lChildren(lChildren), rChildren(rChildren)
    {
    }
    
    void printNode(){
        cout<<"weight = "<<weight<<", ";
        cout<<"parent = "<<parent<<", ";
        cout<<"lChildren = "<<lChildren<<", ";
        cout<<"rChildren = "<<rChildren<<endl;
    }
};

class Tree{
    Node **nodes;
    char** huffmanCodec;
    int length,rPos;
    int mNum;
    /** Tree    Node。
      *
      **/
    void addNode(Node *node){
        if(!node){
            cout<<"addNode ,   NULL"<<endl;
            return;
        }
        for(int i = 0; i < length; i++){
            if(node == nodes[i])//             。。
                return;
        }
        nodes[length++] = node;
    }
    /**   array          ,  v1 v2
      *
      **/
    void findSmallest2ValueInArray(int *array, int length, int *v1, int *v2, int *v1Pos, int *v2Pos){
        int t = 0;
        for(int i = 0; i < length; i++){
            if(array[i] < 0)
                continue;
            ++t;
            if(t == 1){
                *v1 = array[i];
                *v1Pos = i;
            }else if (t == 2){
                *v2 = array[i];
                *v2Pos = i;
            }else{
                if(*v1 > array[i]){
                    if(*v1 < *v2){
                        *v2 = *v1;
                        *v2Pos = *v1Pos;
                    }
                    *v1 = array[i];
                    *v1Pos = i;
                }else if(*v2 > array[i]){
                    *v2 = array[i];
                    *v2Pos = i;
                }
            }
        }
    }
    
    /**
    *   Tree     node   。  huffman    。
    *
    **/
    int findNodePosViaNode(Node *node){
        for(int i = 0; i < length; i++){
            if(nodes[i] == node){
                return i;
            }
        }
        return -1;
    }
    
    /**
    *   Tree     Weight node   ,    node  parent。       。
    *
    **/
    int findNodePosViaWeight(int value, bool isForParent, bool isTheSameWeightNode){
        for(int i = 0; i < length; i++){
            if(nodes[i]->parent == -1 && nodes[i]->weight == value && !isForParent && !isTheSameWeightNode){
                return i;
            }
        }
        return -1;
    }
    /**
    *          。
    *
    **/
    int findHuffmanNodePos(){
        static int mark;//      0
        for(int i = mark; i < length; i++){
            if(nodes[i]->lChildren == -1 && nodes[i]->rChildren == -1){
                mark = i + 1;
                return i;
            }
        }
        return -1;
    }
    
    /**
    *   node
    *
    **/
    Node* getNode(Node *node, int value, int parent, int lChildren, int rChildren, bool isForParent, bool isTheSameWeightNode){//      ,      ,  v1 20,
                                                                                                                               //  v1      ,  v2  20.
                                                                                                                               //     v2 new      。
        if(node){
            cout<<"getNode ,       NULL"<<endl;
            return NULL;
        }
        int pos = findNodePosViaWeight(value, isForParent, isTheSameWeightNode);
        if(pos != -1){
            node = nodes[pos];
        }else{
            node = new Node(value, parent, lChildren, rChildren);
        }
        return node;
    }
    
    /**
    *           -1   。
    *
    **/
    void initArray2Zero(int *array, int length){
        for(int i = 0; i < length; i++){
            array[i] = -1;
        }
    }
    
    /**
    *    int  
    */
    
    void printIntArray(int *array, int length){
        cout<<"[";
        for(int i = 0; i < length - 1; i++){
            cout<<array[i]<<", ";
        }
        cout<<array[length - 1]<<"]"<<endl;
    }
    
    /**
    *for debug
    */
    void debug(int i){
        cout<<"debug "<<i<<endl;
    }
    /**
    *  huffman   huffman  。
    */
    char** generateHuffmanCodec(int num){
        int topIndex = 0;
        huffmanCodec = new char*[num];//    
        for(int i = 0; i < num; i++){
            int index = 0;
            char *data = new char[num + 1];//          
            int thisPos = findHuffmanNodePos();
            Node *currentNode = nodes[thisPos];
            while(currentNode->parent != -1){
                Node *currentParent = nodes[currentNode->parent];
                if(thisPos == currentParent->lChildren){//0
                    data[index++] = '0';
                }else if(thisPos == currentParent->rChildren){//1
                    data[index++] = '1';
                }else{//X, never in.
                    data[index++] = 'X';
                }
                thisPos = currentNode->parent;
                currentNode = currentParent;
            }
            data[index] = '\0';
            huffmanCodec[topIndex++] = data;
        }
        return huffmanCodec;
    }
 
public:
   /**
    *     。
    *
    **/
    void makeTree(int num, ...){
        int weightArray[num];
        initArray2Zero(weightArray, num);
        va_list list;
        va_start(list, num);
        for(int i = 0; i < num; i++){
            weightArray[i] = va_arg(list, int);
        }
        va_end(list);
        printIntArray(weightArray, num);//debug
        int debug_x = 100;
        while(true){
            int v1 = -1, v2 = -1, v1Pos = -1, v2Pos = -1;
            findSmallest2ValueInArray(weightArray, num, &v1, &v2, &v1Pos, &v2Pos);
            if(v1 == -1 || v2 == -1){
                cout<<"v1 v2      -1,     "<<endl;
                break;
            }
            
            Node *node1 = NULL;
            node1 = getNode(node1, v1, -1, -1, -1, false, false);
            addNode(node1);//         add。
            
            Node *node2 = NULL;
            node2 = getNode(node2, v2, -1, -1, -1, false, v1 == v2);//  v1 v2  ,      force,     2        ,          。
            addNode(node2);
            
            Node *parent = NULL;
            parent = getNode(parent, v1 + v2, -1, -1, -1, true, false);//      ,           parent。   parent,               ,    new     。
                                                                       //                       。    parent ,       。
            addNode(parent);
            
            node1->parent = findNodePosViaNode(parent);
            node2->parent = node1->parent;
            
            parent->lChildren = findNodePosViaNode(node1);
            parent->rChildren = findNodePosViaNode(node2);
            
            weightArray[v1Pos] = -1;
            weightArray[v2Pos] = v1 + v2;
            printIntArray(weightArray, num);//debug
        }
        mNum = num;
        generateHuffmanCodec(num);        
    }
    
    /**
    *  huffman 
    *
    **/
    void printTree(){
        for(int i = 0; i < length; i++){
            cout<<"pos = "<<i<<", ";
            nodes[i]->printNode();
            //cout<<findHuffmanNodePos()<<endl;
        }
    }
    
    /**
    *       
    */
    
    void printHuffman(){
        cout<<"------huffman codec begin-----
"; for(int i = 0; i < mNum; i++){ cout<<huffmanCodec[i]<<endl; } cout<<"------huffman codec end-----
"; } /** * */ Tree(): nodes(new Node*[100]), huffmanCodec(NULL), length(0), rPos(-1), mNum(0){// int ? Node*, , int 。 } ~Tree(){ cout<<" "<<endl; delete []nodes; if(huffmanCodec) delete []huffmanCodec; } }; int main(){ Tree *tree = new Tree; tree->makeTree(8, 5, 29, 7, 8, 14, 23, 3, 11); tree->printTree(); tree->printHuffman(); delete tree; }
책의 예는 겨우 30줄 코드인데 300줄을 썼는데 왜 이러지? 이상해. 수련이 부족할 것 같아.노력해야 돼!

좋은 웹페이지 즐겨찾기