按值排序链表 -

时间:2016-04-01 19:14:52

标签: c linked-list

请耐心等待我,我是stackoverflow的新手,所以让我试着解释一下我的问题,如果在我的问题中有任何可以改进的地方,请务必发表评论并且我&# 39;编辑问题

好的,所以我自己有一个链接列表,我想通过列表中的值来订购,这恰好是价格:

tmpPtr->item->price;

我所遇到的问题是切换位置,这里是代码:

struct inventory *sort_list() {
        struct inventory *tmpPtr = pFirstNode;
        struct inventory *temp = NULL;
        struct inventory *tmpNxt = pFirstNode->next;
        int tmp;
        while(tmpNxt != NULL){
               while(tmpNxt != tmpPtr){
                        if(tmpNxt->item->price < tmpPtr->item->price){
                                // if next item price is smaller than current
                                // temp for the next item
                                // heres the problem....
                                temp = tmpNxt->next;
                                tmpNxt->next = tmpPtr;
                                tmpPtr->next = temp;
                        }
                        else{
                            // if not any smaller continue    
                            tmpPtr = tmpPtr->next;

                        }
                }
                tmpPtr = pFirstNode;
                tmpNxt = tmpNxt->next;
        }
        return tmpPtr; 
    }

这些值不是我从逻辑中预期的排序,任何指针都会很棒 编辑:

struct inventory *sort_list() {
        struct inventory *tmpPtr = pFirstNode;
        struct inventory *temp = NULL;
        struct inventory *tmpNxt = pFirstNode->next;
        while(tmpNxt != NULL){
               while(tmpNxt != tmpPtr){
                        if(tmpNxt->item->price < tmpPtr->item->price){
                                // if next item price is smaller than current
                                // temp for the next item
                                if(tmpPtr == pFirstNode){
                                    tmpPtr = pFirstNode->next; // tmpPtr is now second node
                                    pFirstNode->next = tmpPtr->next;
                                    tmpPtr->next = pFirstNode;
                                    pFirstNode = tmpPtr;
                                }

                                tmpNxt = tmpPtr->next;
                                tmpPtr->next = tmpNxt->next;
                                tmpNxt->next = tmpPtr;
                                temp->next = tmpNxt;
                        }

                }
                  temp = tmpPtr;
        }
        return tmpPtr; // Place holder
    }

2 个答案:

答案 0 :(得分:1)

当你处于内部if状态时,你有以下状态:

Node1 -> tmpPtr -> tmpNxt -> Node2

您想要达到的目标是:

Node1 -> tmpNxt -> tmpPtr -> Node2

然后你有以下代码:

  1. temp = tmpNxt->next; //制作temp = Node2
  2. tmpNxt->next = tmpPtr; //将列表更改为Node1 -> tmpPtr <-> tmpNxt
  3. tmpPtr->next = temp; //将列表更改为Node1 ->tmpPtrtmpNxt -> tmpPtr -> Node2
  4. 正如您所看到的,您错过了Node1 -> tmpNext的链接。你可以这样做并检查你的结果。

答案 1 :(得分:1)

要交换两个相邻的单链表成员,你需要三个相邻的成员(你要交换的两个成员后面的成员),除非其中一个是列表的头部。

  1. 列表案例的负责人→交换list_headlist_head->next

    assert(list_head->next);
    next = list_head->next;
    list_head->next = next->next;
    next->next = list_head;
    list_head = next;
    
  2. 其他情况→交换curcur->next

    assert(prev->next == cur && cur->next);
    next = cur->next;
    cur->next = next->next;
    next->next = cur;
    prev->next = next;
    
  3. 但是,如果将前一个节点重新定义为上一个节点的下一个成员的地址,则可以将这两种情况折叠为单个案例。

    void swap_cur_with_next (node **pnext, node *cur) {
        assert(*pnext == cur && cur->next);
        node *next = cur->next;
        cur->next = next->next;
        next->next = cur;
        *pnext = next;
    }
    
    /* swap list_head with list_head->next */
    swap_cur_with_next(&list_head, list_head);
    
    /* swap cur with cur->next */
    swap_cur_with_next(&prev->next, cur);
    

    使用正确的交换例程,可以更轻松地在列表中实现冒泡排序算法。代码结构可能如下所示:

    void bubble_up(node **pnext, node *cur) {
        while (cur->next) {
            if (need_to_swap(cur)) {
                swap_cur_with_next(pnext, cur);
            }
            pnext = &(*pnext)->next;
            cur = *pnext;
        }
    }
    
    node **pnext = &list_head;
    while (*pnext) {
        bubble_up(pnext, *pnext);
        pnext = &(*pnext)->next;
    }
    

    但是,正如另一个答案所述,合并排序是一种更自然,更有效的算法,可用于对列表进行排序。

    至少,您可以将节点指针打包到一个数组中,并使用qsort()对节点指针进行排序,然后按排序顺序将它们链接起来。