两个有序链表排序C语言,K个有序链表的归并排序(C语言)
归并算法时间复杂度: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语言)相关推荐
- c语言双链表排序交换节点_图解:单链表翻转的三种方式!
当我们在聊到链表反转的时候,一定说的都是单链表,双链表本身就具有前驱指针 Prev 和后续指针 next,无需进行翻转. 单链表反转,反转后的效果如下: 看起来很简单,只需要将单链表所有结点的 nex ...
- 链表翻转。给出一个链表和一个数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 ...
- C语言k=xm gt xn gt p,C语言学习001:让程序跑起来
编译工具下载 编译运行 #include int main(){ puts("C rocks!"); return ; } 编译运行程序 在命令提示符窗口中输入" gcc ...
- 【单链表排序】基于C的单链表排序
1.单链表的排序,排序算法有很多种,但是大多数是基于单链表的顺序存储的,单链表的排序要怎么实现. 大家都知道单链表最重要的就是指针,因为单链表不是顺序存储的,所以对排序时必须是指针的后移,才能访问下一 ...
- 单链表中倒数第K个结点
单链表中倒数第K个结点 链表结点定义如下: typedef int ElemType;typedef struct Node {ElemType data; struct Node *next; }H ...
- python 链表倒数第k个节点_链表-删除单链表中倒数第k个节点
题目 实现一个函数,一个可以删除单链表中倒数第k个节点 难度 简单 分析 本题比较简单,实现方法多种多样,这里提供一种方法 首先明确一点,在单链表中删除倒数第k个节点,需要找到他的前一个节点,让前一个 ...
- 剑指offer:合并两个排序的链表 python实现 合并K个排序的链表
题目 题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 对应LeetCode21. 解题思路 暴力求解: 新建一个链表: 依次判断两个链表的大小, ...
- 两个无序单链表,排序后合并成一个有序链表
两个无序单链表,排序后合并成一个有序链表 算法思想:用冒泡法,对链表1和2进行排序,对排序后的两个链表,从小到大进行循环,装入链表3中. #include<stdio.h> #includ ...
- 《剑指offer》-- 链表中倒数第k个节点、反转链表、合并两个排序的链表
一.链表中倒数时第k个节点: 1.题目: 输入一个链表,输出该链表中倒数第k个结点. 2.解题思路:单链表具有单向移动的特性. (1)第一种:先遍历链表,算出链表节点数count,第二次直接遍历到第c ...
最新文章
- IAB303 Data Analytics Assessment Task
- 悟空 CRM(9.0版本)V9.0_20190416 更新日志
- 数学建模_随机森林分类模型详解Python代码
- 求栈中元素个数算法_每日算法系列【LeetCode 315】计算右侧小于当前元素的个数...
- QT中在终端下写个小例子
- [渝粤教育] 中国传媒大学 政治传播学 参考 资料
- 斜视术后融合训练方法_做斜视手术两年后又复发了怎么办?
- Google在东京召开了一场AI座谈会
- 华中科技大学计算机暑期夏令营,2019年华中科技大学计算机专业夏令营
- 连点脚本java,按键精灵键盘连点脚本日常
- 将旧硬盘的内容克隆到新硬盘
- gmx_MMPBSA--计算蛋白-配体自由能及能量分解
- 大白菜无法打开计算机硬盘,大白菜u盘启动盘出现问题及解决办法(上)
- 13、Nepxion Discovery 之 全链路调用链监控
- sklearn的使用案例(以load_breast_cancer数据集为例)
- 机器学习和人工智能发展简史
- 禁止iphone浏览器拖动反弹(橡皮筋效果)
- 深度报道 | 国内CRM市场迎来巨头加码:百度推出爱番番CRM开放平台
- JPA使用过程中遇到的问题
- Vue中阿拉伯数字与汉字的相互转换
热门文章
- Foundations of Qt Development 学习笔记 Part1 Tips1-50
- SqlServer判断表是否存在
- SQLServer2005遇到的一些错误:233,18452,18470
- 如何首次在 Exchange Server 2003 SP1 上部署 RPC over HTTP
- ccna考试真题及经验介绍
- 小白的 --Vuex 入门理解
- 通过 .gitlab-ci.yml配置任务-官方配置文件翻译
- js 关于运算顺序的问题
- 移动端与PHP服务端接口通信流程设计(基础版)
- Java正則表達式入门