單鏈表的實現

週末跟同窗聊起他面試的事,被問起單鏈表翻轉。當時想了個算法,遍歷鏈表節點,就地翻轉。node

後面上網查了下,有三種:面試

1,弄個新鏈表,把舊鏈表每一個節點都insertFirst。算法

2,弄個數組,存儲舊鏈表,而後遍歷一輪,翻轉。數組

3,遍歷鏈表的節點,就地翻轉,性能最快。數據結構

 

後來,想找個JS單鏈表的類,沒找到想要的。。。雙向鏈表居多。被迫無賴,本身寫了個。框架

 

!function(window) {
    var Util = window.Util =  {};
    var Node = Util.Node = function(data){
        //data contains
        this.data = data;
        //next node
        this.next = null;
    }

    Util.LinkedList = function(){
        this.head = null;
    }

    var fn = Util.LinkedList.prototype;
    /**
     * insert data to the head
     * @param data
     * @returns {boolean}
     */
    fn.insertFirst = function(data){
        var node= new Node(data);
        if(this.isEmpty()) {
            this.head = node;
            return true;
        }
        node.next = this.head;
        //change head to the new node
        this.head = node;
        return true;
    }
    /**
     * insert data to the last
     * @param data
     * @returns {boolean}
     */
    fn.insertLast = function(data){
        var node = new Node(data);
        if(this.isEmpty()) {
            //node = head;
            this.head = node;
            return true;
        }
        var p = this.head;
        var pre = this.head;
        //get the last node
        while(!this.isEnd(p)) {
            pre = p;
            p = p.next;
        }
        p.next = node;
        return false;
    }
    /**
     * insert newData before oldData
     * @param oldData
     * @param newData
     * @returns {boolean}
     */
    fn.insertBefore = function(oldData,newData){
        var preNode = this.find(oldData,true);

        if(preNode==null) {
            return false;
        }
        var newNode = new Node(newData);
        if(preNode == this.head) {
            this.insertFirst(newData);
        }else {
            var pNode = preNode.next;
            newNode.next = pNode;
            preNode.next = newNode;
        }
        return true;
    }
    /**
     * insert newData after oldData
     * @param oldData
     * @param newData
     * @returns {boolean}
     */
    fn.insertAfter = function(oldData,newData){
            var preNode = this.find(oldData);
            if(preNode == null) {
                return false;
            }
            var newNode = new Node(newData);
            var pNode = preNode.next;
            newNode.next = pNode;
            preNode.next = newNode;//pNode;
            return true;
    }
    /**
     * remove node
     * @param data
     */
    fn.remove = function(data){
        if(this.isEmpty()) {
            return false;
        }
        var preNode = this.find(data,true);
        if(preNode == this.head) {
            this.head = this.head.next;
        }else {
            var pNode = preNode.next;
            preNode.next = pNode.next;
        }
        return true;
    }
    /**
     * update data
     * @param oldData
     * @param newData
     * @returns {boolean}
     */
    fn.update = function(oldData,newData){
        var pNode = this.find(oldData);
        if(pNode != null) {
            pNode.data = newData;
            return true;
        }
        return false;
    }

    fn.find = function(data,flag){
        var p = this.head,
            pre = this.head;
        while(!this.isEnd(p) && p.data != data) {
            pre = p;
            p = p.next;
        }
        if(flag) return pre;
        else return p;
    }
    /**
     * is empty?
     */
    fn.isEmpty = function(){
        return !this.head;
    }
    /**
     * is the last node?
     * @param node
     */
    fn.isEnd = function(node){
        if(!node)
            return false;
        return !node.next;
    }

    fn.toString = function(){
        var pNode = this.head,
            str = "";
        while(pNode!=null) {
            str += pNode.data;
            pNode = pNode.next;
        }
        return str;
    }

    fn.reverse = function(){
        var node = this.head,
            pre,
            nextNext;
        while(node){
            nextNext = node.next;
            node.next = pre;
            pre = node;
            node = nextNext;
        }
        this.head = pre;
        return this;
    }
}(window);
////test code
//function trace(msg){
//    console.log(msg);
//}
//var linkedList = new Util.LinkedList();
//trace(linkedList.isEmpty() == true);
//linkedList.insertFirst(1);
//trace(linkedList.isEmpty() == false);
//linkedList.insertBefore(1,2);
//trace(linkedList.toString() == "21");
//linkedList.insertLast(3);
//trace(linkedList.toString() == "213");
//trace(linkedList.isEnd(linkedList.find(3)) == true);
//linkedList.remove(3);
//trace(linkedList.isEnd(linkedList.find(2)) == false);
//trace(linkedList.isEnd(linkedList.find(1)) == true);
//trace(linkedList.head.data == 2);
//linkedList.insertFirst(1);
//linkedList.insertFirst(2);
//linkedList.insertFirst(3);
//trace(linkedList.toString() == "32121");
//trace(linkedList.reverse().toString() == "12123");
//linkedList.update(2,4);
//trace(linkedList.toString() == "14123");
//linkedList.insertAfter(4,5);
//trace(linkedList.toString() == "145123");
//linkedList.insertBefore(5,6);
//trace(linkedList.toString() == "1465123");

溫習一下感受不錯,出來社會幾年,回頭看這些東西簡單多了。想當年學這些數據結構,都不知道學來幹嗎。整本書看完,都還給老師了。性能

只記得當時那本書是嚴​蔚​寫的,其中有一句話,令我很受教。全部程序都創建在數據和數據操做之上。延伸出來,MVC,MV,MVVM,這些框架,一開始就是model。this

無論作什麼,第一步我都開始弄數據。時間軸的節點就是鏈表,組件與組件之間就是一棵樹。spa

相關文章
相關標籤/搜索