Typescript實現哈夫曼樹 + 編碼

最近的大三Java實驗課,老師讓咱們用Java語言來完成文件內容的壓縮,不使用Gzip和ZIP的方式來實現,做爲一個前端開發,固然要試試用前端的語言的來實現此做業的要求,我選擇使用Typescript來完成代碼的實現,也試試學了這麼久,Typescript掌握了多少。前端

TS源碼

//規定樹節點的內容對象
interface keyobj {
    key: string,
    val: number
}

//映射表的類型接口約定
interface kcMap {
    [id: string]: string
}

class Huffman{
    //文本
    public str: string;
    //key值和頻率的映射表
    public keyCountMap: any = null;
    //key值和編碼的映射表
    public keyCodeMap: kcMap = {};

    //哈夫曼節點列表
    public nodelist: Array<Nodeitem> = [];
    //哈夫曼樹根節點
    public root: Nodeitem;
    //哈夫曼編碼後的序列
    public code: any = null;

    constructor(str: string){
        this.str = str;
    }
    
    //計算文本每一個字母元素出現的頻率
    public cal(): void{
        let map: {} = {};
        let i: number = 0;

        while(this.str[i]){
            map[this.str[i]] ? map[this.str[i]] ++ : (map[this.str[i]] = 1);
            i ++;
        }

        this.keyCountMap = map
        console.log(this.keyCountMap);
    };
    
    //對於字母頻率,規定成節點,並排序
    public sort(): void{
        //類型聲明爲對象的數組集合
        let result: Array<Nodeitem> = [];

        for(let key in this.keyCountMap){
            if(this.keyCountMap.hasOwnProperty(key)){
                let obj: keyobj = {
                    key: key,
                    val: this.keyCountMap[key]
                };
                console.log(obj);

                result.push(new Nodeitem(null,null,obj));
            }
        }

        result.sort(function(x,y){
            return x.data.val - y.data.val;
        })

        this.nodelist = result;
        
    }
    
    //製做哈夫曼樹
    public makeTree(): Nodeitem{
        let i: number = 0;
        let parentNode: Nodeitem;

        let table: Array<Nodeitem> = this.nodelist;

        //將數組合併成哈夫曼樹
        while(table.length > 1){
            parentNode = new Nodeitem(table[i],table[i+1],{
                key: null,
                val: table[i].data.val + table[i + 1].data.val
            })
            table.splice(i,2);
            table.push(parentNode);
            table.sort(function(x,y) {
                return x.data.val - y.data.val
            })
        }

        this.root = table[0] || new Nodeitem(null,null,{key: null,val: 0});

        return this.root;
    }
    
    //將每一個字母經過哈夫曼樹轉換爲二進制編碼
    public traversal(tree: Nodeitem,code: string): void{
        if(tree.left !== null){
            this.traversal.call(this,tree.left,code + '0');
        }
        else{
            this.keyCodeMap[tree.data.key] = code;
        }

        if(tree.right !== null){
            this.traversal.call(this,tree.right,code + '1');
        }
        else{
            this.keyCodeMap[tree.data.key] = code;
        }

    }
    
    //將文本字符串進行編碼
    public encode(): string{

        this.cal();
        this.sort();
        let root: Nodeitem = this.makeTree();

        console.log(root);
        this.traversal(root,'');

        console.log(this.keyCodeMap);

        let i: number = 0;
        let result: string = '';
        
        while(this.str[i]){
            
            result += this.keyCodeMap[this.str[i ++]];
        }

        this.code = result;
        console.log(result);

        return result;
    }
}

class Nodeitem{

    public left: any;
    public right: any;
    public data: keyobj;
    
    constructor(left: any,right: any,data: keyobj){
        this.left = left;
        this.right = right;
        this.data = data;
    }
}

//測試代碼(demo)
const str1: string = "dasjfhpasujdhfu;h4wpoiufjhapwoivnowuihvno;awjcoi;wejfoiawejfpiuowefjhijwhvniu";
const huffmanDemo: Huffman = new Huffman(str1);
huffmanDemo.encode();
複製代碼

顯示結果

相關文章
相關標籤/搜索