Java 連結串列-刪除連結串列、修改連結串列、遍歷(二)筆記
阿新 • • 發佈:2018-12-25
上一章連結串列:https://blog.csdn.net/xiaoxin0630/article/details/85197714
這裡用虛擬頭節點 更好理解,設定邊界這些
在上一章,迴圈找元素的時候index-1了,設定虛擬節點,就不需要,讓人更加懂
連結串列的刪除
把要新增的當前元素前一個元素的找到,然後指向當前元素的下一個元素,然後把當前元素指向為空,在c語言好像可以釋放
圖片一樣解釋的很清楚
package com.binglian.LinkedList; /** * 連結串列 * @author binglian * */ public class LinkedList<E>{ /** * 連結串列的建立 * 私有的節點,使用者不需要去了解他到底是怎麼樣連線的 * 連結串列可以理解為火車 儲存的元素 為箱子 多個箱子組成, * 就需要一個節點去連線訪問另一個箱子,就用Node * @author binglian * */ private class Node{ public E e;//儲存元素 public Node next;//節點。 /** * 連線下一個連結串列元素,this. 因為都是同名,所以使用this,然後給 * @param e * @param next */ public Node(E e,Node next){ this.e=e; this.next=next; } public Node(E e){ this(e, null); } public Node(){ this(null, null); } @Override public String toString(){ return e.toString(); } } private Node dummyHead; private int size; public LinkedList(){ dummyHead=new Node(); size=0; } //獲取連結串列中的元素個數 public int getSize(){ return size; } //返回連結串列是否為空 public boolean isEmpty(){ return size ==0; } //在鏈頭新增新的元素e public void addHead(E e){ // Node node=new Node(e);//要新增的元素 // node.next=head;//元素指向 原來頭部的元素 // head=node;//然後再吧要新增的元素做為頭部 //另一種更優化的方法 dummyHead=new Node(e,dummyHead);//指向頭部,然後在變為頭部 size++; } /** *在那個地方新增元素,因為連結串列沒有索引,所以 連結串列更適用於新增元素,而不是查詢 *在連結串列的index(0-based)位置新增新的元素e *索引在連結串列中不是一個常用的操作,所以不怎麼重要理解就好 */ public void add(int index,E e){ if(index<0 || index >=size){ throw new IllegalArgumentException("違法操作,"); } Node prev=dummyHead; for(int i=0;i<index ;i++) //就是迴圈找到要新增元素的位置 prev=prev.next; //連結串列中 順序很重要 // Node node =new Node(e);//新增的元素 // node.next=prev.next;//新增的元素指向index以前位置的下一個元素 // prev.next=node;//然後以前位置的元素 指向新增元素 //和新增元素哪裡一樣 更優化 但是沒有上面的更加容易懂 prev.next=new Node(e,prev.next); size++; } //在連結串列末尾新增新的元素e public void addLast(E e){ add(size,e); } //獲得連結串列的第index(0-based)個位置的元素 //在連結串列中不是一個常用的操作,練習用 public E get(int index){ if(index < 0 ||index >=size) throw new IllegalArgumentException("違法操作"); Node cur=dummyHead.next; for(int i=0;i<index;i++) cur=cur.next; return cur.e; } //獲得連結串列的第一個元素 public E getFirst(){ return get(0); } //修改連結串列中的第index(0-based)個位置的元素為e //在連結串列中不是一個常用的操作,聯絡用 public void set(int index,E e){ if(index < 0 ||index >=size) throw new IllegalArgumentException("非法操作"); Node cur=dummyHead; for(int i=0;i<index;i++) cur=cur.next; cur.e=e; } //查詢連結串列中是否有元素e public boolean contains(E e){ Node cur=dummyHead.next; while(cur !=null){ if(cur.e.equals(e)) return true; cur=cur.next; } return false; } //從連結串列中刪除index(0-based)位置的元素,返回刪除的元素 public E remove(int index){ if(index < 0 ||index >=size) throw new IllegalArgumentException("非法操作"); Node prev=dummyHead; for(int i=0;i<index;i++) prev=prev.next; Node retNode=prev.next; prev.next=retNode.next; size--; return retNode.e; } //從刪除中刪除第一個元素,返回刪除的元素 public E removeFirst(){ return remove(size-1); } @Override public String toString(){ StringBuilder res=new StringBuilder(); Node cur=dummyHead.next; while(cur != null){ res.append(cur+"->"); cur=cur.next; } res.append("NULL"); return res.toString(); } }
附上鍊表實現的棧
陣列和連結串列時間執行都差不多
但是佇列用陣列和迴圈佇列 時間差太多了
package com.binglian.LinkedList; public class LinkedListStack<E> implements Stack<E> { private LinkedList<E> list; public LinkedListStack(){ list=new LinkedList<E>(); } public int getSize() { return list.getSize(); } public boolean isEmpty() { return list.isEmpty(); } public void push(E e) { list.addHead(e); } public E pop() { return list.removeFirst(); } public E peek() { return list.getFirst(); } @Override public String toString(){ StringBuilder res=new StringBuilder(); res.append("Stack:top"); res.append(list); return res.toString(); } public static void main(String[] args){ LinkedListStack<Integer> stack=new LinkedListStack<Integer>(); for(int i=0;i<5;i++){ stack.push(i); System.out.println(stack); } stack.pop(); System.out.println(stack); } }