【问题标题】:Bubble-sorting doubly linked list冒泡排序双向链表
【发布时间】:2014-02-04 18:21:43
【问题描述】:

我的双向链表的冒泡排序功能有问题。 当我以单链接方式(仅使用 ->next)对节点进行排序时,它正在工作,但我无法使用 ->prev 指针。 这是我正在使用的代码:

void sort(int count)
{
    struct data *tmp,*current,*nextone;
    int i,j;
    for(i=0;i<count;i++)
    {
        current = first;
        for(j=0;j<count-1-i;j++ )
        {
            if(current->number > current->next->number)
            {
                nextone = current->next;
                current->next = nextone->next;
                nextone->next = current;
                if(current == first)
                {
                    first = nextone;
                    current = nextone;
                }
                else
                {
                    current = nextone;
                    tmp->next = nextone;
                }
            }
            tmp = current;
            current = current->next;
        }
    }
}

这是我正在使用的结构(列表的第一个和最后一个元素的全局变量):

struct data    
{
    int id;
    char name[20];
    int number;
    struct data *next;
    struct data *prev;
};

struct data *first = NULL;
struct data *last = NULL;

【问题讨论】:

  • 贴出在使用双链表节点移动时给您带来麻烦的代码。

标签: c list sorting bubble-sort doubly-linked-list


【解决方案1】:

以下逻辑可行。

我会遵循类似的算法...如果您想移动整个节点...

struct data *before, *after;
if(current->number > current->next->number)
{
    before = current->prev;
    after = current->next;
    if(before != NULL){
        before->next = after;
    }
    current->next = after->next;
    current->prev = after;
    after->next = current;
    after->previous = before;
}

或者,如果目的是对数据进行排序,您可以简单地交换节点中的数字而无需移动整个节点。您可以扩展以下逻辑以包括交换 char 数组和 id。

if(current->number > current->next->number)
{
    int tempNum = current->number;
    current->number = current->next->number;
    current->next->number = tempNum;
}

【讨论】:

  • 运行良好,但由于某种原因,最后一个节点在排序中丢失了。当我添加新节点时,它会替换最后一个节点,当我阅读它时,最后一个节点根本不会显示。
【解决方案2】:

一种更简单的方法是复制节点的数据,你可以交换数据但指向节点的指针。

if(current->number > current->next->number){
   swap(current->id,current->next->id);
   swap(current->name,current->next->name);
    swap(current->number,current->next->number);
}

使用您的方法,您根本不会设置前一个指针。可以先将双链表排序为单链表,然后再遍历链表设置所有的prev指针。

当然,你可以一次对双链表进行排序,但是实现起来有点复杂。您应该每一步考虑 4 个节点,即 current、current->next,以及 current->prev 和 current->next->next。当你想交换当前和当前->下一个时, 你应该设置current-&gt;prev-&gt;next=current-&gt;next, current-&gt;next=current-&gt;next-&gt;next等等。

【讨论】:

  • 虽然如此,但我确实认为这是一个糟糕的答案。链表的重点之一是避免移动大量数据。对于链表,真的没有理由这样做。
【解决方案3】:

你只需要坐下来想一想。

先分配?那么前一个必须为空。

最后分配? Next 必须为 null。

您需要对要交换的上一个和下一个元素做一些交换舞。

一种更简单的方法(对于更大的数组大小也会很快变得更快)是分配一个指针数组,用指向元素的指针填充这些指针,对数组进行 qsort 然后再做一遍以重新连接指针(和删除临时数组)。

【讨论】:

    猜你喜欢
    • 2022-01-09
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    相关资源
    最近更新 更多