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 相关文章推荐
JavaScript 学习初步 入门教程
Mar 25 Javascript
Egret引擎开发指南之运行项目
Sep 03 Javascript
JQuery中ajax方法访问web服务实例
Jul 18 Javascript
jQuery中$.ajax()和$.getJson()同步处理详解
Aug 12 Javascript
javascript封装addLoadEvent实现页面同时加载执行多个函数的方法
Jul 25 Javascript
很酷的星级评分系统原生JS实现
Aug 25 Javascript
JavaScript观察者模式(publish/subscribe)原理与实现方法
Mar 30 Javascript
给vue项目添加ESLint的详细步骤
Sep 29 Javascript
vue2.0 兄弟组件(平级)通讯的实现代码
Jan 15 Javascript
vue源码学习之Object.defineProperty 对数组监听
May 30 Javascript
推荐一个基于Node.js的表单验证库
Feb 15 Javascript
如何利用 JS 脚本实现网页全自动秒杀抢购功能
Oct 12 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的大小写敏感问题整理
2011/12/29 PHP
phpcms手机内容页面添加上一篇和下一篇
2015/06/05 PHP
JQuery模板插件 jquery.tmpl 动态ajax扩展
2011/11/10 Javascript
JavaScript window.document的属性、方法和事件小结
2012/10/24 Javascript
windows下安装nodejs及框架express
2015/08/07 NodeJs
基于 Node.js 实现前后端分离
2016/04/23 Javascript
JS实现简单易用的手机端浮动窗口显示效果
2016/09/07 Javascript
JavaScript之Date_动力节点Java学院整理
2017/06/28 Javascript
Sublime Text新建.vue模板并高亮(图文教程)
2017/10/26 Javascript
Vue条件循环判断+计算属性+绑定样式v-bind的实例
2018/09/18 Javascript
vue实现可视化可拖放的自定义表单的示例代码
2019/03/20 Javascript
小程序如何构建骨架屏
2019/05/29 Javascript
echarts大屏字体自适应的方法步骤
2019/07/12 Javascript
jquery.tagsinput.js实现记录checkbox勾选的顺序
2019/09/21 jQuery
中级前端工程师必须要掌握的27个JavaScript 技巧(干货总结)
2019/09/23 Javascript
layui table 表格上添加日期控件的两种方法
2019/09/28 Javascript
vue中使用rem布局代码详解
2019/10/30 Javascript
详解Python的Django框架中的通用视图
2015/05/04 Python
python图像处理之镜像实现方法
2015/05/30 Python
Python中工作日类库Busines Holiday的介绍与使用
2017/07/06 Python
python移位运算的实现
2019/07/15 Python
详解Python3 中的字符串格式化语法
2020/01/15 Python
新年福利来一波之Python轻松集齐五福(demo)
2020/01/20 Python
pycharm远程连接服务器并配置python interpreter的方法
2020/12/23 Python
html5 video全屏播放/自动播放的实现示例
2020/08/06 HTML / CSS
质量月活动策划方案
2014/03/10 职场文书
电子商务专业毕业生求职信
2014/06/12 职场文书
建筑工地标语
2014/06/18 职场文书
大专学生求职自荐信
2014/07/06 职场文书
语文课外活动总结
2014/08/27 职场文书
关键在于落实心得体会
2014/09/03 职场文书
小学生班干部竞选稿
2015/11/20 职场文书
九年级数学教学反思
2016/02/17 职场文书
90条交通安全宣传标语
2019/10/12 职场文书
关于flex 上下文中自动 margin的问题(完整例子)
2021/05/20 HTML / CSS
MySQL8.0无法启动3534的解决方法
2021/06/03 MySQL