在java中使用单链表和冒泡排序进行编码

时间:2012-12-21 21:44:04

标签: java bubble-sort singly-linked-list

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

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

代码

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);
        }
    }
}

我很感激反馈

3 个答案:

答案 0 :(得分: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不需要在使用它之外声明。

答案 1 :(得分: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

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

答案 2 :(得分:1)

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

开始
current = getHead().getNext()

使用此代码,您将完全退出排序过程,可能是这里的数据需要转到列表的另一端,但在这种情况下,它将始终是数据在head元素中,或者是头节点之后的数据(后者是由于你的if语句结尾)。

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