JS实现的哈夫曼编码示例【原始版与修改版】


Posted in Javascript onApril 22, 2018

本文实例讲述了JS实现的哈夫曼编码。分享给大家供大家参考,具体如下:

原始版

function cal(str) {
  if (typeof str !== 'string' || str.length < 1) {
    return;
  }
  var map = {};
  var i = 0;
  while(str[i]) {
    map[str[i]] ? map[str[i]]++ : (map[str[i]] = 1);
    i++;
  }
  return map;
}
function sort(map) {
  map = map || {};
  var result = [];
  for (key in map) {
    if(map.hasOwnProperty(key)) {
      var obj = {
        key: key,
        val: map[key]
      };
      result.push(new Node(null, null, obj));
    }
  }
  return result.sort(function(x,y){return x.data.val > y.data.val});
}
function Node(left, right, data) {
  this.left = left;
  this.right = right;
  this.data = data;
}
function makeTree(table) {
  var i = 0;
  var len = table.length;
  var node1;
  var node2;
  var parentNode;
  while(table.length > 1) {
    parentNode = new Node(table[i], table[i+1], {key: null, val: table[i]['data'].val + table[i+1]['data'].val});
    table.splice(i,2);
    table.unshift(parentNode);
    table.sort(function(x,y){return x.data.val > y.data.val});
  }
  return table;
}
function encode(str, ret) {
  if (typeof str !== 'string' || str.length < 1) {
    return;
  }
  var i = 0;
  var result = '';
  while(str[i]) {
    result += ret[str[i++]];
  }
  return result
}
function reverseRet(ret) {
  var result = {};
  for (key in ret) {
    if(ret.hasOwnProperty(key)) {
      result[ret[key]] = key;
    }
  }
  return result;
}
function decode(str, ret) {
  var i = 0;
  var result = '';
  var data = '';
  var map = reverseRet(ret);
  while(str) {
    result += str[i++];
    if (result in map) {
      data += map[result];
      str = str.replace(new RegExp("^"+result),'');
      result = '';
      i = 0;
    }
  }
  console.log(data)
}
function traversal(tree, code, ret) {
  if (tree.left !== null) {
    traversal(tree.left, code + '0', ret);
  } else {
    ret[tree.data.key] = code;
  }
  if (tree.right !== null) {
    traversal(tree.right,code + '1', ret);
  } else {
    ret[tree.data.key] = code;
  }
}
var ret = {};
var str = 'ew qew qd ef 24 gf ewr getElementsByTagName';
traversal(makeTree(sort(cal(str)))[0],'', ret)
decode(encode(str, ret), ret)
btoa(encode(str,ret))

修改版

