線性表(二)--- 單鏈表

鏈式存儲結構的線性表 簡稱爲鏈表。是採用一組地址任意的存儲單元存放線性表中的元素數據。
它需要在每一個數據元素裏保存一個引用下一個數據元素的引用 --- 指針。單鏈表 --- 每個節點只保留一個引用, 該引用指向當前節點的下一個節點, 沒有引用指向頭節點, 尾節點的next引用爲null。
建立的方法
1.頭插法 : 該方法從一個空表開始, 不斷創建新節點,將數據元素存入節點的data域中, 然後不斷地以新節點爲頭節點,並讓新節點指向原來的頭節點。
2.尾插法 : 新節點插入當前鏈表的表尾上, 因此需要爲鏈表定義一個引用變量來保存鏈表的最後一個節點。
查找:(1) 找第index個元素:從header節點依次向下在單鏈表中找第index個節點。 算法:以head爲頭, current爲當前節點(初始時current從header起)0 爲頭節點序號, i 爲計數器 則counter依次下移尋找節點, 並使i 同時遞增記錄節點序號, 直到返回指定節點。
       (2) 找element元素:找到是否又等於給定element值的節點 有返回相應的索引 ,無返回-1。
插入:element的新節點插入到第index個節點的位置上, 找到index - 1的節點, 生成一個數據域爲element的newNode
 使得index -1處的節點的next域指向新的節點, 新節點的next指向原來的index處的節點。
刪除:index個節點刪除, 先找到引用它的index - 1節點, 然後讓index - 1的next指向原來的index  + 1節點 ,釋放index處的節點。
 參考代碼:
public class LinkList<T> {

	//定義一個節點類
	private class Node{
		//保存數據
		private T data;
		//下一個節點域
		private Node next;
		public Node(){
			
		}
		public Node(T data, Node next){
			this.data = data;
			this.next = next;
		}
	}
	//保存頭節點 和 尾節點
	private Node header;
	private Node tail;//trailer   prev域 和 next域  -- 引用域
	//鏈表中的節點數
	private int size;
	
	//創建空鏈表
	public LinkList(){
		header = null; 
		tail = null;
	}
	
	//根據指定元素創建鏈表
	public LinkList(T element){
		header = new Node(element, null);//創建每一個元素是以節點的形式出現的
		tail = header;
		size ++;
	}
	
	//返回鏈表節點的長度
	public int length(){
		return size;
	}
	
	//查找1 回去index處的節點
	public T get(int index){
		return getNodeByIndex(index).data;
	}
	
	//根據索引獲取節點
	private Node getNodeByIndex(int index) {
		
		if(index < 0 || index > size -1){
			throw new IndexOutOfBoundsException("線性表越界");
		}
		Node current = header;
		for(int i = 0; i < size && current != null; i ++, current = current.next){//依次向下尋找節點
			if(i == index){
				return current; 
			}
		}
		return null;
	}
	
	//查找指定的element
	public int locate(T element){
		Node current = header;
		for(int i = 0; i < size && current != null; i ++, current = current.next){//依次向下尋找節點
			if(current.data == element){
				return i; 
			}
		}
		return -1;
	}
	
	//插入數據
	public void insert(T element, int index){
		if(index < 0 || index > size){
			throw new IndexOutOfBoundsException("線性表越界");
		}
		if(header == null){
			add(element);
		}
		else{
			if(index == 0){
				addAtHeader(element);
			}
			else{
				Node preNode = getNodeByIndex(index - 1);
				preNode.next = new Node(element, preNode.next);
				size ++;
			}	
		}	
	}
	
	//頭插法
	public void addAtHeader(T element) {
		
		//作爲一個新的頭
		header = new Node(element, header);
		if(tail == null){
			tail = header;
		}
		size ++;	
	}
	
	//尾插法
	public void add(T element){
		
		//判斷是不是空
		if(header == null){
			header = new Node(element, null);
			tail = header;
		}
		else{
			Node newNode = new Node(element, null);
			tail.next = newNode;
			tail = newNode;
		}
		size ++;
	}
	
	//刪除數據
	public T delete(int index){
		
		if(index < 0 || index > size -1){
			throw new IndexOutOfBoundsException("線性表越界");
		}
		Node delNode = null;
		//被刪除的是頭節點
		if(index == 0){
			header = delNode;
            header = header.next;		
		}
		else{
			Node preNode = getNodeByIndex(index - 1);

			delNode = preNode.next;
			preNode = delNode.next;
			//被刪除節點的next引用賦值爲null
			delNode.next = null;
		}
	   size --;
	   return delNode.data;
	}
	//判斷是否爲空
	public boolean empty(){
		return size == 0;
	}
	
	//清空列表
	public void clear(){
		header = null; 
		tail = null;
		size = 0;
	}
	
	public String toString(){
		if(size == 0){
			return "[]";
		}
		else{
			StringBuffer sb = new StringBuffer("[");
			for(Node current = header; current != null; current = current.next){
				sb.append(current.data.toString() + ", ");//這裏, 後面的空格很重要, 否則輸出時可能出錯
			}
			int len = sb.length();
			return sb.delete(len - 2, len).append("]").toString();
		}
	}
}
測試部分:
public static void main(String[] args) {
		LinkList<Integer> llist = new LinkList<Integer>();
			llist.insert(1, 0);
			llist.add(2);//尾插法
			llist.add(3);
			System.out.println(llist);
			System.out.println("2在中的位置:" + llist.locate(2));
			llist.addAtHeader(4);
			System.out.println(llist);
			System.out.println("第2個位置的元素是:" + llist.get(2));
		}



參考:《瘋狂java突破程序員的基本功的16課》

以上就是這篇的內容,如果存在錯誤的地方或有可以優化的地方,請您指出,謝謝!

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