首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

链表的合并排序代码只对C语言中一半的元素进行排序

链表的合并排序是一种常见的排序算法,用于对链表中的元素进行排序。该算法将链表分为两个部分,然后分别对这两个部分进行排序,最后将两个有序的链表合并成一个有序的链表。

以下是一个示例的链表合并排序的代码实现:

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>

// 定义链表节点结构
struct ListNode {
    int val;
    struct ListNode* next;
};

// 合并两个有序链表
struct ListNode* merge(struct ListNode* l1, struct ListNode* l2) {
    if (l1 == NULL) {
        return l2;
    }
    if (l2 == NULL) {
        return l1;
    }

    if (l1->val < l2->val) {
        l1->next = merge(l1->next, l2);
        return l1;
    } else {
        l2->next = merge(l1, l2->next);
        return l2;
    }
}

// 拆分链表
struct ListNode* split(struct ListNode* head) {
    if (head == NULL || head->next == NULL) {
        return head;
    }

    struct ListNode* slow = head;
    struct ListNode* fast = head->next;

    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
    }

    struct ListNode* secondHalf = slow->next;
    slow->next = NULL;

    return secondHalf;
}

// 链表的合并排序
struct ListNode* mergeSort(struct ListNode* head) {
    if (head == NULL || head->next == NULL) {
        return head;
    }

    struct ListNode* secondHalf = split(head);

    head = mergeSort(head);
    secondHalf = mergeSort(secondHalf);

    return merge(head, secondHalf);
}

// 创建链表节点
struct ListNode* createNode(int val) {
    struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
    newNode->val = val;
    newNode->next = NULL;
    return newNode;
}

// 打印链表
void printList(struct ListNode* head) {
    struct ListNode* temp = head;
    while (temp != NULL) {
        printf("%d ", temp->val);
        temp = temp->next;
    }
    printf("\n");
}

int main() {
    // 创建链表
    struct ListNode* head = createNode(4);
    head->next = createNode(2);
    head->next->next = createNode(1);
    head->next->next->next = createNode(3);

    printf("原始链表:");
    printList(head);

    // 链表的合并排序
    head = mergeSort(head);

    printf("排序后链表:");
    printList(head);

    return 0;
}

以上代码实现了链表的合并排序。首先,通过拆分链表的方式将链表分为两个部分,然后递归地对这两个部分进行排序。最后,通过合并两个有序链表的方式将两个部分合并成一个有序的链表。

链表的合并排序算法的时间复杂度为O(nlogn),其中n是链表的长度。该算法在处理大规模数据时具有较好的性能。

