归并算法时间复杂度:O(NlogN)

注意:断链和合并的思想

两个链表的归并:

#include

#include

typedef struct listNode{

int val;

struct listNode* next;

}ListNode;

ListNode* mergeNode(ListNode* left, ListNode* right) {

if(left == NULL) {

return right;

}

if(right == NULL) {

return left;

}

//如果左边值比右值大,将将右链接到左链后边

if(left->val < right->val) {

left->next = mergeNode(left->next, right);

return left;

}else { 如果左边值比右值,将将左链接到右链后边

right->next = mergeNode(left, right->next);

return right;

}

}

ListNode* sortList(ListNode* head){

ListNode *fastNode,*slowNode,*breakNode,*left,*right;

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

return head;

}

//找中间位置元素进行合并

fastNode = head;

slowNode = head;

breakNode = head;

//整个思想很有意思,可以保证slowNode始终处在中间的位置,breakNode处于断链的位置

while(fastNode && fastNode->next) {

fastNode = fastNode->next->next;

breakNode = slowNode;

slowNode = slowNode->next;

}

breakNode->next = NULL;

left = sortList(head);

right = sortList(slowNode);

//采用分治法将左右节点排序

mergeNode(left, right);

}

int main(){

int i ;

ListNode *LN,*p,*LTemp;

int w[4] ={4,2,1,3};

LN = (ListNode *)malloc(sizeof(ListNode));

p = LN;

p->val = w[0];

p->next = NULL;

for(i = 1; i< 4; i++){

LTemp= (ListNode *)malloc(sizeof(ListNode));

LTemp->val = w[i];

LTemp ->next =NULL;

p->next = LTemp;

p= LTemp;

}

LN= sortList(LN);

while(LN){

printf("%d ",LN->val);

LN= LN->next;

}

printf("\n");

return 0;

}

K个有序链表的归并排序:

//合并多个链表,采用归并的思想,将链表数组对半归并,不产生新链表,直接节点

//先是合并两个链表

struct ListNode* mergeTwoLists(struct ListNode* L1, struct ListNode* L2){

if(L1 == NULL) {

return L2;

}

if(L2 == NULL) {

return L1;

}

//如果左边值比右值大,将将右链接到左链后边

if(L1->val < L2->val) {

L1->next = mergeTwoLists(L1->next, L2);

return L1;

}else { 如果左边值比右值,将将左链接到右链后边

L2->next = mergeTwoLists(L1, L2->next);

return L2;

}

}

//第二种方式归并

//先是合并两个链表

struct ListNode* mergeTwoLists(struct ListNode* L1, struct ListNode* L2){

struct ListNode head;

if(!L1) return L2;

if(!L2) return L1;

//如何保证头节点不发生改变

head.next = L1;

//将L1指向head,这样比较时L1 ->next 就i是原来L1的第一个节点

L1 = &head;

//将L2接到L1后边,遍历L2

while( L2 != NULL){

//保存L1后边的节点

struct ListNode *p = NULL;

struct ListNode *q = NULL;

p = L1->next;

q = L2 ->next;

//合并L1和L2

if(L1->next == NULL){

L1 ->next = L2;

break;

}

if(p->val >= L2->val){

L1->next= L2;

L2 ->next = p;

L2 = q;

}

L1 =L1 ->next;

}

return head.next;

}

//分开一个链表

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize){

struct ListNode *L1, *L2;

int mid;

if(listsSize == 0){

return NULL;

} else if(listsSize ==1)

{

return lists[0];

}

else if(listsSize == 2) {

return mergeTwoLists(lists[0], lists[1]);

}

mid = (listsSize+1)/2;

L1 = mergeKLists(&lists[0],mid);

L2 = mergeKLists(&lists[mid],listsSize - mid);

return mergeTwoLists(L1, L2);

}

