1.概念工具
上一個文章裏咱們已經瞭解到鏈表結構,鏈表的特色是長度不固定,不用擔憂插入新元素的時候新增位置的問題。插入一個元素的時候,只要找到插入點就能夠了,不須要總體移動整個結構。測試
這裏咱們瞭解一下雙向鏈表的結構。儘管從鏈表中頭節點遍歷到尾節點很容易,可是反過來,從後向前遍歷就沒有那麼簡單。經過給Node對象增長一個屬性,該屬性存儲指向前驅節點的連接,這樣就容易多了。此時祥鏈表中插入一個節點須要更多的工做,咱們須要指出該節點正確的前驅和後續。可是在從鏈表中刪除節點的時候效率更高了,不須要再查找待刪除節點的前驅節點了。以下圖1演示了雙向鏈表的工做原理。this
圖1spa
首先是要爲Node類增長一個previouse屬性,這個屬性指向當前節點的前驅:code
function Node(element){ this.element = element; this.next = null; this.previous = null; }
雙向鏈表的insert()方法和單項鍊表的相似,可是須要設置新節點的previouse屬性,是其指向該節點的前驅。該方法的定義以下:對象
function insert(newElement , item){ var newNode = new Node(newElement); var current = this.find(item); newNode.next = current.next; newNode.previous = current; current.next = newNode; }
雙向鏈表的刪除remove()方法幣單項鍊表的效率更高,由於不須要查找前驅節點了。首選須要在鏈表中找出存儲待刪除數據的節點,而後設置該節點的next屬性,使其指向待刪除節點的後續。設置該節點的後續的previouse的屬性,使其指向待刪除節點的前驅。以下圖2展現刪除節點的過程:blog
圖2ci
remove()方法的定義以下:element
function remove(item){ var currNode = this.find(item); if(!(currNode.next == null)){ currNode.previous.next = currNode.next; currNode.next.previous = currNode.previous; currNode.next = null; currNode.previous = null; } }
爲了實現反向顯示鏈表中元素的任務,須要給鏈表增長一個工具方法,用來查找鏈表中最後一個節點。findLast()方法找出鏈表中最後一個節點,同時免除從前日後遍歷之苦。以下:rem
function findLast(){ var currNode = this.head; while (!(currNode.next == null)){ currNode = currNode.next; } return currNode; }
有了這個工具方法以後就,就能夠很容易的寫出反向顯示雙向鏈表的元素的方法,dispReverse()方法以下所示:
function dispReverse(){ var currNode = this.head; currNode = this.findLast(); while (!(currNode.previous == null)){ document.write(currNode.element + ' '); currNode = currNode.previous; } }
2.代碼實現
雙向鏈表就上面一些特性,下面是完整的代碼實現和測試代碼:
function Node(element){ this.element = element; this.next = null; this.previous = null; } function LList(){ this.head = new Node('head'); this.find = find; this.insert = insert; this.display = display; this.remove = remove; this.findLast = findLast; this.dispReverse = dispReverse; } function dispReverse(){ var currNode = this.head; currNode = this.findLast(); while (!(currNode.previous == null)){ document.write(currNode.element + ' '); currNode = currNode.previous; } } function findLast(){ var currNode = this.head; while (!(currNode.next == null)){ currNode = currNode.next; } return currNode; } function remove(item){ var currNode = this.find(item); if(!(currNode.next == null)){ currNode.previous.next = currNode.next; currNode.next.previous = currNode.previous; currNode.next = null; currNode.previous = null; } } function display(){ var currNode = this.head; while (!(currNode.next == null)){ document.write(currNode.next.element + ' '); currNode = currNode.next; } } function find(item){ var currNode = this.head; while (currNode.element != item){ currNode = currNode.next; } return currNode; } function insert(newElement , item){ var newNode = new Node(newElement); var current = this.find(item); newNode.next = current.next; newNode.previous = current; current.next = newNode; } var cities = new LList(); cities.insert('Conway','head'); cities.insert('Russellville', 'Conway'); cities.insert('Carlisle', 'Russellville'); cities.insert('Alma' , 'Carlisle'); cities.display(); document.write('<br>'); cities.remove('Carlisle'); cities.display(); document.write('<br>'); cities.dispReverse();