閑著沒事:java雙鏈表的實現:
package org.com.data_structure.list.demo;</p><p>import java.util.List;</p><p>/**<br /> * 雙鏈表的實現<br /> * @author nmw<br /> *<br /> */<br />public final class DoubleLinked {</p><p>/**<br /> * 前端節點<br /> */<br />private transient Node head = new Node(null,null,null); </p><p>/**<br /> * 表示可以在當前的位置插入元素 表示鏈表的大小.<br /> */<br /> private transient int size = 0; </p><p> /**<br /> * 構造不含元素的鏈表<br /> */<br /> public DoubleLinked(){<br /> head.next = head.previous = head;<br /> }</p><p> /**<br /> * 根據給定的鏈表構造新的鏈表/<br /> * @param d<br /> */<br /> public DoubleLinked(DoubleLinked d){<br /> this();<br /> this.addAll(d);<br /> }</p><p>/**<br /> * 鏈表的大小.<br /> * @return<br /> */<br />public int size(){</p><p>return size;<br /> }</p><p>/**<br /> * 鏈表是否為空白.<br /> * @return true or false<br /> */<br />public boolean isEmpty(){</p><p>return size==0;<br />}</p><p>/**<br /> * 是否包含給定的元素<br /> * @param obj<br /> * @return true or false<br /> */<br />public boolean containts(Object obj){</p><p>return this.indexOf(obj) != -1;<br />}</p><p>/**<br /> * 移除鏈表的第一個元素 若鏈表為空白則返回 null<br /> * @return 返回被刪除的元素<br /> */<br />public Object remove(){</p><p>Object obj = null;<br />if(this.size == 0)<br /> return null;</p><p>Node p = head.next; //獲得第一個元素 </p><p>p.next.previous = head; //重構鏈表<br />head.next = p.next; </p><p>this.size -- ; //鏈表大小-1<br />obj = p.obj;<br />return obj;<br />}</p><p>/**<br /> * 移除鏈表中最後一個元素 若鏈表為空白則拋出返回null<br /> * @return 返回最後一個元素<br /> */<br />public Object removeLast(){</p><p>Object obj = null;<br />if(this.size == 0)<br /> return null;</p><p>Node p = this.head.previous; //獲得最後一個節點<br />//重構鏈表<br />p.previous.next = head; //p的上一個元素的下一個元素指向head<br />head.previous = p.previous; //head的上一個元素 指向 p的上一個元素/</p><p>this.size--;<br />obj = p.obj;<br />return obj;<br />}</p><p>/**<br /> * 移除指定索引處的元素 若 index <0或index>size 則泡異常<br /> * 元素下標從0開始<br /> * @param index<br /> * @return 返回指定索引處的元素/<br /> */<br />public Object remove(int index)throws IndexOutOfBoundsException{</p><p>this.check(index); //檢查給定的index是否合理</p><p>Node node = this.getNode(index);</p><p>Node p = node.previous; //當前元素的上一個元素<br />Node n = p.next; //當前元素的下一個元素<br />p.next = n;<br />n.previous = p;</p><p>this.size--;<br />return node.obj;<br />}</p><p>/**<br /> * 移除鏈表中第一次出現時的指定元素<br /> * @param obj<br /> * @return 若存在則返回true 否則返回false.<br /> */<br />public boolean remove(Object obj){</p><p>if(this.size == 0)<br />return false;</p><p>int i = 0;<br />Node node = this.head;<br />boolean fog = false;<br />int size = this.size;<br />if(obj == null)<br />while(i<size){<br />node = node.next;<br />if(node.obj == null){<br />fog = true;<br />break; //表示找到該節點<br />}<br />i++;<br />}<br />else{<br /> while(i<size){<br /> node = node.next;<br /> if(obj.equals(node.obj)){<br /> fog = true;<br /> break;//表示找到該節點<br />}<br /> i++;<br /> }<br />}<br /> //重構鏈表<br />if(fog){<br />Node p = node.previous;<br />Node n = node.next;<br />p.next = n;<br />n.previous = p;<br />}</p><p>return fog;<br />}</p><p>/**<br /> * 刪除元素最後一次出現的節點<br /> * @param o<br /> * @return<br /> */<br />public boolean removeLastOccurrence(Object obj){</p><p>if(this.size == 0)<br />return false;<br />boolean fog = false;<br />int i = 0;<br />int s = this.size;<br />Node node = this.head;<br />Node lastNode = null; //最後出現的節點<br />if(obj == null){<br />while(i<s){<br />node = node.next;<br />if(node.obj == null){<br />lastNode = node;<br />fog = true; //找出最後出現的節點<br />}<br />i++;<br />}<br />}<br />else{<br />while(i<s){<br />node = node.next;<br />if(obj.equals(node.obj)){<br />lastNode = node;<br />fog = true;<br />}<br />i++;<br />}<br />}</p><p>//重構鏈表<br />if(fog){<br />Node p = lastNode.previous;<br />Node n = lastNode.next;<br />p.next = n;<br />n.previous = p;<br />}</p><p>return fog;<br />}</p><p>/**<br /> * 檢查給定值是否越界<br /> * @param index<br /> * @throws IndexOutOfBoundsException<br /> */<br />private void check(int index)throws IndexOutOfBoundsException{</p><p>if(index<0 || index>=this.size)<br />throw new IndexOutOfBoundsException("輸入的值不合理:"+index);<br />}</p><p>/**<br /> * 將元素追加到鏈表的尾部/<br /> * @param obj<br /> * @return<br /> */<br />public boolean add(Object obj){</p><p> Node node = this.createNode(obj);<br /> Node p = this.head.previous; //找出最後一個元素</p><p> node.previous = p; //設定新加元素的上一個元素<br /> node.next = head; //設定新增元素的下一個元素</p><p> p.next = node; //設定增加前最後一個元素的下一個元素/<br /> this.head.previous = node;<br /> this.size++; //鏈表大小+1<br /> return true;<br />}</p><p>/**<br /> * 將指定元素追加到指定位置<br /> * @param index<br /> * @param obj<br /> * @return<br /> */<br />public void add(int index,Object obj){</p><p>this.check(index);</p><p>Node node = this.createNode(obj); //建立新的節點 </p><p>Node indexNode = this.getNode(index); //獲得當前索引處的節點</p><p>Node p = indexNode.previous; //當前索引的上一個節點</p><p>node.previous = p; //新節點的上一個元素<br />node.next = indexNode; //新節點的下一個元素 </p><p>p.next = node; //當前節點的下一個節點指向new Node</p><p>indexNode.previous = node; //當前節點的上一個元素指向 new Node </p><p>this.size++;<br />}</p><p>/**<br /> * 在第一個節點處新增一個節點<br /> * @param obj<br /> * @return true<br /> */<br />public boolean addFirst(Object obj){</p><p>Node newNode = this.createNode(obj); //建立新的 節點<br />Node n = head.next;</p><p>newNode.next = n;<br />newNode.previous = head;</p><p>head.next = newNode;<br />this.size++;<br />return true;<br />}</p><p>/**<br /> * 獲得第一個元素<br /> * @return<br /> */<br />public Object getFirst(){</p><p>if(this.size == 0){<br />return null;<br />}<br />return this.head.next.obj;<br />}</p><p>/**<br /> * 獲得最後一個元素, 若鏈表為空白 則返回null 否則返回最後一個節點的值<br /> * @return<br /> */<br />public Object getLast(){</p><p>if(this.size == 0){<br />return null;<br />}<br />return this.head.previous.obj;<br />}</p><p>/**<br /> * 返回指定索引處的節點值 下標從0開始<br /> * @param index<br /> * @return<br /> */<br />public Object get(int index){</p><p>this.check(index);</p><p>Object obj = null;<br />Node node = this.getNode(index);<br />obj = node.obj;<br />return obj;<br />}</p><p>/**<br /> * 索引從0開始<br /> * @param obj<br /> * @return 返回給定元素在鏈表中索引 若無 則返回null<br /> */<br />public int indexOf(Object obj){</p><p>int i=0;<br />Node node = this.head;<br />int s = this.size;<br />if(obj == null){<br />while(i<s){<br />node = node.next;<br />if(node == null)<br />return i;<br />i++;<br />}<br />}else{<br />while(i<s){<br />node = node.next;<br />if(obj.equals(node.obj))<br />return i;<br />i++;<br />}<br />}</p><p>return -1;<br />}</p><p>/**<br /> * 將鏈表清空<br /> */<br />public void clear(){<br />this.head.next = this.head.previous = null;<br />this.size = 0;<br />}</p><p>/**<br /> * 替換指定索引處的節點<br /> * @param index<br /> * @param obj<br /> * @return<br /> */<br />public Object set(int index,Object obj){</p><p>this.check(index);</p><p>Node node = this.getNode(index); //獲得指定索引處的節點<br />Object o = node.obj; //獲得節點值<br />node.obj = obj; //替換節點值</p><p>return o;<br />}</p><p>/**<br /> * 返回該元素最後一次出現的索引值<br /> * 若包含該元素 則返回下標 負責 返回-1<br /> * @param obj<br /> * @return<br /> */<br />public int lastIndexOf(Object obj){<br />int index = -1;<br />int i = 0;<br />int s = this.size;<br />Node node = this.head;<br />if(obj == null){<br />while(i < s){<br />node = node.next;<br />if(node.obj == null){<br />index = i;<br />}<br />i++;<br />}<br />}<br />else{<br />while(i < s){<br />node = node.next;<br />if(obj.equals(node.obj)){<br />index = i;<br />}<br />i++;<br />}<br />}</p><p>return index;<br />}</p><p>/**<br /> * 返回該鏈表的 數組表示<br /> * @return<br /> */<br />public Object[] toArray(){</p><p>int objLength = this.size;<br />Object[] obj = new Object[objLength];<br />Node node = this.head;<br />int i=0;<br />while(i<objLength){<br />node = node.next;<br />obj[i++] = node.obj;<br />}</p><p>return obj;<br />}</p><p>/**<br /> * 將指定的鏈表最追加到 當前鏈表中<br /> * @param d<br /> * @return<br /> */<br />public boolean addAll(DoubleLinked d){<br />if(d == null)<br />throw new NullPointerException("鏈表不可為空+"+d);<br />Node tlast = this.head.previous; //當前節點的上一個節點<br />Node dfirst = d.head.next; //指定鏈表的第一個節點<br />Node dLast = d.head.previous; //指定節點的最後一個節點</p><p>tlast.next = dfirst; //將鏈表的最後一個節點指向 給定鏈表的第一個節點<br />dfirst.previous = tlast; //指定鏈表的第一元素的上一個節點指向鏈表的最後一個節點</p><p>dLast.next = this.head;<br />this.head.previous = dLast;<br />this.size = this.size + d.size; //新鏈表的長度<br />return true;<br />}</p><p>/**<br /> * 構造一個節點<br /> * @param obj<br /> * @return Node<br /> */<br />private Node createNode(Object obj){<br />return new Node(obj,null,null);<br />}</p><p>private Node getNode(int index){<br />check(index);<br />Node node = this.head;<br />int fog = this.size - index;<br />int i=0;<br />if(fog<=index){<br />while(i<index){<br />node = node.next;<br />i++;<br />}<br />}<br />else{<br />while(i<fog){<br />node = node.previous;<br />i++;<br />}<br />}<br />return node;<br />}</p><p>/**<br /> * 節點元素<br /> * @author nmw<br /> *<br /> */<br />private static class Node{<br />Node next; //節點的下一個元素<br />Object obj ; //節點值<br />Node previous ; //節點上一個原元素 </p><p>public Node(Object obj,Node next,Node previous){<br /> this.obj = obj;<br /> this.next = next;<br /> this.previous = previous;<br />}<br />}</p><p>/**<br /> * 比較兩個鏈表是否相等 若鏈表的每一個元素都相等 則 返回true<br /> */<br />@Override<br />public boolean equals(Object obj) {<br />if(obj == this)<br />return true;<br />else if(obj instanceof DoubleLinked){<br />int i=0;<br />Node n = this.head;<br />DoubleLinked d = (DoubleLinked)obj;<br />Node o = d.head;<br />if(this.size != d.size )<br />return false;<br />while(i<this.size){<br />n = n.next;<br />o = o.next;<br />if(n.obj == null){<br />if(o.obj != null)<br />return false;<br />}<br />else{<br />if(!n.obj.equals(o.obj)){<br />return false;<br />}<br />}<br />}<br />return true;<br />}</p><p>return false;<br />}</p><p>/**<br /> * 返回鏈表的字串表示<br /> */<br />@Override<br />public String toString() {<br />StringBuffer s = new StringBuffer("[ ");<br />Node node = this.head;<br />int i=0;<br />while(i<this.size){<br />node = node.next;<br />s.append(node.obj);<br />i++;<br />if(i != this.size){<br /> s.append(",");<br />}<br />}<br />s.append(" ]");</p><p>return s.toString();<br />}</p><p>public static void main(String[] args){<br />DoubleLinked d = new DoubleLinked();<br />for(int i=0;i<10;i++){<br />d.add(i);<br />}<br />DoubleLinked dl = new DoubleLinked(d);<br />System.out.println(dl.toString());<br />}</p><p>}<br />