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 相关文章推荐
jquery中的$(document).ready()与window.onload的区别
Nov 18 Javascript
动态创建script标签实现跨域资源访问的方法介绍
Feb 28 Javascript
JavaScript将数组转换成CSV格式的方法
Mar 19 Javascript
JavaScript动态修改网页元素内容的方法
Mar 21 Javascript
Node.js中的process.nextTick使用实例
Jun 25 Javascript
jQuery无刷新切换主题皮肤实例讲解
Oct 21 Javascript
微信小程序中setInterval的使用方法
Sep 29 Javascript
vuex实现登录状态的存储,未登录状态不允许浏览的方法
Mar 09 Javascript
vue .js绑定checkbox并获取、改变选中状态的实例
Aug 24 Javascript
详解node和ES6的模块导出与导入
Feb 19 Javascript
使用Vue实现简单计算器
Feb 25 Javascript
JS highcharts动态柱状图原理及实现
Oct 16 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
php实现首页链接查询 友情链接检查的代码
2010/01/05 PHP
PHP中foreach循环中使用引用要注意的地方
2011/01/02 PHP
使用php伪造referer的方法 利用referer防止图片盗链
2014/01/20 PHP
YII Framework框架教程之安全方案详解
2016/03/14 PHP
thinkphp框架下实现登录、注册、找回密码功能
2016/04/06 PHP
从Ajax到JQuery Ajax学习
2007/02/14 Javascript
js 事件小结 表格区别
2007/08/13 Javascript
select、radio表单回显功能实现避免使用jquery载入赋值
2013/06/08 Javascript
js判断子窗体是否关闭的方法
2015/08/11 Javascript
jQuery实现简单的文件上传进度条效果
2020/03/26 Javascript
由简入繁实现Jquery树状结构的方法(推荐)
2016/06/10 Javascript
jquery Banner轮播选项卡
2016/12/26 Javascript
BootStrap表单验证实例代码
2017/01/13 Javascript
Vue2.2.0+新特性整理及注意事项
2018/08/22 Javascript
nodejs中实现用户注册路由功能
2019/05/20 NodeJs
[07:38]2014DOTA2国际邀请赛 Newbee顺利挺进胜者组赛后专访
2014/07/15 DOTA
[08:40]Navi Vs Newbee
2018/06/07 DOTA
django自定义Field实现一个字段存储以逗号分隔的字符串
2014/04/27 Python
Python抓取京东图书评论数据
2014/08/31 Python
浅谈Python反射 &amp; 单例模式
2019/03/21 Python
Pythony运维入门之Socket网络编程详解
2019/04/15 Python
python抓取需要扫微信登陆页面
2019/04/29 Python
简单了解Python matplotlib线的属性
2019/06/29 Python
Python中面向对象你应该知道的一下知识
2019/07/10 Python
对Python获取屏幕截图的4种方法详解
2019/08/27 Python
基于python调用jenkins-cli实现快速发布
2020/08/14 Python
python实现人工蜂群算法
2020/09/18 Python
解决使用Pandas 读取超过65536行的Excel文件问题
2020/11/10 Python
CSS3实现DIV圆角效果完整代码
2012/10/10 HTML / CSS
基于CSS3实现立方体自转效果
2016/03/01 HTML / CSS
HTML5页面无缝闪开的问题及解决方案
2020/06/11 HTML / CSS
参观监狱心得体会
2014/01/02 职场文书
送温暖献爱心活动总结
2014/07/08 职场文书
元旦标语大全
2014/10/09 职场文书
公司租房协议书
2014/10/14 职场文书
Java多线程并发FutureTask使用详解
2022/06/28 Java/Android