推荐的腾讯云相关产品:腾讯云云服务器(https://cloud.tencent.com/product/cvm)

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

删除排序链表中的重复元素删除排序链表中的重复元素 II

Remove Duplicates from Sorted List 题目大意 删除一个有序链表中重复的元素,使得每个元素只出现一次。...代码 class Solution(object): def deleteDuplicates(self, head): """ :type head: ListNode...解题思路 不同的地方是这里要删掉所有的重复项,由于链表开头可能会有重复项,被删掉的话头指针会改变,而最终却还需要返回链表的头指针。...所以需要定义一个新的节点,然后链上原链表,然后定义一个前驱指针和一个现指针,每当前驱指针指向新建的节点,现指针从下一个位置开始往下遍历,遇到相同的则继续往下,直到遇到不同项时,把前驱指针的next指向下面那个不同的元素...如果现指针遍历的第一个元素就不相同,则把前驱指针向下移一位。

2.8K20
  • C语言每日一题(45)删除排序链表中的重复元素

    力扣网83 删除排序链表中的重复元素 题目描述 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。...示例 1: 输入:head = [1,1,2] 输出:[1,2] 示例 2: 输入:head = [1,1,2,3,3] 输出:[1,2,3] 提示: 链表中节点数目在范围 [0, 300] 内 -100...<= Node.val <= 100 题目数据保证链表已经按升序 排列 思路分析 有了44题的基础,这道题简直易如反掌。...基于44题的思路,我们这次直接从头结点和它的下一个结点开始扫描,连哨兵位也不用定义。...这题不同的点在于重复的元素至少要保留一个,所以扫描时如果下一个结点的值等于当前结点的值,我们就从下一个结点开始删,直到值不等时,继续遍历。

    62110

    删除排序链表中重复元素的方法

    链表的操作非常常见,也是面试中经常会被问道的问题。对于链表重复元素的删除,有两个变体,现在总结如下。...* @description 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。...2.删除全部重复的元素,只保留没有重复的元素。 *@description * 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。...但是加上了将全部重复的数字都去除这个条件之后,难度瞬间增加了不少。你需要考虑两个问题: 如果链表头就是重复的数字怎么办 如何移动比较链表,删除元素?...第一,对于表头重复的问题,那么最简单的办法就是在表头添加一个元素,加入链表。之后在链表遍历完之后,返回哨兵的next。这是一个非常好的办法,简直是以后解决链表类问题的套路之一。

    1K10

    【拿捏链表(Ⅱ)】—Leetcode删除排序链表中的重复元素

    目录 删除排序链表中的重复元素(Ⅰ) 删除排序链表中的重复元素(Ⅱ) 删除排序链表中的重复元素(Ⅰ) 题目: 给定一个已排序的链表的头 head ,删除所有重复的元素,使每个元素只出现一次 。...返回 已排序的链表 。 思路:这里的思路很简单,定义两个指针,一个指向head,一个指向head的后一个节点,然后遍历进行比较即可。...} cur=cur->next; } //最后置空,防止野指针 tail->next=NULL;; return head; } 删除排序链表中的重复元素...(Ⅱ) 题目: 给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。...返回 已排序的链表 思路:该题是上题的升级版本,稍稍复杂了一点点,不过核心思想是一样的,为非就是遍历,然后比较。这里我们用哨兵卫的单链表,方便我们对节点进行比较。

    50220

    C语言每日一题(44)删除排序链表中的重复元素 II

    力扣 82 删除排序链表中的重复元素 II 题目描述 给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。...示例 1: 输入:head = [1,2,3,3,4,4,5] 输出:[1,2,5] 示例 2: 输入:head = [1,1,1,2,3] 输出:[2,3] 提示: 链表中节点数目在范围 [0, 300...] 内 -100 <= Node.val <= 100 题目数据保证链表已经按升序 排列 思路分析 一次遍历即可,题目所给的链表已经升序排列好了,那如果有重复元素的话他一定是放在一起的,也就是连续的,所以我们从头结点和它的下一个开始...,如果相等的话,我们就将后面的链表向前移动进行覆盖实现删除,直到两个不等时继续遍历到链表结束。...{ cur->next=cur->next->next;//进行删除,将next的next赋给next实现覆盖删除 } }

    14710

    LeetCode 83:删除排序链表中的重复元素

    一、题目描述 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。...二、题目解析 由于给定的链表是排好序的,因此重复的元素在链表中出现的位置是连续的,这个很关键。 因此我们只需要对链表进行一次遍历,就可以删除重复的元素。...3、在访问过程中,只要当前节点和当前节点的下一个节点有值,就不断访问下去 4、当前节点和当前节点的下一个节点有两种关系。...5、当前节点和当前节点的下一个节点相同,此时要删除重复元素, 由于链表已经是排序的,所以去重操作只需要跳过后面这个重复的节点就行。...6、当前节点和当前节点的下一个节点不相同,那么 cur 这个节点可以保留下来,继续访问后面的节点 三、参考代码 // LeetCode 100 题精讲:https://mp.weixin.qq.com/

    89830

    leetcode:83 删除排序链表中的重复元素

    p.next.next; } else{ p=p.next; } } return head; }; 开始遍历链表的开始...let p=head; 当前节点的值等于下一个的值就删除下一个节点的元素. if(p.val===p.next.val) { p.next=p.next.next; } 问题?...如果next没有值的话,会报错的。 因为要相等啊,比较啊,有值才能比较是吧。 那为什么p.next=p.next.next;如果p.next.next;没有值为什么不会报错?因为他不是比较。...比较必须是值与值比较的啊。 所以 while(p&&p.next) 然后让p遍历下去。 问题? 如果有三个值都相同怎么办? 在循环一次,然后是p再跟p.next的元素对比,比较。。...所以p.next是原本的第三个元素了啊. 最后是: 遍历完后就返回链表的头部了呀,代表结束了啊.

    53430
    领券