欢迎访问宙启技术站
智能推送

C++怎么实现3个链表排序整合到一起

发布时间:2023-05-17 06:44:59

问题描述

在实际编程中,可能需要将多个链表按一定的规则排序整合到一起,使得整合后的链表有序。如何实现这个功能呢?

方法分析

一种比较简单的方法是,首先将多个链表合并成一个链表,然后对这个新链表进行排序。

具体步骤如下:

1. 定义一个新链表,作为排序后的结果链表。

2. 对原始的三个链表分别按照指定规则(如大小)进行排序。

3. 依次比较三个链表的头结点,取出值最小的结点,插入到结果链表中,并将对应原链表的头指针往后移动一个结点,直到三个原链表都为空。

4. 将结果链表返回即可。

具体实现

下面贴出C语言代码实现:

/* 结点数据结构 */

typedef struct node_s {

    int value;     /* 结点值 */

    node_s *next;  /* 下一个结点指针 */

}node;

/**

 * 合并多个链表。

 *

 * @param list1  个链表的头结点指针。

 * @param list2 第二个链表的头结点指针。

 * @param list3 第三个链表的头结点指针。

 * @return 合并后的链表的头结点指针。

 */

node *merge_lists(node *list1, node *list2, node *list3) {

    node *result = NULL;    /* 合并后的链表的头指针 */

    node *tail = NULL;      /* 合并后的链表的尾指针 */

    /* 如果三个链表中有一个为空,则直接返回 */

    if (list1 == NULL && list2 == NULL && list3 == NULL) {

        return NULL;

    }

    /* 将3个链表分别按照指定规则排序(这里按照结点值从小到大排序) */

    list1 = sort(list1);

    list2 = sort(list2);

    list3 = sort(list3);

    /* 比较三个链表的头结点,取出值最小的结点,插入到结果链表中,并将对应原链表的头指针往后移动一个结点 */

    while(list1 != NULL && list2 != NULL && list3 != NULL) {

        node *min_node = NULL;

        if (list1->value <= list2->value && list1->value <= list3->value) {

            min_node = list1;

            list1 = list1->next;

        } else if (list2->value <= list3->value) {

            min_node = list2;

            list2 = list2->next;

        } else {

            min_node = list3;

            list3 = list3->next;

        }

        if (result == NULL) {

            result = min_node;

            tail = min_node;

        } else {

            tail->next = min_node;

            tail = min_node;

        }

    }

    /* 处理剩余的结点 */

    if (list1 != NULL) {

        if (result == NULL) {

            result = list1;

        } else {

            tail->next = list1;

        }

    } else if (list2 != NULL) {

        if (result == NULL) {

            result = list2;

        } else {

            tail->next = list2;

        }

    } else if (list3 != NULL) {

        if (result == NULL) {

            result = list3;

        } else {

            tail->next = list3;

        }

    }

    return result;

}

/**

 * 对链表按照指定规则进行排序。

 *

 * @param head 链表的头结点指针。

 * @return 排序后的链表的头结点指针。

 */

node *sort(node *head) {

    /* 如果链表为空或只有一个结点,则认为已经是有序的 */

    if (head == NULL || head->next == NULL) {

        return head;

    }

    /* 将链表拆分成两个子链表,分别进行排序 */

    node *slow = head;

    node *fast = head->next;

    while(fast != NULL) {

        fast = fast->next;

        if (fast != NULL) {

            slow = slow->next;

            fast = fast->next;

        }

    }

    node *mid = slow->next;

    slow->next = NULL;

    node *left = sort(head);

    node *right = sort(mid);

    /* 将两个已排好序的子链表合并成一个链表 */

    node *result = NULL;

    node *tail = NULL;

    while(left != NULL && right != NULL) {

        node *min_node = NULL;

        if (left->value <= right->value) {

            min_node = left;

            left = left->next;

        } else {

            min_node = right;

            right = right->next;

        }

        if (result == NULL) {

            result = min_node;

            tail = min_node;

        } else {

            tail->next = min_node;

            tail = min_node;

        }

    }

    if (left != NULL) {

        tail->next = left;

    } else if (right != NULL) {

        tail->next = right;

    }

    return result;

}

这份代码通过sort函数实现链表的排序,将待排序的三个链表按照指定规则排序完成后,通过合并产生新的有序链表并返回。

代码解释

1. 首先实现了一个结点数据结构:

typedef struct node_s {

    int value;     /* 结点值 */

    node_s *next;  /* 下一个结点指针 */

}node;

2. 编写了一个merge_lists函数,将三个链表合并成有序的新链表。

3. 编写了一个sort函数,实现链表的排序,并返回排好序的链表的头结点指针。

其中,实现链表排序的代码使用了归并排序算法,具体步骤如下:

先使用快慢指针法将链表分成两个部分。

递归地对两个部分分别进行排序。

将排好序的两个部分合并成一个有序链表。