简体   繁体   English

交换冒泡排序双向链表的节点 C

[英]swapping nodes for a bubble sort doubly linked list C

Welp I'm back.哎呀,我回来了。 I am now trying to do a bubble sort with a node swap.我现在正在尝试使用节点交换进行冒泡排序。 There is a problem in my algorithm that i cannot determine.我的算法中有一个我无法确定的问题。 When I remove the bool condition to determine if the list is sorted, the program produces some output, indicating the loop condition is failing to a problem in the algorithm.当我删除 bool 条件以确定列表是否已排序时,程序会生成一些 output,表明循环条件失败是算法中的问题。 i have diagrammed out what happens on paper, with each pointer as it is reassigned.我已经用图表说明了纸上发生的事情,每个指针都被重新分配了。 I envisioned nodes ab c d, where b and c are swapped.我设想节点 ab c d,其中 b 和 c 交换。 the sort function is below.排序 function 如下。 i have made notes for every action in an attempt to figure what i am doing wrong.我已经为每一个动作做了笔记,试图找出我做错了什么。 no dice, any guidance would be greatly appreciated, thank you.没有骰子,任何指导将不胜感激,谢谢。

void sortList(void)
{
    struct Node *before, *after;
    struct Node * temp;

    bool sorted = false;

    while (sorted == false)
    {
        //test completion
        sorted = true;  //if this isn't changed by the below statement the list is sorted
        temp = head;    //reinitializes where there list sorts from
        while (temp->next != NULL)  //stops at the end of the list
        {
            if (temp->data > temp->next->data)
            {
                //test the value of the nodes to see if they need a sort

                before = temp->prev;    //"back" pointer for subject (b)
                after = temp->next; //"forward" pointer for subject
                if (before != NULL)
                {
                    before->next = after;   //covers swap being made at beginning
                }
                temp->next = after->next;   //points to after next
                after->next->prev = temp;   //sets prev pointer for "d"
                temp->prev = after; //points to what after pointed
                after->next = temp; //places node after next one
                after->prev = before;   //ditto

                sorted = false; //flagged, the list is not sorted
            }
            temp = temp->next;  //moves through the list

        }
    }
}

There are three main problems in the original sortList function:原来的sortList function主要存在三个问题:

  1. It doesn't update head when moving the first node in the list.移动列表中的第一个节点时,它不会更新head (Fix: add an else part to update head .) (修复:添加一个else部分来更新head 。)
  2. after->next->prev dereferences a null pointer at the end of the list. after- after->next->prev取消引用列表末尾的 null 指针。 (Fix: check after->next != NULL first.) (修复:先检查after->next != NULL 。)
  3. temp = temp->next dereferences a null pointer at the end of the list and skips a position when not at the end of the list. temp = temp->next在列表末尾取消引用 null 指针,并在不在列表末尾时跳过 position。 The code that swaps the temp node with the following node already advances temp one position through the list, so it should not be done again.temp节点与以下节点交换的代码已经通过列表将temp节点 position 推进,因此不应再次执行此操作。 (Fix: move temp = temp->next; into an else part executed only when the temp node does not need to be swapped.) (修复:将temp = temp->next;移动到仅在不需要交换temp节点时才执行的else部分。)

Here is an updated version of sortList() with the changes marked:这是sortList()的更新版本,其中标记了更改:

void sortList(void)
{
    struct Node *before, *after;
    struct Node * temp;

    bool sorted = false;

    while (sorted == false)
    {
        //test completion
        sorted = true;  //if this isn't changed by the below statement the list is sorted
        temp = head;    //reinitializes where there list sorts from
        while (temp->next != NULL)  //stops at the end of the list
        {
            if (temp->data > temp->next->data)
            {
                //test the value of the nodes to see if they need a sort

                before = temp->prev;    //"back" pointer for subject (b)
                after = temp->next; //"forward" pointer for subject
                if (before != NULL)
                {
                    // temp is not at beginning of list
                    before->next = after;
                }
                else
                {
                    // *** Fix 1 ***
                    // temp is at beginning of list
                    head = after;
                }
                temp->next = after->next;   //points to after next
                if (after->next != NULL) // *** Fix 2 ***
                {
                    after->next->prev = temp;   //sets prev pointer for "d"
                }
                temp->prev = after; //points to what after pointed
                after->next = temp; //places node after next one
                after->prev = before;   //ditto

                sorted = false; //flagged, the list is not sorted
            }
            else // *** Fix 3 ***
            {
                temp = temp->next;  //moves through the list
            }

        }
    }
}

EDIT编辑

The above version of sortList fails when head is NULL (an empty list) due to temp->next dereferencing a null pointer.由于 temp- temp->next取消引用 null 指针,当headNULL (空列表)时,上述版本的sortList失败。 One way to fix it is to mark an empty list as already sorted by changing the initialization of sorted as follows:修复它的一种方法是通过更改 sorted 的初始化将空列表标记为已sorted ,如下所示:

    bool sorted = (head == NULL);

The amount of work done by sortList can be halved (approximately) by reducing the number of iterations of the inner loop by one after for each iteration of the outer loop.通过在外循环的每次迭代之后将内循环的迭代次数减少一次, sortList完成的工作量可以(大约)减半。 This can be done as follows:这可以按如下方式完成:

  1. Add a new variable done to mark the start of the already sorted portion at the end of the list.添加一个新变量done以在列表末尾标记已排序部分的开始。 Initialize it to NULL near the top of the function (before the outer loop):将其初始化为NULL顶部附近的 NULL(在外循环之前):
    struct Node *done = NULL;
  1. Change the condition for the inner loop to terminate at the end of the unsorted portion of the list:将内部循环的条件更改为在列表的未排序部分的末尾终止:
    while (sorted == false)
    {
        //test completion
        sorted = true;  //if this isn't changed by the below statement the list is sorted
        temp = head;    //reinitializes where there list sorts from
        while (temp->next != done) // stops at the sorted portion of the list
        {
  1. When the inner loop has terminated (at the end of the outer loop), the temp node and everything beyond it is now sorted, so make done point to this node:当内部循环终止时(在外部循环结束时), temp节点和它之外的所有内容现在都已排序,因此将done指向该节点:
        }
        done = temp;    // everything from here is already sorted
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM