简体   繁体   English

Java双向链接列表指针指向以前的节点

[英]Java doubly linked list pointers to previous nodes

I'm making a method to add a Node into a list called "public void add(int index, T value)". 我正在制作一种将Node添加到名为“ public void add(int index,T value)”的列表中的方法。

This method will put a value into an index, and then will have pointers to the next and previous elements in the list. 此方法将一个值放入索引,然后将具有指向列表中下一个和上一个元素的指针。 I have messed up on the pointers to the previous nodes, which I have been sitting and experimenting but don't get to make it work. 我搞砸了以前的节点的指针,这些节点我一直在尝试并尝试,但是没有使它工作。

Example: We have a list with Integer values [2, 4, 6] Instance variables: Node head, tail; 示例:我们有一个包含整数值[2、4、6]的列表。 int amount, changes; 整数数量,变化;

Instance variables for the inner class are: T value; 内部类的实例变量是:T值; Node prev, next; 节点上一个,下一个;

Input: 输入:

add(1, 3);
System.out.println(list.toString());
System.out.println(list.backwardsString());

Expected output: 预期产量:

[2, 3, 4, 6]
[6, 4, 3, 2]

My code so far: 到目前为止,我的代码:

public void add(int index, T value) {
if (index < 0 || index > amount) {
        throw new IndexOutOfBoundsException("Index is not between 0 and amount!");
    }

    if (value== null) {
        throw new NullPointerException("Value can't be null!");
    }

    if (amount == 0) {
        head = tail= new Node<>(value, null, null);
    }
    else if (index == 0) {
        head = head.prev= new Node<>(value, null, head);
    }
    else if (index == amount) {
        tail = tail.next= new Node<>(value, tail, null);
    } 
    else {
        Node<T> p = head;  
        for (int i = 1; i < index; i++) {
            p = p.next;
        }
        p.next= new Node<>(value, p, p.next);


        p = tail;
        for (int i = amount; i > index; i--) {
            p.prev= new Node<>(value, p.prev, p);
            p = p.prev;
        }*/
    }

    amount++;
    changes++;
}

In this occasion I would also ask how does 在这种情况下,我还要问

p.prev.next or p.next.prev p.prev.next或p.next.prev

work? 工作?

You may heavily simplify your design by introducing an empty pseudo node into your List class. 通过将空的伪节点引入List类,可以大大简化您的设计。

Since this node always exists you don't need a special case like: 由于此节点始终存在,因此不需要像下面这样的特殊情况:

if (amount == 0) {
    head = tail= new Node<>(value, null, null);
}
else if (index == 0) {
    head = head.prev= new Node<>(value, null, head);
}

The first node pseudo can be initialized with 可以使用以下内容初始化第一个伪节点

pseudo.next = pseudo;
pseudo.prev = pseudo;

The List is empty if 如果列表为空

pseudo.next == pseudo.prev

The real List start will be pseudo.next and the last list entry will be pseudo.prev. 真正的列表开始将是pseudo.next,最后一个列表条目将是pseudo.prev。 So your List will be actually a ring. 因此,您的列表实际上将是一个铃声。

Your search loop will become 您的搜索循环将变为

   Node<T> p = pseudo.next;  
   for (int i = 0; i < index && p!=pseudo; i++) {
        p = p.next;
   }

However here: 但是在这里:

   p.next= new Node<>(value, p, p.next);

You have to manipulate p.next.prev which also points (or better refers) to an illegal Node<> now. 您必须操纵p.next.prev ,它现在也指向(或更好地引用)非法的Node <>。

But I leave that as a homework -- which this clearly seems to be ;-) 但是我把它留作家庭作业-这显然是;-)

EDIT: 编辑:

Full List implementation demonstrating the sentinel Node 完整列表实现,展示了前哨节点

public class List { 公共课程列表{

public class  Node {
    T value = null;
    Node(T v) {
        value=v;
    }
    Node()   {
    }
    public Node getNext() {
        return next;
    }

    public Node getPrev () {
        return prev;
    }
    public T getValue() {
        return value;
    }

    Node prev = null;
    Node next = null;
};

private Node pseudo = new Node();

List() {
    pseudo.next = pseudo.prev = pseudo;
}

public Node getBegin() {
    return pseudo.next;
}

public Node getEnd() {
    return pseudo;
}

public boolean add(int index, T value) {
    Node p = pseudo.next;

    for (int i = 0; i < index && p!=pseudo; i++) {
        p = p.next;
    }

    // Correct for tail insertion
    if(p == getEnd())
        p = p.prev;

    Node ptm = p.next;

    p.next      = new Node(value);
    p.next.next = ptm;
    p.next.prev = p;
    ptm.prev    = p.next;

    return true;
}

public void delete(int i) {

    Node p = pseudo.next;

    for (int ix = 0; ix < i && p!=pseudo; ix++) {
        p = p.next;
    }

    if(p != getEnd()) {
        Node ptm = p.prev;
        p.prev.next = p.next;
        p.next.prev = ptm;
    }       
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM