使用Java實現鏈表的基本操做時,不像C++有那麼明顯的申請空間和釋放空間的語句。在申請空間時,Java使用new關鍵字;在釋放空間時,由於Java使用自動垃圾回收機制,因此通常就是將要釋放的結點的引用都置爲空。java
鏈表中的各元素稱之爲結點。結點使用類來實現,好比雙向鏈表中的結點包括數據自己,指向前一元素的指針以及指向後一元素的指針。node
有時,有的鏈表還有一個頭結點,這個結點能夠簡化鏈表的實現。jsp
以AOJ(Aizu Online Judge)中的一題雙向循環鏈表爲例進行說明。題目連接 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_Cthis
Your task is to implement a double linked list.spa
Write a program which performs the following operations:指針
- insert x: insert an element with key x into the front of the list.
- delete x: delete the first element which has the key of x from the list. If there is not such element, you need not do anything.
- deleteFirst: delete the first element from the list.
- deleteLast: delete the last element from the list.
The input is given in the following format:code
n
command1
command2
...
commandn
In the first line, the number of operations n is given. In the following n lines, the above mentioned operations are given in the following format:orm
- insert x
- delete x
- deleteFirst
- deleteLast
Print all the element (key) in the list after the given operations. Two consequtive keys should be separated by a single space.ip
Constraintselement
Sample Input 1
7 insert 5 insert 2 insert 3 insert 1 delete 3 insert 6 delete 5
Sample Output 1
6 1 2
Sample Input 2
9 insert 5 insert 2 insert 3 insert 1 delete 3 insert 6 delete 5 deleteFirst deleteLast
Sample Output 2
1
題目大意是輸入\(n\)個命令,命令有四種形式。全部命令執行完畢後,輸出鏈表的鍵值。
參考代碼以下:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; // 定義雙向循環鏈表的結點 class Node{ int value; Node prev; Node next; Node(){ } Node(int value){ this.value = value; } } public class Main { static Node head; // 初始化鏈表,這是一個循環鏈表 private static void init(){ head = new Node(); head.next = head; head.prev = head; } // 在鏈表開頭添加結點 public static void insert(int x){ Node temp = new Node(x); temp.next = head.next; temp.prev = head; head.next = temp; temp.next.prev = temp; } //使用兩個方法來實現delete,首先是尋找到結點,而後再刪除 public static void delete(int x){ deleteNode(listSearch(x)); } public static Node listSearch(int x){ Node cur = head.next; while (cur != head && cur.value != x){ cur = cur.next; } return cur; // 此處沒有考慮找不到的狀況,題目說至少有一個元素存在鏈表中 } public static void deleteNode(Node node){ if (node == head){ return; } node.prev.next = node.next; node.next.prev = node.prev; // 將node的引用都置爲null,以即可以儘快回收 node.prev = null; node.next = null; } public static void deleteFirst(){ deleteNode(head.next); } public static void deleteLast(){ deleteNode(head.prev); } // 打印鏈表元素,須要注意空格和換行的問題 private static void printList() { int count = 0; Node cur = head.next; while (cur != head){ if (count++ > 0){ System.out.print(" "); } System.out.print(cur.value); cur = cur.next; } // 最後若是不換行的話會報格式錯誤的問題 System.out.println(); } public static void main(String[] args) throws IOException { init(); // Scanner sc = new Scanner(System.in); // int n = sc.nextInt(); // // for (int i=0; i<n; i++){ // String str = sc.next(); // // equals會超時 // if (str.charAt(0) == 'i'){ // int key = sc.nextInt(); // insert(key); // }else if (str.length() > 6){ // if (str.charAt(6) == 'F') { // deleteFirst(); // }else { // deleteLast(); // } // } else { // int key = sc.nextInt(); // delete(key); // } // } // 使用Scanner時,一直超時,換成下面的就不超時了 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); for (int i=0; i<n; i++){ String str = br.readLine(); if (str.charAt(0) == 'i'){ int key = Integer.parseInt(str.substring(7)); insert(key); } else if (str.charAt(6) == 'F'){ deleteFirst(); } else if (str.charAt(6) == 'L'){ deleteLast(); } else { int key = Integer.parseInt(str.substring(7)); delete(key); } } printList(); } }