链表

使用Java实现链表的基本操作时,不像C++有那么明显的申请空间和释放空间的语句。在申请空间时,Java使用new关键字;在释放空间时,因为Java使用自动垃圾回收机制,所以一般就是将要释放的结点的引用都置为空。

链表中的各元素称之为结点。结点使用类来实现,比如双向链表中的结点包括数据本身,指向前一元素的指针以及指向后一元素的指针。

有时,有的链表还有一个头结点,这个结点可以简化链表的实现。

以AOJ(Aizu Online Judge)中的一题双向循环链表为例进行说明。题目链接 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_C

Your task is to implement a double linked list.

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:

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:

  • 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.

Constraints

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

}

转载于:https://www.cnblogs.com/WanJiaJia/p/7987853.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值