双链表上的冒泡排序

时间:2011-11-22 16:19:22

标签: java data-structures

public Node get(int i) {  
    if (!isEmpty()) {  
        int j = 0;  
        Node element = head;  
        while (j++ < i) {  
            element = element.getNext();  
            if (element == null)  
                return null;  
        }  
        return element;  
    }  
    return null;  
}  



private void bubbleSort() {  
    for (int i = 0; i < size - 1; i++) {  
        boolean changed = false;  
        for (int j = 0; j < size - i - 1; j++) {  
            if (get(j + 1) != null) {  
                if (get(j).getValue() > get(j + 1).getValue()) {  
                    //System.out.println("Swapping: " + get(j).getValue() + " : " + get(j + 1).getValue());  
                    swap(get(j), get(j + 1));  
                    changed = true;  
                }  
            }  
        }  
        if (!changed)  
            return;  
    }  
}  

public void swap(Node first, Node mid) {  
    if (first == head)  
        head = mid;  
    if (mid == tail) {  
        tail = first;  
    }  
    first.setNext(mid.getNext());  
    mid.setPrev(first.getPrev());  
    first.setPrev(mid);  
    mid.setNext(first);  
}

我不知道遗失了什么...

列表,值:
6
2
4
5
7

排序后:
2
6
7

熟悉的输出:
交换:6&lt; 6&gt; 2
交换:6&lt; 6&gt; 4
交换:6&lt; 6&gt; 5个

拜托,有些人在帮助我,我不知道排序双重链表......

public void swap(Node first, Node mid) {  
    if (first == head)  
        head = mid;  
    if (mid == tail) {  
        tail = first;  
    }  
    first.setNext(mid.getNext());  
    mid.setPrev(first.getPrev());  
    first.setPrev(mid);  
    mid.setNext(first);  
}

请参阅以下代码:swap function。

1 个答案:

答案 0 :(得分:2)

由于这似乎是一个家庭作业问题,我不会给你完整的答案。我相当肯定问题在于你的交换功能。考虑在纸上绘制节点并浏览交换函数,看看哪些节点指向哪里。考虑您正在交换的节点的上一个和下一个节点,以及您还必须更新它们的上一个/下一个节点!当然,除非你的setNext和setPrev函数已经这样做了。

如果您需要其他帮助,请随时发表评论。

编辑1:

另外,作为旁注,不要使用索引(i和j)来跟踪您正在使用的节点,请考虑仅使用节点本身。然后当你调用i ++或j ++时,请调用node = node.getNext()。这样您就不会在运行时添加额外的n因子,并且可以完全取消交换功能。

编辑2:

我的意思是将它绘制在纸上,将每个值按顺序写在纸上。然后围绕每一个绘制一个圆圈,并在每种情况下指向下一个圆圈和前一个圆圈的箭头。用铅笔画箭头!然后在逐步执行交换功能时相应地更新箭头。您甚至不必移动/擦除圆圈,只需擦除箭头并查看它们下一步指向的位置。

编辑3:

好的,所以你有两个想要交换的圈子。这些圆圈都有向外箭头,它们的邻居都有箭头向内。这是每圈4个箭头(2英寸,2英寸,除非你正在处理头部/尾部)。由于你移动2个圆圈,这意味着你必须改变总共8个箭头(除非处理头部/尾部) - 每个圆圈4个。您可能只是每setPrev / setNext更改一个箭头。这意味着这些通常在你的交换函数中被调用8次。你只打电话给他们4次。

编辑4:

您正在更新交换节点的上一个/下一个节点,但不更新其邻居节点。您将要执行类似first.getNext()。setPrev(second)等操作来更新邻居的引用/ prev / next /箭头。

编辑5:

请记住空检查(你不能在null上调用setPrev或setNext,所以请确保当你设置邻居的prev / next时,邻居实际存在(因为head不存在head和next doesn)不存在尾巴))。

编辑6:

如果你你没有做作业......;)

void swap(Node first, Node second) {
    Node firstPrev = first.getPrev();
    Node firstNext = first.getNext();
    Node secondPrev = second.getPrev();
    Node secondNext = second.getNext();

    if (firstPrev) {
        firstPrev.setNext(second);
    }
    if (firstNext) {
        firstNext.setPrev(second);
    }
    if (secondPrev) {
        secondPrev.setNext(first);
    }
    if (secondNext) {
        secondNext.setPrev(first);
    }

    second.setPrev(firstPrev);
    second.setNext(firstNext);
    first.setPrev(secondPrev);
    first.setNext(secondNext);
}