JavaScript数据结构之广义表的定义与表示方法详解


Posted in Javascript onApril 12, 2017

本文实例讲述了JavaScript数据结构之广义表的定义与表示方法。分享给大家供大家参考,具体如下:

广义表是线性表的推广,也有人称其为列表。 那么它和线性表有什么区别呢?线性表中每个成员只能是单个元素,而广义表中的成员可以是单个元素,也可以是广义表,分别称为广义表的原子子表。下面举几个广义表的例子。

A=();
B=(e);
C=(a,(b,c,d));
D=((),(e),(a,(b,c,d)));
E=(a,E);

由于广义表中的数据元素可以具有不同的结构(原子或列表),因此难以用顺序存储结构表示,通常采用链式存储结构。由于列表中的元素可以是原子也可以是列表,所以需要两种结构的节点,一种是表节点,一种是原子节点。

一个表节点由三个域组成,标志域、指向表头的指针域、指向表尾的指针域。而原子节点只需要两个域,标志域和值域。如下图:

JavaScript数据结构之广义表的定义与表示方法详解

上面讲到的五个列表的存储结构如下图:

JavaScript数据结构之广义表的定义与表示方法详解

我们用JavaScript来实现广义表及其基本操作吧。

首先需要定义广义表的存储结构:

var ATOM=0;
var LIST=1;
//广义表的存储结构
function ListNode(){
 //标识位
 this.tag=undefined;
 //原子结点的值域
 this.atom=null;
 //列表结点的值域
 this.ptr={
  hp:null,
  tp:null
 };
}

然后是创建广义表的过程:

//创建广义表
ListNode.prototype.createList=function(string){
 string=string.trim();
 //创建单原子广义表
 var q;
 if(/^[\w-]+$/.test(string)){//含有单字符
  this;tag=ATOM;
  this.atom=string;
 }else{
  this.tag=LIST;
  var p =this;
  //去掉最外层括号(和)
  var sub=string.substr(1,string.length-2);
  do{
  var h,
   i=0,
   k=0,
   n=sub.length,
   ch;
  do{
   ch=sub[i++];
   if(ch=='('){
   ++k;
   }else if(ch==')'){
   --k;
   }
  }while(i<n&&(ch!=','||k!=0));
  //i为第一个逗号分隔索引
  if(i<n){
   h=sub.substr(0,i-1);//每次遍历取出第一个结点,无论是原子还是列表
   sub=sub.substr(i,n-i);
  }else{//最后一组
   h=sub;
   sub='';
  }
  if(h==='()'){//空子表无表头结点
   p.ptr.hp=null;
  }else{//创建表头结点
   this.createList.call((p.ptr.hp=new ListNode()),h);
  }
  q=p;
  //创建表尾结点
  if(sub){
   p=new ListNode();
   p.tag=LIST;
   q.ptr.tp=p;
  }
  }while(sub);
  q.ptr.tp=null;
 }
};

接下就是求广义表的深度,深度的定义为广义表中括弧的重数,是广义表的一种量度。例如,多元多项式广义表的深度为多项式中变元的个数。设LS=(a1,a2,a3,…,an),求LS的深度可以分解为n个之问题,每个子问题为求ai的深度。如果ai是原子,则定义其深度为0,如果ai是广义表,则LS的深度为最大ai的深度+1。空表也是广义表,所以深度为1。实现代码如下:

//求广义表的深度
ListNode.prototype.depth=function(){
 return getDepth(this);
}
function getDepth(list){//深度为括号的重数,也可理解为左括号出现的个数
 if(!list){
  return 1;
 }else if(list.tag===ATOM){
  return 0;
 }else {
  var m=getDepth(list.ptr.hp)+1;
  var n=getDepth(list.ptr.tp);
  return m>n?m:n;
 }
}

最后我们创建测试案例:

var node=new ListNode();
node.createList('((),(a),(b,(c,d,e)))');
alert(node.depth());//5

node结点详细如下图:

JavaScript数据结构之广义表的定义与表示方法详解

完整代码如下:

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title></title>
 </head>
 <body>
<script type="text/javascript">
 var ATOM=0;
 var LIST=1;
 //广义表的存储结构
 function ListNode(){
  //标识位
  this.tag=undefined;
  //原子结点的值域
  this.atom=null;
  //列表结点的值域
  this.ptr={
   hp:null,
   tp:null
  };
 }
 //创建广义表
 ListNode.prototype.createList=function(string){
  string=string.trim();
  //创建单原子广义表
  var q;
  if(/^[\w-]+$/.test(string)){//含有单字符
   this.tag=ATOM;
   this.atom=string;
  }else{
   this.tag=LIST;
   var p =this;
   //去掉最外层括号(和)
   var sub=string.substr(1,string.length-2);
   do{
    var h,
     i=0,
     k=0,
     n=sub.length,
     ch;
    do{
     ch=sub[i++];
     if(ch=='('){
      ++k;
     }else if(ch==')'){
      --k;
     }
    }while(i<n&&(ch!=','||k!=0));
    //i为第一个逗号分隔索引
    if(i<n){
     h=sub.substr(0,i-1);//每次遍历取出第一个结点,无论是原子还是列表
     sub=sub.substr(i,n-i);
    }else{//最后一组
     h=sub;
     sub='';
    }
    if(h==='()'){//空子表无表头结点
     p.ptr.hp=null;
    }else{//创建表头结点
     this.createList.call((p.ptr.hp=new ListNode()),h);
    }
    q=p;
    //创建表尾结点
    if(sub){
     p=new ListNode();
     p.tag=LIST;
     q.ptr.tp=p;
    }
   }while(sub);
   q.ptr.tp=null;
  }
 };
 //求广义表的深度
 ListNode.prototype.depth=function(){
  return getDepth(this);
 }
 function getDepth(list){//深度为括号的重数,也可理解为左括号出现的个数
  if(!list){
   return 1;
  }else if(list.tag===ATOM){
   return 0;
  }else {
   var m=getDepth(list.ptr.hp)+1;
   var n=getDepth(list.ptr.tp);
   return m>n?m:n;
  }
 }
 var node=new ListNode();
 node.createList('((),(a),(b,(c,d,e)))');
 alert(node.depth());//5
