js数据结构之链表(单链表、双向链表、循环链表)

首先,链表有以下特点:

1. 存储空间不固定,可灵活扩充

2.方便多次的插入和删除,效率较高

单链表

单链表是最常用的链表,其对数据的操作均为单项的,向后查找的。

/*
链表(基于对象)  此处为单链表
*/
function Node (ele) {
    this.element = ele;
    this.next = null;
}


function LinkedList () {
    this.head = new Node("head");  // 头结点
    this.find = find;   // 根据element值查找节点
    this.findPrevious = findPrevious;
    this.insert = insert;
    this.remove = remove;
    this.display = display;
}


function find (item) {
    var currNode = this.head;
    while(currNode.element !== item) {
        if(currNode.next === null) {
            return false;
        }
        currNode = currNode.next;
    }
    return currNode;
}

function findPrevious (item) {
    var currNode = this.head;
    while(currNode.next!==null&& currNode.next.element!=item){
        currNode = currNode.next;
    }
    return currNode;
}


function insert (newEleContent, item) {
    var newNode = new Node(newEleContent);
    var currNode = this.find(item);    
    newNode.next = currNode.next;
    currNode.next = newNode;
}

function display () {
    var currNode = this.head;
    while(currNode.next !== null){
        console.log(currNode.next.element)
        currNode = currNode.next;
    }
}

function remove (item) {
    var currNode = this.find(item);
    var previousNode = this.findPrevious(currNode.element);
    previousNode.next = currNode.next;
    currNode = null;
}

双向链表

双向链表可以方便地对数据进行向前和向后查找(操作),如播放器正向播放音乐时用户存在上一曲和下一曲的操作需要,此时就用到了双向链表。

function Node (ele) {
    this.element = ele;
    this.next = null;
    this.previous = null;
}



function DuplexLinkedList () {
    this.head = new Node("head");
    this.find = find;
    this.findLast = findLast;
    this.remove = remove;
    this.insert = insert;
    this.display = display;
    this.displayReverse = displayReverse;
}



function find (item) {
    var currNode = this.head;
    while (currNode.element!==item) {
        currNode = currNode.next;
    }

    return currNode;
}



function remove (item) {
    var currNode = this.find(item);
    currNode.previous.next = currNode.next;
    if(currNode.next){
        currNode.next.previous = currNode.previous;    
    }
    currNode = null;
}



function insert (eleContent, item) {
    var newNode = new Node(eleContent);
    var currNode = this.find(item);
    // 先操作新节点,否则会进死循环
    newNode.previous = currNode;    
    newNode.next = currNode.next;
    currNode.next = newNode;
    if(currNode.next.previoue){
        currNode.next.previous = newNode;    
    }
    console.log(newNode);
    
}

function findLast () {
    var currNode = this.head;
    while(currNode.next!==null){
        currNode = currNode.next;
    }
    return currNode;
}

function display () {
    var currNode = this.head;
    while (currNode.next!==null){
        console.log(currNode.next.element);
        currNode = currNode.next;
    }
}

function displayReverse () {
    var currNode = this.findLast();
    console.log(currNode);
    while(currNode.previous!==null){
        console.log(currNode.element);
        currNode = currNode.previous;
    }
}

循环链表

同理,循环链表是单向的,但是可以循环地查找。例如解决约瑟夫环问题

function Node (ele) {
    this.element = ele;
    this.next = null;
}

//循环链表需要将this.head.next指向this.head

function CirLinkedList () {
    this.head = new Node("head");
    this.head.next = this.head;
    this.find = find;
    this.findPrevious = findPrevious;
    this.insert = insert;
    this.remove = remove;
    this.display = display;
}




function find (item) {
    var currNode = this.head;
    while(currNode.element !== item) {
        if(currNode.next === null) {
            return false;
        }
        currNode = currNode.next;
    }
    return currNode;
}

function findPrevious (item) {
    var currNode = this.head;
    while(currNode.next!==null&& currNode.next.element!==item){
        currNode = currNode.next;
    }
    return currNode;
}

function insert (newEleContent, item) {
    var newNode = new Node(newEleContent);
    var currNode = this.find(item);    
    newNode.next = currNode.next;
    currNode.next = newNode;
    console.log(newNode);
}

function display () {
    var currNode = this.head;
    // 循环输出判断需要增加next是不是头节点
    while(currNode.next.element != "head" && currNode.next.element!=="head" ){
        console.log(currNode.next.element);
        currNode = currNode.next;
    }
}

function remove (item) {
    var currNode = this.find(item);
    var previousNode = this.findPrevious(currNode.element);
    previousNode.next = currNode.next;
    currNode = null;
}

 

posted @ 2018-07-15 20:42  TateWang  阅读(274)  评论(0编辑  收藏  举报
Top