JS中链表的处理

最近在做关于链表的算法题,觉得有必要对链表的一些知识点做个梳理。当然都是通过看了各种文章组合起来的,感谢别人的分享。

1、链表与数组的差别

         链表 的特性是在中间任意位置添加删除元素的都非常的快,不需要移动其它的元素。通常链表每一个元素都要保存一个指向下一个元素的指针(单链表)。双链表的话每个元素即要保存到下一个元素的指针,还要保存一个上一个元素的指针。循环链表则把最后一个元素中保存下一个元素指针指向第一个元素。  
 
       
数组 是一组具有相同类型和名称的变量的集合。这些变量称为数组的元素,每个数组元素都有一个编号,这个编号叫做下标,我们可以通过下标来区别这些元素。数组元素的个数有时也称之为数组的长度。 
 
        数组是将元素在内存中连续存放,由于每个元素占用内存相同,所以你可以通过下标迅速访问数组中任何元素。但是如果你要在数组中增加一个元素,你需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样的道理,如果你想删除一个元素,你同样需要移动大量元素去填掉被移动的元素。 

        链表恰好相反,链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起。比如:上一个元素有个指针指到下一个元素,以此类推,直到最后一个元素。如果你要访问链表中一个元素,你需要从第一个元素开始,一直找到你需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了, 只要修改元素中的指针就可以了。 
从上面的比较你可以看出,如果你的应用需要快速访问数据,很少或不插入和删除元素,你就应该用数组;相反, 如果你的应用需要经常插入和删除元素你就需要用链表数据结构了。


2、链表特点的代码分析

    创建链表

function ListNode(x){
    this.val = x;
    this.next = null;

}

    链表长度分析(不能像数组那样直接使用 .length):

a、使用递归:

function length(head) {
  return head ? 1 + length(head.next) : 0
}

b、使用循环:

function lengthV2(head) {
  let len = 0
  let node = head

  while (node) {
    len++
    node = node.next
  }

  return len
}

    单向链表的反转(让节点的下一节点指向自身,第一个节点指向null):

a、常规解法

function ReverseList(pHead)
{
    // write code here
    if(pHead == null){
        return null;
    }
    var p = pHead.next;
    var currHead = pHead;
    pHead.next = null;
    var pr;
    while(p){
        pr = p.next;
        p.next = currHead;
        currHead = p;
        p = pr;
    }
    return currHead;

}

b、递归

function ReverseList(pHead)
{
    // write code here
    if(pHead==null){
        return null;
    }else if(pHead.next==null){
        return pHead;
    }
    var currHead = ReverseList(pHead.next);
    pHead.next.next = pHead;
    pHead.next = null;
    return currHead;
}

    

有关链表中元素的增加、删除、更改、查找,可看这篇文章:链表的处理

猜你喜欢

转载自blog.csdn.net/qq_20901397/article/details/80032200