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 相关文章推荐
网页设计常用的一些技巧
Dec 22 Javascript
解决Extjs 4 Panel作为Window组件的子组件时出现双重边框问题
Jan 11 Javascript
javascript 数组排序函数sort和reverse使用介绍
Nov 21 Javascript
JavaScript中读取和保存文件实例
May 08 Javascript
javascript动态判断html元素并执行不同的操作
Jun 16 Javascript
JavaScript jQuery 中定义数组与操作及jquery数组操作
Dec 18 Javascript
JS基于构造函数实现的菜单滑动显隐效果【测试可用】
Jun 21 Javascript
js检测离开或刷新页面时表单数据是否更改的方法
Aug 02 Javascript
angularjs封装$http为factory的方法
May 18 Javascript
webpack打包优化的几个方法总结
Feb 10 Javascript
Vue 实现监听窗口关闭事件,并在窗口关闭前发送请求
Sep 01 Javascript
vue配置型表格基于el-table拓展之table-plus组件
Apr 12 Vue.js
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操作excel文件 基于phpexcel
2010/07/02 PHP
Android ProgressBar进度条和ProgressDialog进度框的展示DEMO
2013/06/19 PHP
CodeIgniter生成网站sitemap地图的方法
2013/11/13 PHP
php在线解压ZIP文件的方法
2014/12/30 PHP
Zend Framework数据库操作方法实例总结
2016/12/11 PHP
thinkPHP实现的省市区三级联动功能示例
2017/05/05 PHP
关于viewport,Ext.panel和Ext.form.panel的关系
2009/05/07 Javascript
关于JS控制代码暂停的实现方法分享
2012/10/11 Javascript
js iframe跨域访问(同主域/非同主域)分别深入介绍
2013/01/24 Javascript
一个JavaScript递归实现反转数组字符串的实例
2014/10/14 Javascript
jQuery操作cookie方法实例教程
2014/11/25 Javascript
javascript常用功能汇总
2015/07/05 Javascript
Bootstrap入门书籍之(一)排版
2016/02/17 Javascript
jQuery+ajax简单实现文件上传的方法
2016/06/03 Javascript
jQuery中each循环的跳出和结束实例
2017/08/16 jQuery
React Native 使用Fetch发送网络请求的示例代码
2017/12/02 Javascript
Vue侧滑菜单组件——DrawerLayout
2017/12/18 Javascript
vue 优化CDN加速的方法示例
2018/09/19 Javascript
element vue validate验证名称重复 输入框与后台重复验证 特殊字符 字符长度 及注意事项小结【实例代码】
2018/11/20 Javascript
如何解决webpack-dev-server代理常切换问题
2019/01/09 Javascript
微信小程序使用字体图标的方法
2019/05/23 Javascript
vue框架制作购物车小球动画效果实例代码
2019/09/26 Javascript
jQuery实现可编辑的表格
2019/12/11 jQuery
Python中elasticsearch插入和更新数据的实现方法
2018/04/01 Python
python 自动重连wifi windows的方法
2018/12/18 Python
python 3.74 运行import numpy as np 报错lib\site-packages\numpy\__init__.py
2019/10/06 Python
Python单链表原理与实现方法详解
2020/02/22 Python
Python实现的北京积分落户数据分析示例
2020/03/27 Python
Python Request类源码实现方法及原理解析
2020/08/17 Python
Python实现京东抢秒杀功能
2021/01/25 Python
第二层交换机和路由器的区别?第三层交换机和路由器的区别?
2013/05/23 面试题
大学校园生活自我鉴定
2014/01/13 职场文书
2014年资料员工作总结
2014/11/18 职场文书
童年读书笔记
2015/06/26 职场文书
python3.9之你应该知道的新特性详解
2021/04/29 Python
MySQL COUNT函数的使用与优化
2021/05/10 MySQL