1.實現鏈表的步驟
- 1).實現Node節點類(用來保存鏈表中每個節點的數據,以及下一個節點成員)
- 2).實現LinkList鏈表類(用來封裝Node節點類,和用戶實現交互)
- 3).在LinkList類里,實現添加,刪除,根據要查的Node數據來找表中的序號,根據要查的序號來找對應的Node數據.
- 4).在LinkList類里,實現toArrays方法,用來取出鏈表中的Node數據的數組
2.類的實現
/*節點類*/ class Node { private String data; //節點保存的數據 private Node next; //下個節點 public Node(String data){ this.data = data; } public String getData() { return data; } public void setData(String data) { this.data = data; } public Node getNext() { return next; } public void setNext(String data) { this.next = new Node(data); } /*Description: 添加節點 *return : */ public void addNode(String data) { if(getNext()!=null) { this.next.addNode(data); } else { this.setNext(data); } } /*Description: 獲取節點數據 *return : */ public String getData(int index) { String ret =null ; if(index == 0) //如果遞歸到0,則返回當前數據 { ret=data; } else //否則繼續遞歸查找 { ret=this.next.getData(--index); } return ret; } /*Description: 遞歸地查找data位於鏈表哪個序號 *return : -1(表示未找到) */ public int findIndex(String data,int index) { if(this.data.equals(data)) //已找到 { return index; } else if (getNext()==null) //未找到 { return -1; } return this.next.findIndex(data,++index); } /*Description: 遞歸地查找data,並刪除 *data: 要找的data *PreNode: 上個節點,如果為null則當前位於表頭 *index: 表示當前位於鏈表哪個序號 *return : -1(表示未找到) 0~(len-1) (表示data位於鏈表哪個序號) */ public int delData(String data,Node PreNode,int index) { int ret = -1; if(this.data.equals(data)) //刪除 { PreNode.next = this.next; return index; } else if (getNext()==null) //未找到 { return ret; } return this.next.delData(data,this,++index); } } /*鏈表類*/ class LinkList { private Node next; //負責管理的節點 private int len; //統計節點長度 public LinkList(String data) { next = new Node(data); len =1; } /*Description: 添加一個節點數據 *return : */ public void addData(String data) { this.next.addNode(data); len++; } /*Description: 刪除一個節點數據 *return : -1(未找到要刪除的數據) 0~(len-1) (表示data位於鏈表哪個序號) */ public int delData(String data) { int ret=-1; if(len>=0) //鏈表有數據 { if(this.next.getData().equals(data)) //刪除表頭需要特殊處理 { this.next = this.next.getNext(); ret = 0; } else ret = next.delData(data,this.next,1); } if(ret!= -1) //已刪除 { len--; } return ret; } /*Description: 根據index找到對應的節點數據 *return : 返回節點數據 */ public String getNodeData(int index) { String ret=null; if(index>=0 && index<(len)) { ret = next.getData(index); } return ret; } /*Description: 根據data查找節點Node位於鏈表哪個序號 *return : -1(表示未找到) 0~(len-1) (表示data位於鏈表哪個序號) */ public int findNodeIndex(String data) { int ret=-1; if(len>=0) //鏈表有數據 { ret = next.findIndex(data,0); //從序號0開始找 } return ret; } /*Description: 將鏈表中所有的節點數據轉為數組 *return : */ public String[] toArrays() { Node tmp=this.next; String[] arr = new String[len]; for(int i=0; i< len; i++) { arr[i] = tmp.getData(); tmp = tmp.getNext(); } return arr; } public int length() { return len; } }
3.測試代碼
public class Test{ public static void main(String args[]){ LinkList list = new LinkList("小A"); //添加節點數據 list.addData("小B"); list.addData("小C"); list.addData("小D"); list.addData("小E"); //打印節點數據 System.out.println("print Node data:"); for(int i=0;i<list.length();i++) { System.out.println(list.getNodeData(i)); } System.out.println("---------------------"); //查找節點數據的序號 System.out.println("小A的index位於:"+list.findNodeIndex("小A")); System.out.println("小D的index位於:"+list.findNodeIndex("小D")); System.out.println("小F的index位於:"+list.findNodeIndex("小F")); //返回-1,表示未找到 //刪除節點數據 System.out.println("刪除小A,並打印小A之前的位置:"+list.delData("小A")); System.out.println("刪除小E,並打印小E之前的位置:"+list.delData("小E")); //通過數組打印數據 System.out.println("\r\nprint Node data by toArrays() :"); String[] arr=list.toArrays(); for(int i=0;i<arr.length;i++) { System.out.println(arr[i]); } System.out.println("---------------------"); } }
運行打印:
PS:這樣寫,只是簡單的實現某個數據類型的鏈表.在后面我們學習了JAVA-Object類,由於Object類是所有類的超類,所以,我們可以來實現滿足所有類型的鏈表
接下來開始重新修改鏈表.
4.修改鏈表-將節點數據改為Object類型
class Node { private Object data; //節點保存的數據 private Node next; //下個節點 public Node(Object data){ this.data = data; } public Object getData() //獲取數據 { return data; } public void setData(Object data) { this.data = data; } public Node getNext() { return next; } public void setNext(Object data) { this.next = new Node(data); } /*Description: 添加節點 *return : */ public void addNode(Object data) { if(getNext()!=null) { this.next.addNode(data); } else { this.setNext(data); } } /*Description: 獲取節點數據 *return : */ public Object getData(int index) { Object ret =null ; if(index == 0) //如果遞歸到0,則返回當前數據 { ret=data; } else //否則繼續遞歸查找 { ret=this.next.getData(--index); } return ret; } /*Description: 遞歸地查找data位於鏈表哪個序號 *return : -1(表示未找到) */ public int findIndex(Object data,int index) { if(this.data.equals(data)) //已找到 { return index; } else if (getNext()==null) //未找到 { return -1; } return this.next.findIndex(data,++index); } /*Description: 遞歸地查找data,並刪除 *data: 要找的data *PreNode: 上個節點,如果為null則當前位於表頭 *index: 表示當前位於鏈表哪個序號 *return : -1(表示未找到) 0~(len-1) (表示data位於鏈表哪個序號) */ public int delData(Object data,Node PreNode,int index) { int ret = -1; if(this.data.equals(data)) //刪除 { PreNode.next = this.next; return index; } else if (getNext()==null) //未找到 { return ret; } return this.next.delData(data,this,++index); } } /*鏈表類*/ class LinkList { private Node next; //負責管理的節點 private int len; //統計節點長度 public LinkList(Object data) { next = new Node(data); len =1; } /*Description: 添加一個節點數據 *return : */ public void addData(Object data) { this.next.addNode(data); len++; } /*Description: 刪除一個節點數據 *return : -1(未找到要刪除的數據) 0~(len-1) (表示data位於鏈表哪個序號) */ public int delData(Object data) { int ret=-1; if(len>=0) //鏈表有數據 { if(this.next.getData().equals(data)) //刪除表頭需要特殊處理 { this.next = this.next.getNext(); ret = 0; } else ret = next.delData(data,this.next,1); } if(ret!= -1) //已刪除 { len--; } return ret; } /*Description: 根據index找到對應的節點數據 *return : 返回節點數據 */ public Object getNodeData(int index) { Object ret=null; if(index>=0 && index<(len)) { ret = next.getData(index); } return ret; } /*Description: 根據data查找節點Node位於鏈表哪個序號 *return : -1(表示未找到) 0~(len-1) (表示data位於鏈表哪個序號) */ public int findNodeIndex(Object data) { int ret=-1; if(len>=0) //鏈表有數據 { ret = next.findIndex(data,0); //從序號0開始找 } return ret; } /*Description: 將鏈表中所有的節點數據轉為數組 *return : */ public String[] toArrays() { Node tmp=this.next; String[] arr = new String[len]; for(int i=0; i< len; i++) { arr[i] = tmp.getData().toString(); tmp = tmp.getNext(); } return arr; } public int length() { return len; } }
5.測試修改后的鏈表
接下來,我們便來寫一個student學生類,然后通過我們修改后的鏈表來保存該類
5.1 student學生類如下所示:
/*學生類*/ class Student { String name; //名字 String clas; //班級 int score; //成績 Student(String name,String clas,int score) { this.name = name; this.clas = clas; this.score = score; } /*覆寫Object類的equals方法*/ public boolean equals(Object obj) { if(obj == null) //地址為null return false; if(obj instanceof Student == false) //非本類 { System.out.println("ERR"); return false; } if(this == obj) //地址相同 return true; Student st = (Student)obj; if(this.name.equals(st.name) && this.clas.equals(st.clas) && this.score == st.score ) return true; return false; } /*覆寫Object類的toString方法*/ public String toString() { return "姓名:"+name+" 班級:"+clas+" 成績:"+score; } }
5.2 student學生類的測試代碼如下所示:
Student xiaoA = new Student("小A","初1-6班",77); Student xiaoB = new Student("小B","初2-1班",99); Student xiaoC = new Student("小C","初1-2班",66); Student xiaoD = new Student("小D","初2-2班",49); Student xiaoE = new Student("小E","初2-3班",88); Student xiaoF = new Student("小F","初2-3班",89); //創建鏈表,並添加 xiaoA 鏈表節點 LinkList list = new LinkList(xiaoA); //繼續添加節點數據 list.addData(xiaoB); list.addData(xiaoC); list.addData(xiaoD); list.addData(xiaoE); //打印節點數據 System.out.println("print Node data:"); for(int i=0;i<list.length();i++) { System.out.println(list.getNodeData(i)); } System.out.println("---------------------"); //查找節點數據的序號 System.out.println("小A的index位於:"+list.findNodeIndex(xiaoA)); System.out.println("小D的index位於:"+list.findNodeIndex(xiaoD)); System.out.println("小F的index位於:"+list.findNodeIndex(xiaoF)); //返回-1,表示未找到 //刪除節點數據 System.out.println("刪除小A,並打印小A之前的位置:"+list.delData(xiaoA)); System.out.println("刪除小E,並打印小E之前的位置:"+list.delData(xiaoE)); //通過數組打印數據 System.out.println("\r\nprint Node data by toArrays() :"); String[] arr=list.toArrays(); for(int i=0;i<arr.length;i++) { System.out.println(arr[i]); } System.out.println("---------------------");
5.3 打印如下: