5

我的代码有问题,我创建了一个单链表类,您可以在其中添加、删除、修改、合并等......但是,我正在尝试一个简单的冒泡排序并且遇到了列表存在的问题未正确排序。这里有一些注意事项:

  • 它是链表的自定义实现
  • 单链表的节点包含两件事:一个包含客户所有数据的 CustomerFile 对象和一个指向列表中下一项的“下一个”节点指针
  • 该列表按每个节点的客户文件中存储的姓氏按升序 (AZ) 排序
  • 添加记录功能将节点插入到列表中的正确位置,因此列表最初不需要排序 - 但是如果更改姓氏,作为程序的一部分,列表需要再次排序
  • 我宁愿不创建一个新列表并在该列表上重新使用此插入记录来创建一个新列表,因为这是内存密集型的,我的任务是尽可能高效
  • 链表的结构不能改变 - 已经决定了,我太远了,无法更改为数组之类的东西
  • 该列表有一个头节点,它有下一个项目但没有尾节点。它有一个指定的 NULL next 指针来指示列表的结尾

编码

public static void sortList()
{
    if (isEmpty() == true)
    {
        System.out.println("Cannot sort - the list is empty");
    }
    else if (getHead().getNext() == null)
    {
        System.out.println("List sorted");
    }
    else
    {
        Node current = getHead().getNext();
        CustomerFile tempDat;
        boolean swapDone = true;
        while (swapDone)
        {
            current = getHead().getNext();
            swapDone = false;
            while (current != null)
            {
                if (current.getNext() != null &&
                    current.getData().getSurname().compareTo(
                        current.getNext().getData().getSurname()) >0)
                {
                    tempDat = current.getData();
                    current.setData(current.getNext().getData());
                    current.getNext().setData(tempDat);
                    swapDone = true;
                }
                current = current.getNext();
            }
        }
        if (getHead().getData().getSurname().compareTo(
            getHead().getNext().getData().getSurname()) >0)
        {
            current = getHead().getNext();
            getHead().setNext(current.getNext());
            setHead(current);
        }
    }
}

我会很感激反馈

4

3 回答 3

4

您的代码是一种奇怪的混合物,主要是交换数据,但特别对待头部,试图通过切换链接与下一个交换它。

如另一个答案所述,最后一次交换没有正确实现,但是如果您通过交换数据来做事,实际上没有理由特别对待头部。

您所要做的就是在外循环的头部开始对列表的每次遍历。

这产生了一个可行的解决方案:

public void sortList()
{
    if (isEmpty())
    {
        System.out.println("An empty list is already sorted");
    }
    else if (getHead().getNext() == null)
    {
        System.out.println("A one-element list is already sorted");
    }
    else
    {
        Node current = getHead();
        boolean swapDone = true;
        while (swapDone)
        {
            swapDone = false;
            while (current != null)
            {
                if (current.getNext() != null && current.getData().getSurname().compareTo(current.getNext().getData().getSurname()) >0)
                {
                    CustomerFile tempDat = current.getData();
                    current.setData(current.getNext().getData());
                    current.getNext().setData(tempDat);
                    swapDone = true;
                }
                current = current.getNext();
            }
            current = getHead();
        }
    }
}

我把这个做成了非静态的,因为正如评论中所指出的,我不清楚你的静态文件是如何工作的。您可以在您的上下文中将其设为静态。

我还更改了其他一些小事情。从来没有必要通过代码检查条件

if (isEmpty() == true)

在 Java 中,这完全等价于

if (isEmpty())

并且tempDat不需要在使用它的地方之外声明。

于 2012-12-22T15:33:56.453 回答
1

您没有在排序中包括头部。

public static void sortList()
{
    if (isEmpty() == true)
    {
        System.out.println("Cannot sort - the list is empty");
    }
    else if (getHead().getNext() == null)
    {
        System.out.println("List sorted");
    }
    else
    {
        Node current = getHead();
        // Node current = getHead().getNext();
        CustomerFile tempDat;
        boolean swapDone = true;
        while (swapDone)
        {
            current = getHead().getNext();
            swapDone = false;
            while (current != null)
            {
                if (current.getNext() != null && current.getData().getSurname().compareTo(current.getNext().getData().getSurname()) >0)
                {
                    tempDat = current.getData(); // td -> objectA, cd -> objectA
                    current.setData(current.getNext().getData()); // cd -> objectB
                    current.getNext().setData(tempDat); // nd -> td -> objectA
                    swapDone = true;
                }
                current = current.getNext();
            }
        }
        //if (getHead().getData().getSurname().compareTo(getHead().getNext().getData().getSurname()) >0)
        //{
        //  current = getHead().getNext(); // current -> head+1
        //  getHead().setNext(current.getNext()); //head+1 -> head+2
        //  setHead(current); // head -> head+1
        //}
    }
}

上面注释掉的代码也有错误。应用该代码会删除一个节点。

// list: a -> b -> c -> d
current = getHead().getNext(); // current = b
getHead().setNext(current.getNext()); // a -> c 
setHead(current); // head = b
// list: b -> c -> d
// and nothing points to 'a' anymore

而不是交换数据,您应该尝试交换节点。如果您采用这种方法,您应该找到更好的解决方案。

于 2012-12-21T22:48:11.523 回答
1

我认为这里的主要问题是你从

current = getHead().getNext()

使用此代码,您将完全将头部排除在排序过程之外,并且可能此处的数据需要转到列表的另一端,但在这种情况下,它将始终是头部中的数据元素,或者是直接在头节点之后的数据(后者是由于你最后的 if 语句)。

尝试从列表的开头开始,看看会带来什么。

于 2012-12-21T23:30:23.363 回答