動手寫一個雙向鏈表

單向鏈表就不寫了,進來直接寫雙向鏈表。
首先需要了解雙向鏈表的接口。將鏈的節點抽象爲一個對象,對象存在兩個指針,一個指向前面一個節點,一個指向後面一個節點。
實現雙向鏈表的功能就是對鏈的指針操作。

package com.linked;

/**
 * 實現雙向鏈表
 * @author T
 */
public class LinkedTable<T> {
	
	private Node<T> head;
	private Node<T> tail;
	private int size;
	
	
	//head不存入數據
	public void addFirst(T data){
		Node node = null;
		//如果head爲空,表明鏈表爲空。
		if(head == null){
			node = new Node(data,null,null);
			tail = node;
		} else {
			node = new Node(data,null,head);
			head.previous = node;
		}
		head = node;
		size++;
	}
	
	//head不存入數據
	public void addLast(T data){
		Node node = null;
		if(tail == null){
			node = new Node(data,null,null);
			head = node;
		} else {
			node = new Node(data,tail,null);
			tail.next = node;
		}
		tail = node;
		size++;
	}
	
	public T getFirst(){
		return head.data;
	}
	
	public T getLast(){
		return tail.data;
	}
	
	/**
	 * 通過索引獲取索引所對應節點的值
	 * @param index
	 * @return
	 */
	public T get(int index){
		if(index < 0 || index > size){
			throw new IndexOutOfBoundsException();
		}
		if(index == 0){
			return getFirst();
		}
		if(index == size-1){
			return getLast();
		}
		Node<T> node = getNode(index);
		return node.data;
	}
	
	
	public int size(){
		return size;
	}
	
	/**
	 * 獲取索引節點
	 * @param index
	 * @return
	 */
	private Node<T> getNode(int index){
		if(index < 0 || index > size){
			throw new IndexOutOfBoundsException();
		}
		Node<T> node = head;
		for (int i = 0; i < index; i++) {
			node = node.next;
		}
		return node;
	}
	
	/**
	 * 實現索引加入,索引節點的前方加入
	 * @param data
	 * @param index
	 */
	public void add(T data,int index){
		//獲取索引對應的節點
		Node node = getNode(index);
		
		//創建newNode與前後的關係,previous指向node的前面節點,next指向node
		Node newNode = new Node(data,node.previous,node);
		
		//建立前一個節點與newNode的關係
		node.previous.next = newNode;
		
		//建立後一個節點node與newNode的關係
		node.previous = newNode;
		
		size++;
	}
	
	
	public void delete(int index){
		if(index == 0){
			head.next.previous = head.previous;
			head = head.next;
		} else {
			Node<T> node = getNode(index);
			node.previous.next = node.next;
			node.next.previous = node.previous;
		}
		size--;
	}
	
	
	
	/**
	 * 建立鏈表最小單元-鏈
	 * @author T
	 * @param <T>
	 */
	class Node<T>{
		private T data;
		private Node<T> previous;
		private Node<T> next;
		
		
		public T getData() {
			return data;
		}
		public void setData(T data) {
			this.data = data;
		}
		
		public Node(T data){
			this.data = data;
		}
		public Node<T> getPrevious() {
			return previous;
		}
		public void setPrevious(Node<T> previous) {
			this.previous = previous;
		}
		public Node<T> getNext() {
			return next;
		}
		public void setNext(Node<T> next) {
			this.next = next;
		}
		
		/**
		 * @param data 真實數據
		 * @param previous 前置
		 * @param next 後置
		 */
		public Node(T data, Node<T> previous, Node<T> next) {
			this.data = data;
			this.previous = previous;
			this.next = next;
		}
		
		
		
	}

}

測試一下:

package com.linked;

public class LinkedTableTest {
	
	public static void main(String[] args) {
		LinkedTable<String> lt = new LinkedTable<String>();
		lt.addFirst("10");
		lt.addFirst("11");
		lt.addFirst("12");
		lt.addFirst("13");
		lt.addFirst("14");
		lt.addFirst("15");
		
		lt.add("10.5", 1);
		
		System.out.println("==ready==");
		
		for (int i = 0; i < lt.size(); i++) {
			System.out.println(lt.get(i));
			System.out.println("---------------");
		}
		System.out.println("==delete==");
		lt.delete(1);
		for (int i = 0; i < lt.size(); i++) {
			System.out.println(lt.get(i));
			System.out.println("---------------");
		}
	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章