冒泡排序双链表

Posted

技术标签:

【中文标题】冒泡排序双链表【英文标题】:Bubble sort double linked list 【发布时间】:2015-06-03 09:15:08 【问题描述】:

大家好,我正在尝试使用冒泡排序算法在 C 中对我的双链表进行排序。这是我的代码:

struct node 
                unsigned char key;
                unsigned char num;
                struct node *left;
                struct node *right;
            ;

这是我的排序函数:

void sort(int count, struct node *t_node)

    struct node *tmp,*nextnode, *node1, *node2;

    for(node1 = t_node;node1->right != NULL ;node1 = node1->right) 
        for(node2 = node1->right; node2->right != NULL; node2 = node2->right) 
            if(node2->key > node2->right->key)
                           
                nextnode = node2->right;
                tmp = node2->left;
                node2->right = nextnode->right;             
                node2->left = nextnode->left;
                nextnode->right = node2;
                nextnode->left = tmp;
            
        
    


它工作在 80%,因为例如数据:

node1 key=3
node2 key=144
node3 key=49
node4 key=207

排序后的结果是:

node1 key=3
node2 key=144
node4 key=207

为什么我的第三个节点消失了?问题出在哪里?

【问题讨论】:

tmp->rightnextnode->right->left 怎么样? 应该如何分配? 考虑将交换抽象为一个单独的函数。确保边缘情况(交换到和远离列表的开头或结尾)工作。 考虑分配一个临时数组,从那里复制列表中的值,使用简单的qsort() 对数组进行排序,然后复制回列表中。不需要更改列表,这通常更简单,更容易正确。当然,它确实需要更高的(临时)内存使用量。 @unwind 我认为 OP 已将其作为对双链表进行操作的练习,即使您是正确的,我也不认为 OP 的代码是为了“真正使用”而设计的跨度> 【参考方案1】:

这是一个双向链表。要交换两个节点,通常需要更新 6 个指针。假设我们有A <-> B <-> C <-> D,而您想要交换BC:您需要更新ABCright,以及Bleft @、CD

您的代码仅在此处更新 4 个指针:

        if(node2->key > node2->right->key)
                       
            nextnode = node2->right;
            tmp = node2->left;
            node2->right = nextnode->right;             
            node2->left = nextnode->left;
            nextnode->right = node2;
            nextnode->left = tmp;
        

这将解决您的问题:

        if(node2->key > node2->right->key)
                       
            nextnode = node2->right;
            tmp = node2->left;
            if (tmp)
                tmp->right = nextnode;
            if (nextnode->right)
                nextnode->right->left = node2;
            node2->right = nextnode->right;             
            node2->left = nextnode->left;
            nextnode->right = node2;
            nextnode->left = tmp;
        

【讨论】:

对示例数据进行排序时出现问题: 排序前:Node value: 199 Node value: 100 Node value: 12 Node value: 101 排序后我得到:Node value: 199 Node value: 12 Node value: 101 错误在哪里?【参考方案2】:

您还需要替换前一个节点(代码中的tmp,但我建议使用更明确的名称...)right 指针和下一个节点的左指针:

tmp <-> node1 <-> node2 <-> nextnext

您在node1 上并检测到您需要将其与node2 交换:

您需要将tmp -> node1 更改为tmp -> node2 您还需要将node2 nextnext 更改为node1 nextnext 以及

【讨论】:

以上是关于冒泡排序双链表的主要内容,如果未能解决你的问题,请参考以下文章

Java中双链表的冒泡排序[重复]

一百万个结构数组,根据其中一项值排序,用双链表还是数组排序效率更好

从数组冒泡排序迁移到链表冒泡排序

经典算法学习——非循环双向链表实现冒泡排序(不带头结点)

经典算法学习——链表实现冒泡排序

单链表 --- 冒泡排序 约瑟夫环