function Huffman(str) {
  // 需要编码的字符串
  this.str = str;
  // 键和频率映射表
  this.keyCountMap = null;
  // 编码和键的映射表
  this.codeKeyMap = {};
  // 键和编码的映射表
  this.keyCodeMap = {};
  // 哈夫曼树节点列表
  this.nodeList = null;
  // 哈夫曼树根节点
  this.root = null;
  // 哈夫曼编码后的01序列
  this.code = null;
}
Huffman.prototype.cal = function cal() {
  str = this.str;
  var map = {};
  var i = 0;
  while(str[i]) {
    map[str[i]] ? map[str[i]]++ : (map[str[i]] = 1);
    i++;
  }
  this.keyCountMap = map;
}
Huffman.prototype.sort = function sort() {
  map = this.keyCountMap;
  var result = [];
  for (key in map) {
    if(map.hasOwnProperty(key)) {
      var obj = {
        key: key,
        val: map[key]
      };
      result.push(new Node(null, null, obj));
    }
  }
  this.nodeList = result.sort(function(x,y){return x.data.val > y.data.val});
}
function Node(left, right, data) {
  this.left = left;
  this.right = right;
  this.data = data;
}
Huffman.prototype.makeTree = function makeTree() {
  var i = 0;
  var len = this.nodeList.length;
  var node1;
  var node2;
  var parentNode;
  var table = this.nodeList;
  while(table.length > 1) {
    parentNode = new Node(table[i], table[i+1], {key: null, val: table[i]['data'].val + table[i+1]['data'].val});
    table.splice(i,2);
    table.unshift(parentNode);
    table.sort(function(x,y){return x.data.val > y.data.val});
  }
  this.root = table[0] || new Node();
  return this.root;
}
Huffman.prototype.traversal = function traversal(tree, code) {
  if (tree.left !== null) {
    traversal.call(this,tree.left, code + '0');
  } else {
    this.keyCodeMap[tree.data.key] = code;
  }
  if (tree.right !== null) {
    traversal.call(this, tree.right,code + '1');
  } else {
    this.keyCodeMap[tree.data.key] = code;
  }
}
Huffman.prototype.encode = function encode() {
  this.cal();
  this.sort();
  var root = this.makeTree();
  this.traversal(root, '');
  var ret = this.keyCodeMap;
  var i = 0;
  var result = '';
  var str = this.str;
  while(str[i]) {
    result += ret[str[i++]];
  }
  this.code = result;
  console.log('encode:' + result);
  return result
}
Huffman.prototype.reverseMap = function reverseMap() {
  var ret = this.keyCodeMap;
  var result = {};
  for (key in ret) {
    if(ret.hasOwnProperty(key)) {
      result[ret[key]] = key;
    }
  }
  this.codeKeyMap = result;
  return result;
}
Huffman.prototype.decode = function decode() {
  var i = 0;
  var result = '';
  var data = '';
  var map = this.reverseMap();
  var str = this.code;
  while(str) {
    result += str[i++];
    if (result in map) {
      data += map[result];
      str = str.replace(new RegExp("^"+result),'');
      result = '';
      i = 0;
    }
  }
  console.log("decode:" + data)
}
Huffman.prototype.encodeBase64 = function() {
  try {
    var base64 = btoa(this.code);
    return base64;
  } catch(e) {
    return '';
  }
}
var str = 'ew qew qd ef 24 gf ewr getElementsByTagName';
var huffman = new Huffman(str)
huffman.encode(str)
huffman.decode();
huffman.encodeBase64();

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
JavaScript中的匀速运动和变速(缓冲)运动详细介绍
Nov 11 Javascript
JQuery触发事件例如click
Sep 11 Javascript
easyui datagrid 键盘上下控制选中行示例
Mar 31 Javascript
用jquery实现动画跳到顶部和底部(这个比较简单)
Sep 01 Javascript
js模仿java的Map集合详解
Jan 06 Javascript
AngularJS入门教程之AngularJS表达式
Apr 18 Javascript
jQuery的框架介绍
May 11 Javascript
JavaScript Base64 作为文件上传的实例代码解析
Feb 14 Javascript
原生js实现旋转木马轮播图效果
Feb 27 Javascript
JavaScript中重名的函数与对象示例详析
Sep 28 Javascript
微信小程序自定义组件实现环形进度条
Nov 17 Javascript
layui 中select下拉change事件失效的解决方法
Sep 20 Javascript
使用Angular CLI快速创建Angular项目的一些基本概念和写法小结
Apr 22 #Javascript
Vue下滚动到页面底部无限加载数据的示例代码
Apr 22 #Javascript
关于Angularjs中自定义指令一些有价值的细节和技巧小结
Apr 22 #Javascript
jQuery中图片展示插件highslide.js的简单dom
Apr 22 #jQuery
手写简单的jQuery雪花飘落效果实例
Apr 22 #jQuery
JQuery元素快速查找与操作
Apr 22 #jQuery
javaScript产生随机数的用法小结
Apr 21 #Javascript
You might like
smarty实例教程
2006/11/19 PHP
PHP实现多条件查询实例代码
2010/07/17 PHP
比file_get_contents稳定的curl_get_contents分享
2012/01/11 PHP
php写的AES加密解密类分享
2014/06/20 PHP
javascript 打印页面代码
2009/03/24 Javascript
jquery 查找select ,并触发事件的实现代码
2011/03/30 Javascript
ASP.NET jQuery 实例11 通过使用jQuery validation插件简单实现用户登录页面验证功能
2012/02/03 Javascript
ASP.NET jQuery 实例18 通过使用jQuery validation插件校验DropDownList
2012/02/03 Javascript
Nodejs异步回调的优雅处理方法
2014/09/25 NodeJs
JavaScript黑洞数字之运算路线查找算法(递归算法)实例
2016/01/28 Javascript
纯JS打造网页中checkbox和radio的美化效果
2016/10/13 Javascript
Angular2使用jQuery的方法教程
2017/05/28 jQuery
浅谈通过JS拦截 pushState和replaceState事件
2017/07/21 Javascript
解读ES6中class关键字
2017/11/20 Javascript
javascript匿名函数中的'return function()'作用
2018/10/15 Javascript
Javascript通过控制类名更改样式
2019/05/24 Javascript
nodejs中的异步编程知识点详解
2021/01/17 NodeJs
Python中的time模块与datetime模块用法总结
2016/06/30 Python
Python操作mysql数据库实现增删查改功能的方法
2018/01/15 Python
python @property的用法及含义全面解析
2018/02/01 Python
Python global全局变量函数详解
2018/09/18 Python
基于Python3.6+splinter实现自动抢火车票
2018/09/25 Python
Python动态语言与鸭子类型详解
2019/07/01 Python
Python线程条件变量Condition原理解析
2020/01/20 Python
Python中zip函数如何使用
2020/06/04 Python
scrapy中如何设置应用cookies的方法(3种)
2020/09/22 Python
python 装饰器的基本使用
2021/01/13 Python
CSS3 特效范例整理
2011/08/22 HTML / CSS
戴尔英国官网:Dell英国
2017/05/27 全球购物
金融专业推荐信
2013/11/14 职场文书
文明工地标语
2014/06/16 职场文书
运动会横幅标语
2014/06/17 职场文书
大学本科生职业生涯规划书范文
2014/09/14 职场文书
CSS实现隐藏搜索框功能(动画正反向序列)
2021/07/21 HTML / CSS
Python编程根据字典列表相同键的值进行合并
2021/10/05 Python
码云(gitee)通过git自动同步到阿里云服务器
2022/12/24 Servers