我知道冒泡排序可能不是最快的方法,但它可以接受。我只是在调整算法以从数组中加倍链接列表时遇到了麻烦。
我的双链表有一个int类型和一个用于保存数字和单词的字符串。我的列表是按照我按字母顺序排序的插入排序排序的,现在我需要以数字方式重新排序我的双链表,最大到最小。
我的麻烦在于如何运行这个循环,以便彻底正确排序,而不仅仅是一次。
这是我到目前为止所做的事情:
void DblLinkedList::ReorderListNumeric()
{
dummy = new Node();
temphead = head;
temp = head->next;
while(tempTwo->next != NULL)
{
if(temp->wordCount < tempTwo->wordCount)
{
dummy->word = tempTwo->word;
dummy->wordCount = tempTwo->wordCount;
tempTwo->word = temp->word;
tempTwo->wordCount = temp->wordCount;
temp->word = dummy->word;
temp->wordCount = dummy->wordCount;
}
temp = tempTwo;
tempTwo = tempTwo->next;
}
}
答案 0 :(得分:6)
我的麻烦在于如何运行这个循环,以便彻底排序,而不仅仅是一次。
如果你已经有一个成功完成一次传递并且交换正常的循环,那么相对有效地进行多次传递的通常方法是:
set swapped = true
while swapped:
set swapped = false
do your one pass, setting swapped to true whenever you swap
这避免了天真的n 2 解决方案,初学者总是会开始。
这就是它。
您将swapped
设置为true
,以便您最初输入列表,然后立即在循环内将其设置为false
。
只有在进行交换时,您的单次传递才会设置swapped
。如果您的传递中没有发生交换,则列表将被排序并退出循环。
如果发生任何交换,则设置swapped
标志,您需要再次运行。这是因为交换可能位于列表的末尾,并使之前的订单无效,例如:
Initial: 1 2 3 4 6 7 5
Pass1: 1 2 3 4 6 5<=>7 (swap)
Pass2: 1 2 3 4 5<=>6 7 (swap)
Pass3: 1 2 3 4 5 6 7 (no swap, so exit loop)
因此,假设您的代码是正确的,请从以下内容开始:
void DblLinkedList::ReorderListNumeric() {
Node *ptr, *dummy = new Node();
// Zero or one element, no sort required.
if (head == NULL) return;
if (head->next == NULL) return;
// Force initial entry.
int swapped = 1;
while (swapped) {
// Flag as last time, then do one pass.
swapped = 0;
ptr = head;
while (ptr->next != NULL) {
if (ptr->wordCount < ptr->next->wordCount) {
// Swapping, need another pass.
swapped = 1;
dummy->word = ptr->word;
ptr->word = ptr->next->word;
ptr->next->word = dummy->word;
dummy->wordCount = ptr->wordCount;
ptr->wordCount = ptr->next->wordCount;
ptr->next->wordCount = dummy->wordCount;
}
ptr = ptr->next;
}
}
}
答案 1 :(得分:1)
使用2个循环彻底对列表进行排序(我不考虑此处的效率,因为这对您来说并不重要)。因此,使用2个指针迭代列表,就像使用数组一样 -
void DblLinkedList::ReorderListNumeric()
{
NODE* temphead = NULL; // assuming your list is made of NODEs
NODE* temp = NULL;
for(temphead = head; temphead && temphead->next != NULL; ++ temphead)
{
for(temp = temphead->next; temp && temp->next != NULL; ++temp)
{
if(temphead->wordCount < temp->wordCount)
{
std::string dummyWord = temp->word;
int dummyCount = temp->wordCount;
temp->word = temphead->word;
temp->wordCount = temphead->wordCount;
temphead->word = dummyWord;
temphead->wordCount = dummyCount;
}
}
}
}
BTW,为什么要创建一个虚拟节点来交换,当你想要的只是交换值。