C++对双向链表进行冒泡排序

发布于 2024-09-23 23:59:00 字数 816 浏览 11 评论 0原文

我知道冒泡排序可能不是最快的方法,但它是可以接受的。我只是在将算法调整为数组中的双链接列表时遇到麻烦。

我的双链表有一个 int 类型和一个 string 类型来保存数字和单词。我的列表是用插入排序来排序的,我编写了该插入排序来按字母顺序排序,现在我需要按数字顺序重新排序我的双链表,从最大到最小。

我的麻烦点是如何运行这个循环,以便它得到正确彻底的排序,而不仅仅是一次。

到目前为止,这是我所取得的成果:

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

I know bubble sort is probably not the fastest way to do this but its acceptable. i'm just having trouble with adjusting the algorithm to double link lists from arrays.

My double linked lists have a type int and a type string to hold a number and a word. My list was sorted with an insertion sort that I wrote to sort alphabetically, now I need to reorder my double linked list numerically, greatest to least.

My trouble spot is how to run this loop so that it is properly sorted thoroughly and not just one time.

here's what i've managed to get down so far:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

千年*琉璃梦 2024-09-30 23:59:00

我的麻烦点是如何运行这个循环,以便它得到正确彻底的排序,而不仅仅是一次。

如果您已经有一个循环可以成功执行一次传递并且交换也可以,那么相对有效地执行多次传递的通常方法是:

set swapped = true
while swapped:
    set swapped = false
    do your one pass, setting swapped to true whenever you swap

这避免了初学者总是从简单的 n2 解决方案开始。

确实如此。

您将 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;
        }
    }
}

My trouble spot is how to run this loop so that it is properly sorted thoroughly and not just one time.

If you already have a loop that will successfully do one pass and swap is okay, the usual way to do multiple passes relatively efficiently is:

set swapped = true
while swapped:
    set swapped = false
    do your one pass, setting swapped to true whenever you swap

This avoids the naive n2 solution that beginners will invariably start with.

And that's it really.

You set swapped to true so that you initially enter the list then set it to false immediately, inside the loop.

Your single pass will set swapped only if a swap takes place. If no swap takes place in your pass, then the list is sorted and you exit the loop.

If any swap takes place, the swapped flag is set and you will need to run another pass. This is because the swap could be at the end of the list and invalidate the order earlier on, such as:

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)

So, assuming your code is correct, start with something like:

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;
        }
    }
}
内心旳酸楚 2024-09-30 23:59:00

使用 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;
            }
        }
    }
}

顺便说一句,为什么要创建一个虚拟节点来交换,而您想要的只是交换值。

Use 2 loops to sort the list thoroughly ( I am not considering the efficiency here as thats not important to you at the moment). So iterate the list with 2 pointers as you would do with arrays -

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, Why do want to create a dummy node to swap, when all you want is to swap the values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文