【Java資料結構】單鏈表的手動實現及部分操作
阿新 • • 發佈:2021-01-04
連結串列是一種物理儲存結構上非連續儲存結構,資料元素的邏輯順序是通過連結串列中的引用連結次序實現的 。
最近學習了Java資料結構中的單鏈表,為了提高下自己的程式碼能力以及對單鏈表的理解,於是手動實現部分單鏈表的操作。
1. 建立單鏈表 2. 列印單鏈表 3. 找到倒數第一個節點 4. 連結串列的長度 5. 找到倒數第二個節點 6. 找到第n個節點(n從1開始) 7. 是否包含關鍵字key節點 8. 頭插法 9. 尾插法 10. 找到index-1位置的節點 11. 在任意位置插入data節點 12. 找到關鍵字key的節點 13. 刪除第一個出現key的節點 14. 刪除所有key節點 15. 清空一個單鏈表 16. 反轉一個單鏈表 17. 返回中間連結串列,如果有兩個中間節點,返回第二個
MyLinkedList
class Node {
public int val;
public Node next;
public Node() {
}
public Node(int val) {
this.val = val;
}
}
public class MyLinkedList {
public Node head;//表示當前連結串列的頭 預設是null
//建立單鏈表
public void createLinked() {
this.head = new Node(12);
Node node2 = new Node(22);
Node node3 = new Node(32);
Node node4 = new Node(42);
this.head.next = node2;
node2.next = node3;
node3.next = node4;
}
//列印單鏈表
public void display() {
Node cur = this.head;
while (cur != null) {
System.out. print (cur.val +" ");
cur = cur.next;
}
System.out.println();
}
//找到倒數第一個節點
public Node findLastNode() {
if(this.head == null) {
System.out.println("head == null");
return null;
}
Node cur = this.head;
while (cur.next != null) {
cur = cur.next;
}
return cur;
}
//連結串列的長度
public int size() {
Node cur = this.head;
int count = 0;
while(cur != null) {
count++;
cur = cur.next;
}
return count;
}
//找到倒數第二個節點
public Node findLastTwoNode() {
if(this.head == null) {
System.out.println("連結串列為空!");
return null;
}
if(this.head.next == null) {
System.out.println("只有一個節點!");
return null;
}
Node cur = this.head;
while(cur.next.next != null) {
cur = cur.next;
}
return cur;
}
//找到第n個節點(n從1開始)
public Node findN(int n) {
if(this.head == null) {
System.out.println("連結串列為空!");
return null;
}
if(n <= 0) {
System.out.println("n太小了!");
return null;
}
if(n > size()) {
System.out.println("n太大了!");
}
int count = 1;
Node cur = this.head;
while(count != n) {
count++;
cur = cur.next;
}
return cur;
}
//是否包含關鍵字key節點
public boolean contains(int key) {
Node cur = this.head;
while(cur != null) {
if(cur.val == key) {
return true;
}
cur = cur.next;
}
return false;
}
//頭插法
public void addFirst(int data) {
Node node = new Node(data);
if(this.head == null){
this.head = node;
}else{
node.next = this.head;
this.head = node;
}
}
//尾插法
public void addLast(int data) {
Node node = new Node(data);
if(this.head == null) {
this.head = node;
}else{
Node cur = this.head;
while(cur.next != null) {
cur = cur.next;
}
cur.next = node;
}
}
//找到index-1位置的節點
public Node moveIndex(int index) {
Node cur = this.head;
int count = 0;
while(count != index-1) {
cur = cur.next;
count++;
}
return cur;
}
//在任意位置插入data節點
public void addIndex(int index,int data) {
if(index < 0 || index >size()) {
System.out.println("index不合法");
return;
}
if(index == 0) {
addFirst(data);
return;
}
Node cur = moveIndex(index);
Node node= new Node(data);
node.next = cur.next;
cur.next=node;
}
//找到關鍵字key的節點
public Node searchPrev(int key) {
Node cur = this.head;
while(cur.next != null) {
if(cur.next.val == key) {
return cur;
}
cur = cur.next;
}
return null;
}
//刪除第一個出現key的節點
public void remove(int key) {
if(this.head == null) {
return;
}
if(this.head.val == key) {
this.head = this.head.next;
}
Node prev = searchPrev(key);
if(prev == null) {
System.out.println("此前驅為空");
}else{
Node del = prev.next;
prev.next = del.next;
}
}
//刪除所有key節點
public void removeAllKey(int key) {
Node prev = this.head;
Node cur = prev.next;
while(cur != null) {
if(cur.val == key) {
prev.next = cur.next;
}else{
prev = cur;
}
cur = cur.next;
}
if(this.head.val == key) {
this.head = this.head.next;
}
}
//清空一個單鏈表
public void clear() {
this.head = null;
}
//反轉一個單鏈表
public Node reverseList() {
Node cur = this.head;
Node prev = null;
Node newHead = null;
while(cur != null) {
Node curNext = cur.next;
if(curNext == null) {
newHead = cur;
}
cur.next = prev;//後繼變前驅
prev = cur;
cur = curNext;
}
return newHead;
}
//返回中間連結串列,如果有兩個中間節點,返回第二個
public Node middleNode() {
Node fast = this.head;
Node slow = this.head;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
TestDemo
public class TestDemo {
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addFirst(19);
myLinkedList.addFirst(29);
myLinkedList.addFirst(39);
myLinkedList.display();//39 29 19
myLinkedList.addLast(1);
myLinkedList.addLast(2);
myLinkedList.addLast(3);
myLinkedList.addLast(4);
myLinkedList.display();//39 29 19 1 2 3 4
myLinkedList.addIndex(0,110);
myLinkedList.display();//110 39 29 19 1 2 3 4
myLinkedList.addIndex(2,120);
myLinkedList.display();//110 39 120 29 19 1 2 3 4
myLinkedList.addIndex(9,119);
myLinkedList.display();//110 39 120 29 19 1 2 3 4 119
myLinkedList.addIndex(-9,119);
}
public static void main2(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
//這個函式結束之後,我們拿到了當前連結串列的頭節點
myLinkedList.createLinked();
myLinkedList.display();
System.out.println("==================");
int n = 4;
Node ret = myLinkedList.findN(n);
System.out.println("第"+n+"個節點是:"+ret.val);
System.out.println("==================");
System.out.println(myLinkedList.size());
System.out.println("==================");
System.out.println(myLinkedList.contains(421));
}
public static void main1(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
//這個函式結束之後,我們拿到了當前連結串列的頭節點
myLinkedList.createLinked();
myLinkedList.display();
System.out.println("==================");
try {
//放的是可能出現異常程式碼
Node ret = myLinkedList.findLastTwoNode();
System.out.println(ret.val);
}catch (NullPointerException e) {
}
System.out.println("==================");
/*ret = myLinkedList.findLastTwoNode();
System.out.println(ret.val);*/
System.out.println("雖然發生了異常,但是我還是想列印這句話");
}
}
測試結果
39 29 19
39 29 19 1 2 3 4
110 39 29 19 1 2 3 4
110 39 120 29 19 1 2 3 4
110 39 120 29 19 1 2 3 4 119
index不合法