内核链表实现任意两个节点交换位置

本文介绍了一种使用链表实现的冒泡排序算法,并详细展示了如何通过比较和交换链表节点来完成排序过程。该算法适用于任何基于链表的数据结构,提供了一个具体的C语言示例程序,包括必要的数据定义、比较函数、交换函数以及排序函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#include "list.h" //list.h这个文件需要你自己打造,可以拷贝内核源码,也可以参考我的博文

struct data_info {
    int data;
    struct list_head list;
};

int  cmp_data(struct list_head *a, struct list_head *b)
{
    struct data_info *pa = list_entry(a, struct data_info, list);
    struct data_info *pb = list_entry(b, struct data_info, list);
    return pa->data - pb->data;
}

void  swap(struct list_head *a, struct list_head *b)//加入一个节点作为缓存作用,具有通用性,不管两个节点是相邻还是不相邻。
{
    struct  list_head flag = {NULL, NULL};
    __list_add(&flag, b->prev, b);
    list_del(b);
    __list_add(b, a->prev, a);
    list_del(a);
    __list_add(a, flag.prev, &flag);
    list_del(&flag);
}

void  bubble_sort(struct list_head *head, int  (*compar)(struct list_head *, struct list_head *))
{
    struct list_head *start = NULL; 
    struct list_head *end = NULL;   
     //采用冒泡排序算法。
    list_for_each_reverse(end, head) //从尾向头遍历。
    {   
        list_for_each(start, head) //从头向尾遍历。
        {           
            if (start == end)                       
                break;

            if (compar(start, start->next) > 0) 
            {
                swap(start, start->next);                           
                start = start->prev; //start归位
                if (start == end) 
                    end = end->next; //end归位            
            }
        }
    }
}

int main(void)
{
    struct data_info s[] =  {{6}, {4}, {7}, {9}, {2}, {8}, {5}, {1}, {3}};

    LIST_HEAD(head);
    int i;
    for (i = 0; i < sizeof s/ sizeof *s; ++i) 
    {
        list_add_tail(&s[i].list, &head);
    } //尾插,构成链表

    struct data_info *pdata = NULL;
    list_for_each_entry(pdata, &head, list) 
    {
        printf("%d ", pdata->data);
    }
    printf("\n"); //排序之前

    bubble_sort(&head, cmp_data); //进行排序

    list_for_each_entry(pdata, &head, list) 
    {
        printf("%d ", pdata->data);
    }
    printf("\n"); //排序之后
    return 0;
}

以下是一个简单的C++程序,用于将一个长度为n的数组转换为链表,并交换链表两个节点和最后两个节点位置: ```cpp #include <iostream> using namespace std; struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; ListNode* arrayToLinkedList(int arr[], int n) { ListNode *head = new ListNode(arr[0]); ListNode *tail = head; for (int i = 1; i < n; i++) { tail->next = new ListNode(arr[i]); tail = tail->next; } return head; } void swapNodes(ListNode *head, int pos1, int pos2) { if (pos1 == pos2) return; // 如果交换位置相同,则无需交换 ListNode *p1 = head; ListNode *p2 = head->next; for (int i = 0; i < pos1 && i < pos2; i++) { p1 = p1->next; } for (int i = 0; i < pos2 - pos1 && p2 != NULL && p2 != head->next; i++) { p2 = p2->next; } if (p2 == NULL) return; // 如果pos2大于链表长度,则无需交换 p1->next = p2->next; // 交换节点位置 p2->next = p1; // 交换节点值 } int main() { int arr[] = {1, 2, 3, 4, 5}; int n = sizeof(arr) / sizeof(arr[0]); ListNode *head = arrayToLinkedList(arr, n); swapNodes(head, 1, 3); // 将链表两个节点交换位置 swapNodes(head, -2, -1); // 将链表最后两个节点交换位置 // 输出链表内容,验证交换结果是否正确 ListNode *p = head->next; while (p != NULL) { cout << p->val << " "; p = p->next; } return 0; } ``` 在上面的代码中,我们首先定义了一个`ListNode`结构体,用于表示链表中的节点。然后,我们使用`arrayToLinkedList`函数将数组转换为链表。该函数使用一个指针`tail`来跟踪链表的尾部,并在数组中逐个添加节点。最后,我们返回链表的头节点。 接下来,我们定义了`swapNodes`函数,用于交换链表中的节点位置和值。该函数接受一个链表节点两个位置参数,并使用指针遍历链表来找到要交换节点。最后,我们使用指针来交换节点位置和值。 在主函数中,我们首先创建一个长度为5的数组并转换为链表。然后,我们调用`swapNodes`函数两次来交换链表两个节点和最后两个节点位置。最后,我们输出链表内容,以验证交换结果是否正确。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值