双向链表

86 阅读2分钟

双向链表定义

  • 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针分别指向直接后继和直接前驱.
  • 特点: 从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点.

常用方法的实现

function DoubleLink(){
    function Node(data){
        this.data = data;
        this.prev = null;
        this.next = null;
    }
    
    this.head = null;
    this.tail = null;
    this.length = 0;
    
    // 1. 向链表末尾添加一个元素
    DoubleLink.prototype.append = function(data){
        let newNode = new Node(data);
        if (this.length === 0) { //当前链表中为空时
            this.head = newNode;
            this.tail = newNode;
        }else{
            let current = this.head;
            while(current.next){
                current = current.next;
            }
            
            newNode.prev = current;
            current.next = newNode;
            this.tail = newNode;
        }
        
        this.length += 1;
    }
    
    // 2. 向链表中插入一个元素
    DoubleLink.prototype.insert = function(position, data){
        // 边界判断
        if (position < 0 || position > this.length) return false;
        
        let newNode = new Node(data);
        if (this.length === 0) { // 链表中没有元素
            this.head = newNode;
            this.tail = newNode;
        }else{
            if (position === 0) { // 插入第一个位置
                this.head.prev = newNode;
                newNode.next = this.head;
                this.head = newNode;
            }else{
                if (position === this.length) { // 插入位置在最后
                    this.tail.next = newNode;
                    newNode.prev = this.tail;
                    this.tail = newNode;
                }else{ // 插入位置为中间的某个地方
                    let current = this.head;
                    let index = 0;
                    
                    while(index++ < position){
                        current = current.next;
                    }
                    
                    current.prev.next = newNode;
                    newNode.prev = current.prev;
                    newNode.next = current;
                    current.prev = newNode;
                }
            }
        }
        
        this.length += 1;
    }
    
    // 3.get 获取元素的位置
    DoubleLink.prototype.get = function(position){
        // 判断边界
        if (position < 0 || position >= this.length) return null;
        
        let isForward = this.length / 2 > position;
        if (isForward) { // 位置信息在前面
            let current = this.head;
            let index = 0;
            
            while(index++ < position){
                current = current.next;
            }
            
            return current.data;
        }else{ // 位置信息在后面
            let current = this.tail;
            let index = this.length - 1;
            
            while (index-- > position) {
                current = current.prev;
            }
            
            return current.data;
        }
    }
    
    // 4.indexOf 返回元素在链表中的索引
    DoubleLink.prototype.indexOf = function(data){
        let index = 0;
        let current = this.head;
        
        while(current){
            if (current.data == data) {
                return index;
            }
            current = current.next;
            index++;
        }
        
        return -1;
    }
    
    // 5.update 修改某个位置的元素
    DoubleLink.prototype.update = function(position, data){
        // 边界判断
        if (position < 0 || position >= this.length) return false;
        
        let current = this.head;
        let index = 0;
        while(index++ < position){
            current = current.next;
        }
        
        current.data = data;
        return true;
    }
    
    // 6.removeAt 移除执行位置的元素
    DoubleLink.prototype.removeAt = function(position){
        // 边界处理
        if (position < 0 || position >= this.length) return null;
        
        let current = this.head;
        if (position === 0) { // 当删除的是第一个元素
            this.head.next.prev = null;
            this.head = this.head.next;
        } else if (position === this.length - 1){ // 删除的是最后一个元素
            current = this.tail;
            this.tail.prev.next = null;
            this.tail = this.tail.prev;
        } else {  //删除的是中间的某一个元素
            let index = 0;
            while (index++ < position) {
                current = current.next;
            }
            
            current.prev.next = current.next;
            current.next.prev = current.prev;
            current.prev = null;
            current.next = null;
        }
        
        this.length -= 1;
        return current.data;
    }
    
    // 7. remove 移除某个元素
    DoubleLink.prototype.remove = function(data){
        let index = this.indexOf(data);
        return this.removeAt(index);
    }
    
    // 8.isEmpty 是否为空链表
    DoubleLink.prototype.isEmpty = function(){
        return this.length === 0;
    }
    
    // 9. size 获取链表的长度
    DoubleLink.prototype.size = function(){
        return this.length;
    }
    
    // 10.返回元素的节点数据
    DoubleLink.prototype.toString = function(){
        let endStr = '';
        let current = this.head;
        
        while(currnet){
            endStr += current.data + ' ';
            current = current.next;
        }
        
        return endStr;
    }
    
    // 11. 正向遍历节点字符串形式
    DoubleLink.prototype.forwardString = function(){
        return this.toString();
    }
    
    // 12. 反向遍历节点字符串形式
    DoubleLink.prototype.backwardString = function(){
        let endStr = '';
        let current = this.tail;
        
        while(current){
            endStr += current.data + ' '
            current = current.prev;
        }
        
        return endStr;
    }
}