线性表_单向链表

数据结构

  • 线性表

    零个或多个数据元素的有限排列
    
    数据元素可以为空
    数据元素有限
    数据元素之间的逻辑接口为线性结构
    数据元素类型一致
    
    • 顺序线性表

      使用连续的内存存储单元防止线性数据元素
      
      • 数组
    • 链式线性表

      数据元素可以随意存储在某个存储单元 每个节点会包含其他的节点的地址
      
      • 单向链表 ( 每个节点除了数据元素,还包含一个指向一个指向下一个节点的指针)
      • 双向链表 ( 每个节点除了数据元素,还包含一个指向上一个节点的指针和一个指向下一个节点的指针)
      • 静态链表 (使用顺序结构实现链式线性表)
      • 循环链表
      顺序线性表适合 频繁的 查找 或者知道需要的存储空间大小
      
      链式线性表适合 插入	和 删除操作
      
    • 实现单向链表(typeScript)

      类型声明
      export declare interface Link<T> {
        length: number;//长度
        values:T[];//所有值
        append(ele: T): number;//新增
        setValue(index:number,value:T):void;//修改
        insert(index:number,value:T):void;//插入
        removeElementByIndex(index: number): T | null;//删除
        removeElement(ele: T): number;//删除
        getElementByIndex(index: number): T | null;//获取
        getIndexByElement(ele:T):number;//获取
      }
      
      实现
      import { Link } from "./Link";
      namespace YoLink {
        class Node<T> {
          value: any;
          index: number;
          next: any;
          constructor(value: T | null, index: number, next: Node<T> | null) {
            this.value = value;
            this.index = index;
            this.next = next;
          }
        }
        export class SingLinkList<T> implements Link<T> {
          header: Node<T>;
          eleCount = 0;
          constructor() {
            this.header = new Node(null, 0, null);
          }
          static from<T>(values: T[] = []): SingLinkList<T> {
            const link = new SingLinkList<T>();
            values.forEach(link.append.bind(link));
            return link;
          }
          get length() {
            return this.eleCount;
          }
          set length(len: number) {
            if (len >= this.eleCount) return;
            else if (len < this.eleCount && len > 0) {
              var value: Node<T> = this.header;
              while (--len >= 0 && value != null) {
                value = value.next;
              }
              value.next = null;
              this.eleCount = len;
            } else {
              this.header.next = null;
              this.eleCount = 0;
            }
          }
          _getElement(index: number): Node<T> | null {//内部方法 便于获取对应索引的节点
            var count = index + 1;
            var node: Node<T> = this.header;
            while (--count >= 0 && node != null) {
              node = node.next;
            }
            return node;
          }
          _resetIndex() {//内部方法 重置索引
            var count = this.eleCount;
            var node = this.header;
            var index = -1;
            while (count-- > 0) {
              node = node.next;
              node.index = ++index;
            }
          }
          append(ele: T): number {
            var node = this._getElement(this.eleCount - 1);
            const nextNode = new Node<T>(ele, this.eleCount, null);
            node.next = nextNode;
            this.eleCount += 1;
            return this.eleCount;
          }
      
          getElementByIndex(index: number): T {
            const node = this._getElement(index);
            return node ? node.value : null;
          }
          getIndexByElement(ele: T): number {
            var node = this.header;
            while (node != null) {
              if (node.value == ele) {
                return node.index;
              }
              node = node.next;
            }
            return -1;
          }
          removeElementByIndex(index: number): T | null {
            var node = this._getElement(index);
            if (node == null || node == this.header) {
              return null;
            } else {
              if (node.index == 0) {
                this.header.next == this._getElement(1);
              } else if (node.index == this.eleCount - 1) {
                this._getElement(index - 1).next = null;
              } else {
                this._getElement(index - 1).next = this._getElement(index + 1);
              }
              this.eleCount -= 1;
              this._resetIndex();
            }
          }
          removeElement(ele: T): number {
            if (ele == null) return -1;
            var node = this.header;
            while (node != null && node.next.value != ele) {
              node = node.next;
            }
            if (node == null) return -1;
            const index = node.next.index;
            var selectNode = node.next;
            if (index == 0) {
              this.header.next = selectNode;
            } else {
              node.next = selectNode.next;
            }
            this.eleCount -= 1;
            this._resetIndex();
            // this.deleteElementByIndex(index);
            return index;
          }
          setValue(index: number, value: T) {
            const node = this._getElement(index);
            if (node) {
              node.value = value;
            }
          }
          insert(index: number, value: T) {
            const node = this._getElement(index);
            if (node) {
              const next = node.next;
              const newNode = new Node(value, index, next);
              node.next = newNode;
            } else if (index == this.eleCount) {
              const newNode = new Node(value, index, null);
              const last = this._getElement(this.eleCount - 1);
              last.next = newNode;
            } else {
              return;
            }
            this.eleCount += 1;
            this._resetIndex();
          }
          get a(): number {
            return this.eleCount;
          }
          get values(): T[] {
            const values: T[] = [];
            var node = this.header.next;
            if (node == null) return values;
            do {
              values.push(node.value);
            } while ((node = node.next) != null);
            return values;
          }
        }
      }
      
      测试
      const singLink2: Link<number> = new YoLink.SingLinkList();
      singLink2.append(1);
      singLink2.append(2);
      singLink2.append(3);
      singLink2.append(4);
      console.log(singLink2.values);
      singLink2.removeElement(3);
      console.log(singLink2.getElementByIndex(2));
      singLink2.setValue(2, 100);
      singLink2.insert(1, 66);
      singLink2.insert(30, 99999);
      console.log(singLink2.values);
      singLink2.length = 2;
      console.log(singLink2.values);
      
      const singLink3 = YoLink.SingLinkList.from([1, 2, 4, 5, 6]);
      console.log(singLink3.values);
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值