• 链表


    使用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();
        }
    
    }
    
    
    
  • 相关阅读:
    VMWare Workstation的激活码 亲测有效
    虚拟机搭建appRtcDemo的appr.tc服务器
    windows webrtc支持H264的源码编译
    windows webrtc 编译
    获取windows系统分屏个数
    windows cmd窗口光标闪动效果消失
    win10 检测系统是不是正版的 以及slmgr.vbm -dlv命令不生效
    symfonos2
    利用ARP欺骗进行MITM(中间人攻击)
    内网学习之MySQL服务提权
  • 原文地址:https://www.cnblogs.com/WanJiaJia/p/7987853.html
Copyright © 2020-2023  润新知