冒泡在C#中的通用列表中排序

时间:2011-03-18 16:45:58

标签: c# generic-list bubble-sort

我正在使用C#中的通用列表,但是当我尝试使用冒泡排序方法对节点进行排序时,我遇到了问题。

namespace ConsoleApplication1
{    

public class GenericList
{
    private class Node
    {
        // Each node has a reference to the next node in the list.
        public Node Next;           
        public int Data;
    }

    // The list is initially empty.
    private Node head = null;

    // Add a node at the beginning of the list with t as its data value.
    public void AddNode(int t)
    {
        Node newNode = new Node();
        newNode.Next = head;
        newNode.Data = t;
        head = newNode;
    }


//list length
        public int Size()
        {
            int listsize= 0;
            Node current = head;
            while (current != null)
            {
                listsize++;
                current = current.Next;
            }
            return listsize;            
        }

        //bubble sort
        public void bubblesort()
        {
            int size = Size();

            Node current = head;

            for (int i = 1; i < size; i++)
            {
                for (int j = 0; j < size - 1; j++)
                {


                    if (current.Data > current.Next.Data && current.Next!=null)
                    {
                        int temp = current.Data;
                        current.Data = current.Next.Data;
                        current.Next.Data = temp;
                    }

                }
            }

            head = current;
        }
     }
}

当我向列表中添加5个以上的节点时,bubblesort方法停止工作(没有正确排序列表)。 谁能帮忙吗?

4 个答案:

答案 0 :(得分:2)

你需要澄清“停止工作”的意思......失败了吗?核心转储?没有正确排序列表?

问题是您需要在current的每次迭代(head+1迭代之前)将i重置回j

如果您希望向上移动最大值,则j应该从1升级到size-i(因为首次通过后,最大数字将位于顶部 - 不需要再次检查)。或者,将最小值从j向下size-1向下i

嵌套循环方法的替代方法:您可以使用while / boolean / loop方法(在while之外,boolean指示是否进行了更改,for loop internal)。当数据已经有点整齐时,这会有一些性能上的好处 - 它会在嵌套for方法之前停止处理(即使数据已经排序,它也会运行最大次数)。

答案 1 :(得分:1)

来吧,伙计们......让他有些松懈......这是谷歌一代。

btw ..

http://www.google.co.uk/search?q=C%23+bubble+sort

..会给你一些很好的例子。

现在您的代码出现了什么问题:

此代码(来自上方)

    Node current = head;

    for (int i = 1; i < size; i++)
    {
        for (int j = 0; j < size - 1; j++)
        {


            if (current.Data > current.Next.Data && current.Next!=null)
            {
                int temp = current.Data;
                current.Data = current.Next.Data;
                current.Next.Data = temp;
            }

        }
    }

与说:

完全相同
    Node current = head;
            if (current.Data > current.Next.Data && current.Next!=null)
            {
                int temp = current.Data;
                current.Data = current.Next.Data;
                current.Next.Data = temp;
            }

您不会更改“当前”节点,即您始终在列表中排序第一项和第二项。

我不会给你完整的解决方案,这就是家庭作业的用途。在循环中确保当你的列表开始是内部循环时,你的当前总是列表中的第j个项目,你将获得正确的结果。

此外,您的交换位略有不正确,您应该交换节点而不仅仅是数据。即节点的Next字段以及当前节点需要更新的点。这应该会让你获得更多的布朗尼点,而不仅仅是交换数据。

还有一些调试提示:添加一个Print()函数,如下所示:

public void Print()
    {
        Node current = head;
        Console.Write("List: ");
        while (current != null)
        {
            Console.Write("{0} ", current.Data);
            current = current.Next;
        }
        Console.WriteLine("");
    }

并在排序循环中调用它,它将帮助您了解列表在每次迭代之间的变化情况。这有助于您了解问题的位置。

List: 3 1 50 2 5 4
List: 3 1 50 2 5 4
List: 1 3 50 2 5 4
List: 1 3 50 2 5 4
List: 1 3 2 50 5 4
List: 1 3 2 5 50 4
List: 1 3 2 5 4 50
List: 1 2 3 5 4 50
List: 1 2 3 5 4 50
List: 1 2 3 4 5 50

哦!男人..每次我读代码我发现一些新的错误! ......

        if (current.Data > current.Next.Data && current.Next!=null)

应该是

        if (current != null && current.Next!=null && current.Data > current.Next.Data)

您的代码不会崩溃,因为它目前没有做任何事情。

希望这有帮助。

答案 2 :(得分:0)

您有两个嵌套循环声明ij变量,但您从不在循环中使用它们。这显然是错误的。

for (int i = 1; i < size; i++)
{
    for (int j = 0; j < size - 1; j++)
    {

你应该做的是使用while循环遍历列表,就像你在Size方法中一样,如果它们是向后的,则交换相邻的元素。您将跟踪bool是否实际执行了任何交换,如果是,则再次遍历列表。这将重复,直到您没有执行任何交换。

这假设您确实需要实施冒泡排序以满足您的分配要求。否则,没有理由比框架中的内置集合类型和排序方法更喜欢它。

答案 3 :(得分:0)

另一个带有2个属性的简单类的例子。这不是数组,而是模拟指针的简单类......只是为了好玩!

class MyLinkedList
{
    MyLinkedList nextNode;
    int data;

    public void OrderListBubbleAlgoritm(ref MyLinkedList head)
    {
        bool needRestart = true;
        MyLinkedList actualNode = head; //node Im working with        
        int temp;

        while (needRestart)
        {
            needRestart = false;
            actualNode = head;
            while (!needRestart && actualNode.nextNode != null)
            {
                if (actualNode.nextNode.data >= actualNode.data) //is sorted
                {
                    actualNode = actualNode.nextNode;
                }
                else
                {
                    //swap the data
                    temp = actualNode.data;
                    actualNode.data = actualNode.nextNode.data;
                    actualNode.nextNode.data = temp;

                    needRestart = true;
                }
            }
        }
    }
 }

请记住仅使用少量数据进行气泡排序。
它的表现是:O(n ^ 2)