数据结构与算法--链表

148 阅读2分钟

链表是什么

链表是多个元素组成的有序列表,但元素存储是不连续的,用next指针连在一起。

数组与链表的区别:数组增删非首尾元素时往往需要移动元素。而链表增删非首尾元素,不需要移动元素,只需要更改next的指向即可。

javascrit中没有链表,但是可以使用Object模拟链表

let a = { val: 'a' };
let b = { val: 'b' };
let c = { val: 'c' };
let d = { val: 'd' };

a.next = b;
b.next = c;
c.next = d;

//遍历链表
let pointer = a;
while (pointer) {
    console.log(pointer.val);
    pointer = pointer.next;
}

//插入
let e = { val: 'e' };
c.next = e;
e.next = d;

//删除
c.next = d;

前端与链表

1、js中的原型链

  • 原型链的本质是链表
  • 原型链上的节点是各种原型对象,比如Function.prototype、Object.prototype...
  • 原型链通过__proto__属性连接各种原型对象

原型链长啥样?

  • obj -> Object.prototype -> null
  • func -> Function.prototype -> Object.prototype -> null
  • arr -> Array.prototype -> Object.prototype -> null

原型链知识点:

  • 1、如果A沿着原型链能找到B.prototype,那么A instanceof B为true
  • 2、如果在A对象上没有找到x属性,那么会沿着原型链找x属性
//实现instanceOf,判断一个变量是否是另外一个变量的实例
function instanceOf(A, B){
    let p = A;
    
    while(p){
        if(p === B.prototype){
            return true;
        }
        p = p.__proto__;
    }
    return false;
}

//属性
var foo = {};
var F = ()=> {}

Object.prototype.a = 'value a';
Function.prototype.b = 'value b';

console.log(foo.a); //'value a'
console.log(foo.b); //undefined

console.log(F.a); //'value a'
console.log(F.b); //'value b'

2、使用链表指针获取JSON的节点值

function getValueByPath(obj, path){
    let p = obj;
    path.forEach(k => {
        p = p[k];
    });
    return p;
}

var json = {
    a: {b: { c: 'c'}},
    d: {e : 'e'}
};
const path = ['a', 'b', 'c'];
var value = getValueByPath(json, path);

应用

1、删除链表中的节点(力扣237)

链表中无法直接获取删除节点的上一个节点,所以可以将被删除节点转移下一个节点实现删除

var deleteNode = function(node) {
    node.val = node.next.val;
    node.next = node.next.next;
};

2、两数相加(力扣2)

3、判断环形链表(力扣141)

var hasCycle = function(head) {
    let p1 = head;
    let p2 = head;

    while(p1 && p2 && p2.next){
        p1 = p1.next;
        p2 = p2.next.next;
        if(p1 === p2){
            return true;
        }
    }
    return false;
};

知识来源: coding.imooc.com/learn/list/…