鏈表

使用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.
Input

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
Output

Print all the element (key) in the list after the given operations. Two consequtive keys should be separated by a single space.ip

Constraintselement

  • The number of operations ≤ 2,000,000
  • The number of delete operations ≤ 20
  • 0 ≤ value of a key ≤ \(10^9\)
  • The number of elements in the list does not exceed \(10^6\)
  • For a delete, deleteFirst or deleteLast operation, there is at least one element in the list.

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();
    }

}
相關文章
相關標籤/搜索