</script>
 </body>
</html>

由于广义表的应用多在于数学领域的公式推导和演算上,这里就不再详解了。

这里补充一下广义表的长度和深度算法:

广义表LS=(f,(),(e),(a,(b,c,d)))的长度是多少,深度是多少

例如上表、长度为4、深度为3、为什么呢

长度的求法为最大括号中的逗号数加一、LS最大括号内有

1. f 元素后边有个逗号、
2.()元素后有个逗号、
3.(e)元素后有个逗号
4. (a,(b,c,d))后边没有逗号 ----把这个看成是一个元素

也就是三个逗号 同样被分成四组、长度就为四了

深度的求法为上面每个元素的括号匹配数加1

1. f元素的深度为0+1=1
2. ()元素深度为1+1=2
3. (e)元素深度为1+1=2
4 . (a,(b,c,d))元素的深度为2+1=3

所以深度为3

综上所诉、长度为4、深度为3

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

Javascript 相关文章推荐
jQuery中绑定事件的命名空间详解
Apr 05 Javascript
JavaScript高级程序设计 阅读笔记(十三) js定义类或对象
Aug 14 Javascript
javascript实现确定和取消提示框效果
Jul 10 Javascript
jQuery组件easyui对话框实现代码
Aug 25 Javascript
jQuery图片切换动画特效
Nov 02 Javascript
jQuery表格(Table)基本操作实例分析
Mar 10 Javascript
IScroll那些事_当内容不足时下拉刷新的解决方法
Jul 18 Javascript
Webpack 之 babel-loader文件预处理器详解
Mar 23 Javascript
Vue数据双向绑定底层实现原理
Nov 22 Javascript
JS精确判断数据类型代码实例
Dec 18 Javascript
Vue如何提升首屏加载速度实例解析
Jun 25 Javascript
antd-日历组件,前后禁止选择,只能选中间一部分的实例
Oct 29 Javascript
JavaScript数据结构之数组的表示方法示例
Apr 12 #Javascript
easyui-edatagrid.js实现回车键结束编辑功能的实例
Apr 12 #Javascript
Vue生命周期示例详解
Apr 12 #Javascript
easyui关于validatebox实现多重规则验证的方法(必看)
Apr 12 #Javascript
easyui-datagrid特殊字符不能显示的处理方法
Apr 12 #Javascript
JavaScript数据结构中串的表示与应用实例
Apr 12 #Javascript
javascript数据结构之串的概念与用法分析
Apr 12 #Javascript
You might like
php报表之jpgraph柱状图实例代码
2011/08/22 PHP
PHP数据集构建JSON格式及新数组的方法
2012/11/07 PHP
PHP获取二叉树镜像的方法
2018/01/17 PHP
laravel框架添加数据,显示数据,返回成功值的方法
2019/10/11 PHP
PHP获取当前时间不准确问题解决方案
2020/08/14 PHP
JavaScript中的一些定位属性[图解]
2010/07/14 Javascript
解析javascript 数组以及json元素的添加删除
2013/06/26 Javascript
我的Node.js学习之路(三)--node.js作用、回调、同步和异步代码 以及事件循环
2014/07/06 Javascript
jsonp跨域请求数据实现手机号码查询实例分析
2015/12/12 Javascript
原生js实现弹出层登录拖拽功能
2016/12/05 Javascript
Javascript实现倒计时(防页面刷新)实例
2016/12/13 Javascript
Bootstrap的modal拖动效果
2016/12/25 Javascript
BootStrap自定义popover,点击区域隐藏功能的实现
2018/01/23 Javascript
关于vuejs中v-if和v-show的区别及v-show不起作用问题
2018/03/26 Javascript
解决jquery有正确返回值但不执行success函数的问题
2018/08/20 jQuery
Vue 框架之键盘事件、健值修饰符、双向数据绑定
2018/11/14 Javascript
JavaScript find()方法及返回数据实例
2020/04/30 Javascript
解决vue cli4升级sass-loader(v8)后报错问题
2020/07/30 Javascript
Node.js path模块,获取文件后缀名操作
2020/11/07 Javascript
[04:48]DOTA2亚洲邀请赛林书豪为VGJ加油
2017/04/01 DOTA
Python程序中设置HTTP代理
2016/11/06 Python
彻底理解Python list切片原理
2017/10/27 Python
django之session与分页(实例讲解)
2017/11/13 Python
100行Python代码实现每天不同时间段定时给女友发消息
2019/09/27 Python
Python numpy大矩阵运算内存不足如何解决
2020/11/19 Python
JACK & JONES荷兰官网:男士服装和鞋子
2021/03/07 全球购物
师范大学音乐表演专业求职信
2013/10/23 职场文书
职业生涯规划怎么写
2013/12/29 职场文书
安全月活动总结
2014/05/05 职场文书
关于读书的演讲稿300字
2014/08/27 职场文书
房屋登记授权委托书范本
2014/10/09 职场文书
志愿者事迹材料
2014/12/26 职场文书
2015年保洁工作总结范文
2015/04/28 职场文书
中考百日冲刺决心书
2015/09/22 职场文书
房地产置业顾问工作总结
2015/10/23 职场文书
前端JavaScript大管家 package.json
2021/11/02 Javascript