前端面試總結--數據結構與算法四

鏈表

前端的面試中,鏈表仍是常常會被問到。因此熟悉鏈表的結果以及鏈表操做的方法仍是很重要的。
說道存儲多個元素,數組多是最經常使用的數據結構。這種數據結構很是方便,提供了便利店[]語法來訪問它的元素。可是數組的缺點就是對元素進行插入或者刪除操做的成本很高,須要移動元素。
鏈表存儲有序的元素集合,但不一樣於數組,鏈表中的元素在內存中並非連續放置的。每一個元素由一個存儲元素自己的節點和一個指向下一個元素的引用組成。鏈表的一個好處在於,增長或刪除元素的時候不須要移動其它元素。數組的另外一個細節是能夠直接訪問任何位置的任何元素,而要訪問鏈表中間的一個元素,須要從起點開始迭代列表直到找到所需的元素。前端

建立鏈表

function LinkedList(){
    var Node = function(element){
        this.element = element;
        this.next = null;
    }
    var length = 0;
    var head = null;
}

鏈表的方法

append(element) -- 向鏈表尾部添加一個新的項
insert(position, element) -- 向鏈表的特定位置插入一個新的項
remove(element) -- 從鏈表中移除元素
indexOf(element) -- 返回元素在鏈表中的索引。若是鏈表中沒有該元素則返回-1
removeAt(position) -- 從鏈表的特定位置移除一項
isEmpty() -- 若是鏈表中不包含任何元素,返回true,若是鏈表長度大於0返回false
size() -- 返回鏈表包含的元素個數vue

鏈表的完整代碼

function LinkedList(){
        var Node = function(element){
            this.element = element;
            this.next = null;
        }
        var length = 0;
        var head = null;
        
       this.append = function(element){
           var node = new Node(element),current;
           if(head === null){
               head = node;
           } else {
               current = head;
               //循環列表,直到最後一項
               while(current.next){
                   current = current.next;
               }
               //找到最後一項,將其next賦值爲node
               current.next = node;
           }
           length++;
       };
       
       this.removeAt = function(position){
           if(position > -1 && position < length){
               var current = head,
               previous,
               index = 0;
               
               if(position === 0){
                   head = current.next;
               } else {
                   while(index++ < pisition){
                       previous = current;
                       current = current.next;
                   }
                   previous.next = current.next;
               }
               length--;
               
               return current.element;
           } else {
               return null;
           }
       };
       
       this.insert = function(position, element){
           if(position >= 0 && position <= length){
               var node = new Node(element),
               current = head,
               previous,
               index = 0;
               
               if(position === 0){
                   node.next = current;
                   head = node;
               } else {
                   while(index++ < position){
                       previous = current;
                       current = current.next;
                   }
                   previous.next =node;
                   node.next = current;
               }
               
               length++;
               
               return true;
           } else {
               return false;
           }
       };
       
       this.indexOf = function(element){
           var current = head, index = 0;
           while(current){
               if(element === current.element){
                   return index;
               }
               index++;
               current = current.next;
           }
           return -1;
       };
       
       this.remove = function(element){
           var index = this.indexOf(element);
           return this.removeAt(index);
       }
       
       this.isEmpty = function(){
           return length === 0;
       }
       
       this.size = function(){
           return length;
       }
       
       this.getHead = function(){
           return head;
       }
       
 }

雙向鏈表

雙向鏈表和普通鏈表的區別在於,在鏈表中,一個節點只有鏈向下一個節點的連接,而在雙向鏈表中,連接是雙向的。node

function DoublyLinkedList(){
    var Node = function(element){
        this.element = element;
        this.next = null;
        this.prev = null;
    };
    var length = 0;
    var head = null;
    var tail = null;
    
    this.insert = function(position, element){
        if(position >= 0 && position <= length){
            var node = new Node(element),
            current = head,
            previous,
            index = 0;
            if(position === 0){
                if(!head){
                    head = node;
                    tail = node;
                } else {
                    node.next = current;
                    current.previous = node;
                    head = node;
                }
            } else if(position === length){
                current = tail;
                current.next = node;
                node.previous = current;
                tail = node;
            } else {
                while(index++ < position){
                    previous = current;
                    current = current.next;
                }
                node.next = current;
                previous.next = node;
                
                current.prev = node;
                node.prev = previous;
            }
            length++;
            return true;
        } else {
            return false;
        }
    };
    
    this.removeAt = function(position){
        if(position > -1 && position < length){
            var current = head,
            previous,
            index = 0;
            if(position === 0){
                head = current.next;
                if(length === 1){
                    tail = null;
                } else {
                    head.prev = null;
                }
            } else if(position === length-1){
                current = tail;
                tail = current.prev;
                tail.next = null;
            } else {
                while(index++ < position){
                    previous = current;
                    current = current.next;
                }
                previous.next = current.next;
                current.next.prev = previous;
            }
            length--;
            return current.element;
        } else {
            return null;
        }
    }
}

參考書籍:Learning Javascript Data Structures and Algorithms面試

推薦一個找vue,angular組件的輪子工廠 算法

前端面試總結--數據結構與算法一
前端面試總結--數據結構與算法二
前端面試總結--數據結構與算法三segmentfault

相關文章
相關標籤/搜索