Java實現連結串列帶註釋
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();
}
}
相關文章
- java實現連結串列反轉Java
- java實現雙向連結串列Java
- 連結串列-單連結串列實現
- 圖解雙連結串列(Java實現)圖解Java
- FreeRTOS連結串列實現
- Python實現單連結串列Python
- 實現雙向連結串列
- 演算法與資料結構-連結串列((linked-list)-Java實現單向連結串列演算法資料結構Java
- 用連結串列的方式實現大數相減-Java實現Java
- Java實現單向連結串列基本功能Java
- 【資料結構】連結串列(單連結串列實現+詳解+原碼)資料結構
- TypeScript 實現連結串列反轉TypeScript
- 連結串列找環(python實現)Python
- Go實現雙向連結串列Go
- go 實現單向連結串列Go
- golang 實現連結串列爽不爽?Golang
- 019 透過連結串列學Rust之雙連結串列實現PeekRust
- 019 通過連結串列學Rust之雙連結串列實現PeekRust
- (超詳細)動手編寫-連結串列(Java實現)Java
- 單連結串列實現原理以及具體程式碼(java)Java
- pta重排連結串列(一個很清晰的實現,完全模擬連結串列的實現)
- 詳細分析連結串列的資料結構的實現過程(Java 實現)資料結構Java
- 單連結串列建立連結串列出現問題
- Java兩種方式實現連結串列的刪除,返回頭結點Java
- java實現單連結串列、棧、佇列三種資料結構Java佇列資料結構
- 【演算法-java實現】合併兩個有序連結串列演算法Java
- PHP 使用連結串列實現對映PHP
- [連結串列]leetcode138-複製帶隨即指標的連結串列LeetCode指標
- 023 透過連結串列學Rust之非安全方式實現連結串列1Rust
- 024 透過連結串列學Rust之非安全方式實現連結串列2Rust
- 023 通過連結串列學Rust之非安全方式實現連結串列1Rust
- 024 通過連結串列學Rust之非安全方式實現連結串列2Rust
- js實現資料結構--單連結串列JS資料結構
- 詳細分析連結串列中的遞迴性質(Java 實現)遞迴Java
- 013 透過連結串列學習Rust之實現連結串列的通用函式Rust函式
- 013 通過連結串列學習Rust之實現連結串列的通用函式Rust函式
- 用連結串列實現佇列的功能佇列
- 雙向連結串列的功能實現(初版