两个有序链表排序C语言,K个有序链表的归并排序(C语言)相关推荐

  1. c语言双链表排序交换节点_图解:单链表翻转的三种方式!

    当我们在聊到链表反转的时候,一定说的都是单链表,双链表本身就具有前驱指针 Prev 和后续指针 next,无需进行翻转. 单链表反转,反转后的效果如下: 看起来很简单,只需要将单链表所有结点的 nex ...

  2. 链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现

    题目中最重要的就是学会一种方法,就是把链表中长度为k的一段从链表中摘除,翻转之后在将其衔接回链表.这是主要的思绪,以下按照此思路给出程序: #include<iostream> using ...

  3. C语言k=xm gt xn gt p,C语言学习001:让程序跑起来

    编译工具下载 编译运行 #include int main(){ puts("C rocks!"); return ; } 编译运行程序 在命令提示符窗口中输入" gcc ...

  4. 【单链表排序】基于C的单链表排序

    1.单链表的排序,排序算法有很多种,但是大多数是基于单链表的顺序存储的,单链表的排序要怎么实现. 大家都知道单链表最重要的就是指针,因为单链表不是顺序存储的,所以对排序时必须是指针的后移,才能访问下一 ...

  5. 单链表中倒数第K个结点

    单链表中倒数第K个结点 链表结点定义如下: typedef int ElemType;typedef struct Node {ElemType data; struct Node *next; }H ...

  6. python 链表倒数第k个节点_链表-删除单链表中倒数第k个节点

    题目 实现一个函数,一个可以删除单链表中倒数第k个节点 难度 简单 分析 本题比较简单,实现方法多种多样,这里提供一种方法 首先明确一点,在单链表中删除倒数第k个节点,需要找到他的前一个节点,让前一个 ...

  7. 剑指offer:合并两个排序的链表 python实现 合并K个排序的链表

    题目 题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 对应LeetCode21. 解题思路 暴力求解: 新建一个链表: 依次判断两个链表的大小, ...

  8. 两个无序单链表,排序后合并成一个有序链表

    两个无序单链表,排序后合并成一个有序链表 算法思想:用冒泡法,对链表1和2进行排序,对排序后的两个链表,从小到大进行循环,装入链表3中. #include<stdio.h> #includ ...

  9. 《剑指offer》-- 链表中倒数第k个节点、反转链表、合并两个排序的链表

    一.链表中倒数时第k个节点: 1.题目: 输入一个链表,输出该链表中倒数第k个结点. 2.解题思路:单链表具有单向移动的特性. (1)第一种:先遍历链表,算出链表节点数count,第二次直接遍历到第c ...

最新文章

  1. IAB303 Data Analytics Assessment Task
  2. 悟空 CRM(9.0版本)V9.0_20190416 更新日志
  3. 数学建模_随机森林分类模型详解Python代码
  4. 求栈中元素个数算法_每日算法系列【LeetCode 315】计算右侧小于当前元素的个数...
  5. QT中在终端下写个小例子
  6. [渝粤教育] 中国传媒大学 政治传播学 参考 资料
  7. 斜视术后融合训练方法_做斜视手术两年后又复发了怎么办?
  8. Google在东京召开了一场AI座谈会
  9. 华中科技大学计算机暑期夏令营,2019年华中科技大学计算机专业夏令营
  10. 连点脚本java,按键精灵键盘连点脚本日常
  11. 将旧硬盘的内容克隆到新硬盘
  12. gmx_MMPBSA--计算蛋白-配体自由能及能量分解
  13. 大白菜无法打开计算机硬盘,大白菜u盘启动盘出现问题及解决办法(上)
  14. 13、Nepxion Discovery 之 全链路调用链监控
  15. sklearn的使用案例(以load_breast_cancer数据集为例)
  16. 机器学习和人工智能发展简史
  17. 禁止iphone浏览器拖动反弹(橡皮筋效果)
  18. 深度报道 | 国内CRM市场迎来巨头加码:百度推出爱番番CRM开放平台
  19. JPA使用过程中遇到的问题
  20. Vue中阿拉伯数字与汉字的相互转换

热门文章

  1. Foundations of Qt Development 学习笔记 Part1 Tips1-50
  2. SqlServer判断表是否存在
  3. SQLServer2005遇到的一些错误:233,18452,18470
  4. 如何首次在 Exchange Server 2003 SP1 上部署 RPC over HTTP
  5. ccna考试真题及经验介绍
  6. 小白的 --Vuex 入门理解
  7. 通过 .gitlab-ci.yml配置任务-官方配置文件翻译
  8. js 关于运算顺序的问题
  9. 移动端与PHP服务端接口通信流程设计(基础版)
  10. Java正則表達式入门