我正在使用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方法停止工作(没有正确排序列表)。 谁能帮忙吗?
答案 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)
您有两个嵌套循环声明i
和j
变量,但您从不在循环中使用它们。这显然是错误的。
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)