• javascript实现数据结构: 串的块链存储表示


      和线性表的链式存储结构相类似,也可采用链式方式存储串值。由于串结构的特殊性--结构中的每个数据元素是一个字符,则用链表存储串值时,存在一个“结点大小”的问题,即每个结点可以存放一个字符,也可以存放多个字符。

      下面是结点大小为4(即每个结点存放4个字符)的链表:

      head --> (a) --> (b) --> (c) --> ... --> (i)

      当结点大小大于1时,由于串长不一定是结点大小的整倍数,则链表中的最后一个结点不一定全被串值占满,此时通常补上“#”或其它非串值字符。

      为了便于进行串的操作,当以链表存储串值时,除头指针外还可附设一个尾指针指示链表中的最后一个结点,并给出当前串的长度,称如此定义的串存储结构为块链结构。

      由于一般情况下,对串进行操作时,只需要从头向尾顺序扫描即可,则对串值不必建立双向链表。设尾指针的目的是为了便于进行连接操作,但应注意连接时需处理第一个串尾的无效字符。

      在链式存储方式中,结点大小的选择和顺序存储方式的格式选择一样都很重要,它直接影响到串处理的效率。如果串很长,这要求我们考虑串值的存储密度:

      存储密度 = 串值所占的存储位 / 实际分配的存储位

      串值的链式存储结构对某些串操作,如连接操作等有一定方便之处,但总的来说不如另外两种存储结构灵活,它占用存储量大且操作复杂。

      实现代码:

      复制代码

      1 function Chunk(chunkSize) {

      2 this.chunkSize = chunkSize || 4;

      3 this.ch = [];

      4 for (var i = 0; i < this.chunkSize; i++) {

      5 this.ch[i] = '#';

      6 }

      7 // type: Chunk

      8 this.next = null;

      9 }

      10

      11 exports.LString = LString;

      12 function LString(chunkSize) {

      13 // type Chunk

      14 this.head = null;

      15 // type: chunk

      16 this.tail = null;

      17 // 串的当前长度

      18 this.length = 0;

      19 this.chunkSize = chunkSize || 4;

      20 }

      21

      22 LString.prototype = {

      23 // 将字符串转换成LString类型

      24 strAssign: function (chars) {

      25 this.head = this.tail = new Chunk(this.chunkSize);

      26 this.length = chars.length;

      27

      28 var current = this.head;

      29 for (var i = 0, len = chars.length; i < len; i++) {

      30 current.ch[i % this.chunkSize] = chars[i];

      31 if (i + 1 < len && (i + 1) % this.chunkSize === 0) {

      32 current.next = new Chunk();

      33 current = current.next;

      34 }

      35 }

      36

      37 this.tail = current;

      38 },

      39 // 字符串对比

      40 // TODO 是否去掉chunkSize的对比

      41 strCompare: function (tLString) {

      42 var current = this.head;

      43 var curT = tLString.head;

      44

      45 if (this.length !== tLString.length) return false;

      46

      47 while (current) {

      48 for (var i = 0; i < this.chunkSize; i++) {

      49 if (current.ch[i] !== curT.ch[i]) return false;

      50 }

      51

      52 current = current.next;

      53 curT = curT.next;

      54 }

      55

      56 return true;

      57 },

      58 clearString: function () {

      59 this.head = this.tail = null;

      60 this.length = 0;

      61 },

      62 concat: function (tLSting) {

      63 if (!tLSting.length) return;

      64

      65 var ret = new LString(this.chunkSize);

      66

      67 if (this.head === null) {

      68 copyString(ret, tLSting);

      69 } else {

      70 ret.head = ret.tail = new Chunk(this.chunkSize);

      71 copyString(ret, this);

      72

      73 var index = ret.tail.ch.indexOf('#');

      74 if (index === -1) {

      75 copyString(ret, tLSting);

      76 } else {

      77 copyString(ret, tLSting, ret.tail, tLSting.head, index);

      78 }

      79 }

      80

      81 return ret;

      82 },

      83 substring: function (pos, len) {

      84 pos = ~~pos || 0;

      85 len = ~~len || this.length;

      86 if (pos < 0 || pos > this.length - 1 || len < 0 || len > this.length - pos)

      87 throw new Error('unexpected parameter');

      88

      89 var sub = new LString(this.chunkSize);

      90 var current = findPosChunk(this, pos);

      91 var curS = sub.head = new Chunk(this.chunkSize);

      92 var i = 0;

      93 sub.length = len;

      94

      95 outerloop: while (current) {

      96 for (var j = 0, size = this.chunkSize; j < size; j++) {

      97 if (i === len) {

      98 break outerloop;

      99 } else {

      100 curS.ch[j] = current.ch[(i + pos) % this.chunkSize];

      101 i++;

      102 if ((i + pos) % this.chunkSize === 0) {

      103 current = current.next;

      104 }

      105 if (i % this.chunkSize === 0 && (current.ch[i] || current.next)) {

      106 curS.next = new Chunk(this.chunkSize);

      107 curS = curS.next;

      108 }

      109 }

      110 }

      111 }

      112

      113 return sub;

      114 },

      115 toString: function () {

      116 var current = this.head;

      117

      118 if (current === null) return '';

      119

      120 var str = '';

      121 while (current) {

      122 for (var i = 0, len = this.chunkSize; i < len; i++) {

      123 var ch = current.ch[i];

      124 if (ch === '#') {

      125 return str;

      126 } else {

      127 str += current.ch[i];

      128 }

      129 }

      130 current = current.next;

      131 }

      132

      133 return str;

      134 }

      135 };

      136

      137 function findPosChunk(lString, pos) {

      138 var current = lString.head;

      139 while (current) {

      140 for (var i = 0, len = lString.chunkSize; i < len; i++) {

      141 if (pos-- === 0) return current;

      142 }

      143 current = current.next;

      144 }

      145 }

      146

      147 function copyString(destination, target, curD, currT, offset) {

      148 offset = offset || 0;

      149 currT = currT || target.head;

      150 curD = curD || destination.head;

      151 var k = 0;

      152

      153 while (currT) {

      154 for (var i = 0, len = target.chunkSize; i < len; i++, k++) {

      155 var j = k % curD.chunkSize + offset;

      156 curD.ch[j % curD.chunkSize] = currT.ch[i];

      157

      158 if ((j + 1) % curD.chunkSize === 0 && (currT.ch[i + 1] || currT.next)) {

      159 curD.next = new Chunk(destination.chunkSize);

      160 curD = curD.next;

      161 }

      162 }

      163

      164 currT = currT.next;

      165 }

      166

      167 destination.tail = curD;

      168 destination.length += target.length;

      169 }

      170

      171 var a = new LString();

      172 var b = new LString();

      173 var c = new LString();

      174

      175 a.strAssign('abcdefg');

      176 console.log(a + '');

      177 b.strAssign('hijklmno');

      178 console.log(b + '');

      179 c.strAssign('abcdefg');

      180 console.log(a.strCompare(b));

      181 console.log(a.strCompare(c));

      182 var t = a.concat(b);

      183 console.log(t + '');

      184 t = t.substring(2, 5);

      185 console.log(t + '');

  • 相关阅读:
    c++ configure帮助
    YML项目阶段性总结
    layerui 页面定位和行定位
    [转]Debian 下部署 PHP 运行环境
    win10限制访问解决
    各linux版本重启apache命令
    debian 下py2.7 安装mysql模块
    debian9 安装 odoo11 笔记用 部分内容转载前辈的,在此感谢
    在 DEBIAN 上安装 SQL SERVER
    [转帖 ]MySQL 5.7 新特性 JSON
  • 原文地址:https://www.cnblogs.com/asds/p/7651457.html
Copyright © 2020-2023  润新知