微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在java中使用双向链表制作移动光标

如何解决在java中使用双向链表制作移动光标

我正在尝试在 Java 中为一个简单的移动光标编写代码。我必须使用双向链表。我也应该自己实现doubyLinkedList 类。在这个程序中,我们首先从用户那里取一个n 这样的整数作为行数。然后我们取 n 行输入。每行仅包含一个字符,可以是 <>- 或小写英文字母之一。对于 ><,我们将光标向右或向左移动。对于 -,我们删除光标位置的字符。对于字母表,我们将它们添加到双向链表中。最后我们将结果打印在一行中,没有空格。我已经创建了doubyLinkedList 类和所需的方法。我认为它工作正常,但代码的时间复杂度必须是 O(n)。我想现在是 O(n^2)

import java.util.*;
public class DoublyLinkedList {
static Node head = null;
static int size = 0;
class Node {
    String data;
    Node prev;
    Node next;
    Node(String d) {
        data = d;
    }
}
static Node deleteNode(Node del) {
    if (head == null || del == null)
        return null;
    if (head == del)
        head = del.next;
    if (del.next != null)
        del.next.prev = del.prev;
    if (del.prev != null)
        del.prev.next = del.next;
    del = null;
    size --;
    return head;
}
public String GetNth(int index) {
    Node current = head;
    int count = 0;
    while (current != null)
    { if (count == index)
        return current.data;
        count++;
        current = current.next;
    }
    assert (false);
    return null;
}
public static void deleteNodeAtGivenPos(int n) {
    size--;
    if (head == null || n <= 0)
        return;
    Node current = head;
    int i;
    for (i = 1; current != null && i < n; i++)
        current = current.next;
    if (current == null)
        return;
    deleteNode(current);
}
void insertFirst (String data){
    size++;
    Node newNode = new Node(data);
    if (head == null) {
        newNode.prev = null;
        head = newNode;
        return;
    }
    else
        head.prev= newNode;
    newNode.next=head;
    head = newNode;
}
void append(String data) {
    size++;
    Node newNode = new Node(data);
    Node last = head;
    newNode.next = null;
    if (head == null) {
        newNode.prev = null;
        head = newNode;
        return;
    }
    while (last.next != null)
        last = last.next;
    last.next = newNode;
    newNode.prev = last;
}
public void insertAtGivenPos(String s,int index){
    Node newNode= new Node(s);
    Node current= head;
    if (index==0)
        insertFirst(s);
    else if(index==size)
        append(s);
    else{
        for(int j = 0; j < index && current.next != null; j++){
            current = current.next;
        }
        newNode.next = current;
        current.prev.next = newNode;
        newNode.prev = current.prev;
        current.prev = newNode;
        size++;
    }
}
public void print(Node node) {
    while (node != null) {
        System.out.print(node.data + "");
        node = node.next;
    }
}
public static void main(String[] args) {
    Scanner sc = new Scanner(system.in);
    int n = Integer.parseInt(sc.nextLine());
    String [] arr= new String[n];
    for (int i=0; i< n; i++)
        arr[i] = sc.nextLine();
    DoublyLinkedList dll = new DoublyLinkedList();
    int cursor= 0;
    for (int i=0; i< n; i++){
        if (arr[i].matches("[a-z]")){
            dll.insertAtGivenPos(arr[i],cursor);
            cursor++;
        }
        else if (arr[i].contains("-")&& dll.GetNth(cursor-1)!= null) {
            dll.deleteNodeAtGivenPos(cursor);
            cursor--;
        }
        else if (arr[i].contains("<") && dll.GetNth(cursor-1)!= null)
            cursor--;
        else if (arr[i].contains(">") && dll.GetNth(cursor+1)!= null)
            cursor++;
    }
    dll.print(dll.head);
}
}

如何改进代码以降低时间复杂度?

编辑:我也明白我的代码在某些情况下给出了错误的答案。你能帮我调试一下吗?

解决方法

如果你不是被迫遵循实现细节,我建议不要有游标。相反,保留一个变量 currentNode,它是 cursor 将指向的节点。因此,对于输入循环中的每个命令(或数据),您都有一个 O(1) 操作,如下所示,因此将获得 O(n) 时间复杂度。

1 - 对于 > :将 currentNode 更改为 currentNode.next

2 - < 做相反的事情

3 - 对于 -currentNode 的上一个和下一个节点更改为 点的情况下(因此当前被删除)

4 - 最后用于插入:创建一个节点并像 3 一样,更改 指向它的侧节点

,

您不需要内部 for 循环。接受后立即处理输入。

for (int i=0; i< n; i++)
    arr[i] = sc.nextLine();
    DoublyLinkedList dll = new DoublyLinkedList();
    int cursor= 0;
    if (arr[i].matches("[a-z]")){
        dll.insertAtGivenPos(arr[i],cursor);
        cursor++;
    }
    else if (arr[i].contains("-")&& dll.GetNth(cursor-1)!= null) {
        dll.deleteNodeAtGivenPos(cursor);
        cursor--;
    }
    else if (arr[i].contains("<") && dll.GetNth(cursor-1)!= null)
        cursor--;
    else if (arr[i].contains(">") && dll.GetNth(cursor+1)!= null)
        cursor++;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。