Java實現連結串列帶註釋

榮迷十二點六發表於2020-12-13

Node類

package cn.hbrj.DataStruct;

/**
 * 節點型別  把一個包含元素和next格子看成是一個節點
 * T data儲存資料元素 
 * Next  訪問當前節點下一個元素
 * @author XuYang
 *
 * @param <T>
 */
public class Node<T> {

	private T m_Date;//需要儲存的資料元素
	
	public T getM_Date() {
		return m_Date;
	}
	public void setM_Date(T m_Date) {
		this.m_Date = m_Date;
	}
	private Node<T> m_pNext;//後繼    引用/物件
	
	
	private Node<T> m_pFront;//前驅
	
	public Node<T> getM_pNext() {
		return m_pNext;
	}
	public void setM_pNext(Node<T> m_pNext) {
		this.m_pNext = m_pNext;
	}
	public Node<T> getM_pFront() {
		return m_pFront;
	}
	public void setM_pFront(Node<T> m_pFront) {
		this.m_pFront = m_pFront;
	}
	//有引數建構函式
	public Node(T pDate){
		m_Date=pDate;//初始化資料的構造方法
		
		m_pNext=null;		
	}
	//無引數建構函式
	public Node(){
		m_Date=null;
		m_pNext=null;
	}
	
	
	
}

連結串列類

package cn.hbrj.DataStruct;

import java.sql.Date;

/**
 * 儲存資料組織資料 
 * 連結串列中的元素  Node<T> node  node.next
 * @author XuYang
 *
 */
public class LinkedList<T> {

	private int m_unsize=0;//連結串列長度
	
	
	//長度只讀的
	public int getM_unsize(){
		return m_unsize;
	}
	 Node<T>  m_Head;//儲存連結串列的頭節點
	
	 Node<T>  m_End;//儲存連結串列的尾節點
	
	//判斷連結串列是否為空
    public boolean isEmpty(){
    	//頭節點為空 連結串列就是看空
    	return m_Head==null?true:false;
    }
    
    
    //新增元素 新增就是尾接點後新增
    
    public void push_back(T pdata){
    	//表面上是新增元素 實際上新增了一個節點
    	Node<T>  pNewNode=new Node<T>(pdata);
    	//給元素包裝成節點
    	if (isEmpty()) {
			m_Head=pNewNode;//如果是空 新節點作為頭節點
		}
    	
    	else {
			m_End.setM_pNext(pNewNode);//如果不為空 設定為尾節點下一個節點
		}
    	m_End=pNewNode;
    	//更新尾節點
    	m_unsize++;   
    	//長度++
    }
    //前插
    /**
     * 
     * @param pdate 插入元素
     * @param pos   插入位置
     * @return
     */
    public boolean insertForward(T pdate,int pos){
    	if (isEmpty()) {
			System.out.println("空連結串列");
			return false;
		}
    	
    	else if (pos>=m_unsize) {
			System.out.println("去你的把,超過了連結串列長度");
			return false;
		}
    	
    	
    	//插入成功的情況
    	if (pos==0) {
			Node<T> pnewNode=new Node<>(pdate);
			//用節點包裝插入資料
			pnewNode.setM_pNext(m_Head);
			//原來的頭節點變成新節點的下一個
			
			m_Head=pnewNode;
			//更新頭節點
			m_unsize++;
			//長度++
			
			return true;
			
			
		}
    	
    	else {
			//插入的位置不是0 
    		//******找位置***** 一個一個找,記得數數(next十次)
    		//要的位置是10
    		//不斷的next  用一個臨時節點 記錄頭節點
    		//第一次    臨時節點.next              1
    		//第二次    臨時節點=臨時節點.next  
    		//          臨時節點.next.             2
    		Node<T>  ptempNode=m_Head;
    		//用臨時節點記錄頭節點
    		Node<T>  pFrontNode=new Node<>();
    		//儲存每個元素的前驅節點
    		
    		//找位置
    		int  utempPos=1;
    		//一個一個推位置的條件
    		while (ptempNode.getM_pNext()!=null&&utempPos<=pos) {
				pFrontNode=ptempNode;//儲存前驅節點
				//儲存了你插入位置的上一個節點 一會兒有用
				
				ptempNode=ptempNode.getM_pNext();
				//臨時節點作用 就是不斷的取下一個 直到找到對應位置節點為止
				utempPos++;
			}
    		
    		//插入元素
    		Node<T>  pnewNode=new Node<>(pdate);
    		
    		//插入  
    		pnewNode.setM_pNext(ptempNode);
    		//新節點下一個設定為插入位置的節點
    		pFrontNode.setM_pNext(pnewNode);
    		//儲存的前驅 下一個就是插入的新節點
    		
    		
    		m_unsize++;//長度++

       }
    	return true;
    	//單連結串列  
    	//連結串列和陣列有什麼區別?
    
    	//1.連結串列的後插
    	//2.連結串列的刪除
    	
    	//棧和佇列 順序列  鏈列 順序棧  鏈棧
    	//
    }



    //小問題 前插入 有重複的指令碼 插入成功有多種情況
    public boolean insertBack(T pdata,int pos){
    	boolean isRet=false;//標記插入是否成功
    	
    	//不在if寫return   如果失敗/成功  設定isRet  然後break
    	do {
			if (isEmpty()) {
				System.out.println("連結串列為空");
				break;
			}
			else if (pos>=m_unsize) {
				System.out.println("去你的把越界了");
				break;
			}
			
			//插入成功
			Node<T>  pnewNode=new Node<>(pdata);//插入的元素
			if (pos==0) {
				pnewNode.setM_pNext(m_Head.getM_pNext());
				
				m_Head.setM_pNext(pnewNode);
				
			}
			else if(pos==m_unsize-1) {
				m_End.setM_pNext(pnewNode);
				//最後位置插入
				m_End=pnewNode;
				//更新尾節點
			}
			else {
				Node<T>  ptempNode=m_Head;
				//記錄頭節點
				
				int ptempIndex=1;
				//遍歷索引初始值
				while(ptempNode.getM_pNext()!=null&&ptempIndex<=pos){
					ptempNode=ptempNode.getM_pNext();
					
					ptempIndex++;
					//如果 是  1  臨時節點 往下走了一次
					//ptempNode  第二個節點
				}
				//後插  不用記錄前驅
				pnewNode.setM_pNext(ptempNode.getM_pNext());
				//先設定新節點的下一個為插入位置節點的下一個
				ptempNode.setM_pNext(pnewNode);
				//設定插入位置節點的下一個為新節點
			}
			isRet=true;
		} while (false);
    	if (isRet) {
			m_unsize++;
		}
    	else {
			System.out.println("有誤");
		}
    	return isRet;
    }
    

    
  
    public T removeAt(int pos){
    	
    	boolean isRet=false;//標記刪除是否成功
    	T temp=null;//刪除的元素
    	
    	
    	Node<T> ptempNode=null;//記錄空節點
    	
    	do {
			if (isEmpty()) {
				break;
			}
			else if (pos>=m_unsize) {
				break;
			}
			if (pos==0) {
				//刪除頭節點
				ptempNode=m_Head;//記錄下來返回用
				m_Head=m_Head.getM_pNext();
				//把原來的第二節點設定為頭節點
				//第二節點的下一個是第三節點
				
				//新的頭節點 下一個是原來第三個嗎  是
				
			}
			else {
				Node<T> pFront=null;//記錄每個節點的前驅節點
				
				ptempNode=m_Head;//要刪除那個 暫時記錄頭節點
				
				int tempIndex=1;
				
				while (ptempNode.getM_pNext()!=null&&tempIndex<=pos) {
					pFront=ptempNode;
					
					ptempNode=ptempNode.getM_pNext();
					
					tempIndex++;
				}
				//迴圈完成 找到了要刪除的節點
				
				pFront.setM_pNext(ptempNode.getM_pNext());
				//設定刪除位置的前驅節點 下一個為 刪除位置的後繼節點
				
				
			}
			isRet=true;
		} while (false);
    	
    	if (isRet) {
			if (m_unsize>0) {
				m_unsize--;
			}
			//刪除元素的時候 連結串列儲存是無序的 利用記憶體可能都是零零散散的
			System.gc();//強制回收
		}
    	
    	return temp;//記得返回刪除的元素
    }
    public T  getElement(int index){
    	
    	
    	//連結串列查詢效率低
    	T temp=null;
    	//中間變數
    	if (isEmpty()) {
			System.out.println("連結串列沒東西");
		}
    	else {
			Node<T>  ptempNode=m_Head;
			
			int tempIndex=1;
			while (ptempNode.getM_pNext()!=null&&tempIndex<=index) {
				ptempNode=ptempNode.getM_pNext();
				
				tempIndex++;
			}
			
			temp=ptempNode.getM_Date();
		}
    	return temp;
    }
    
    //全部清除
    public void clear(){
    	Node<T> ptempNode=null;
    	//記錄頭節點
    	while(m_Head!=null){
    		ptempNode=m_Head;
    		//每次都讓臨時變數是最新的頭節點
    		m_Head=m_Head.getM_pNext();
    		//設定頭節點為下一個
    		
    		ptempNode=null;//刪除了上一次的頭節點
    		
    	}
    	System.gc();
    }
}

相關文章