【剑指offer】面试题17、合并两个排序的链表
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如输入图中的链表 1 和链表 2,则合并之后的升序链表如链表 3 所示。链表结点定义如下: typedef struct Node {int m_nValue;struct Node *m_pNext; }ListNode;
一、创建有序链表
创建有序链表的一般步骤: 1、初始化链表为空; 2、生成新的结点指针 pNew; 3、找到该结点值对应的位置,有两种可能:头部,非头部; 4、插入该结点。
假设一链表L现在两个结点,结点值分别为 3、5,现在欲插入的结点值分别为 4,7:
1、现在我们欲插入值为 4 的结点pNew,遍历指针为 pNode,初始值指向值为 3 的头结点pHead;
2、遍历原有链表 L 时,发现 4 > 3,于是 pNode 变为指向值为5的结点pTail;
3、继续比较,由于5 > 4,因此值为 5 的结点的位置就是我们要找的位置;
4、执行插入操作;
注意:在插入的过程中,由于需要连接链表,需要把pNode的前一个链表结点保存下来。
代码如下:
1 void createOrderedList(ListNode **pHead, int len) 2 { 3 while(len--) 4 { 5 ListNode *pNew = (ListNode*)malloc(sizeof(ListNode)); 6 pNew->m_nValue = rand()%100; 7 pNew->m_pNext = NULL; 8 9 if(*pHead == NULL) // 空 10 *pHead = pNew; 11 else //非空 12 { 13 ListNode *pNode = *pHead; 14 ListNode *pPre = NULL; 15 while(pNode != NULL) 16 { 17 if(pNode->m_nValue < pNew->m_nValue) 18 { 19 pPre = pNode; 20 pNode = pNode->m_pNext; 21 } 22 else 23 break; 24 } 25 // 插入的位置 26 if(pPre == NULL) // 头结点位置 27 { 28 pNew->m_pNext = *pHead; 29 *pHead = pNew; 30 } 31 else // 其他位置 32 { 33 pNew->m_pNext = pNode; // 连接链表 34 pPre->m_pNext = pNew; 35 } 36 } 37 } 38 }
View Code
二、两个有序链表的合并(顺序从小到大依次排列)
思路:设有 X 和 Y两个链表;
1、分别遍历 X和Y这两个链表;
2、若 Px 的结点值小于 Py 的结点值,则将结点 Px 结点放入到 合并之后的链表中;否则,执行3;
3、将结点 Px 结点放入到 合并之后的链表中;
4、若while循环中 Px==NULL,则说明链表Px已空,这时,直接将Py的后续结点加入到链表中即可;
5、反之, 若while循环中 Py==NULL,则说明链表Py已空,这时,直接将Px的后续结点加入到链表中即可。
完整的代码如下:
1 #include "stdio.h" 2 #include "stdlib.h" 3 #include "time.h" 4 5 #define N 10 6 7 typedef struct Node 8 { 9 int m_nValue; 10 struct Node *m_pNext; 11 }ListNode, *pListNode; 12 13 // 创建有序链表 14 void createOrderedList(ListNode **pHead, int len) 15 { 16 while(len--) 17 { 18 ListNode *pNew = (ListNode*)malloc(sizeof(ListNode)); 19 pNew->m_nValue = rand()%100; 20 pNew->m_pNext = NULL; 21 22 if(*pHead == NULL) // 空 23 *pHead = pNew; 24 else //非空 25 { 26 ListNode *pNode = *pHead; 27 ListNode *pPre = NULL; 28 while(pNode != NULL) 29 { 30 if(pNode->m_nValue < pNew->m_nValue) 31 { 32 pPre = pNode; 33 pNode = pNode->m_pNext; 34 } 35 else 36 break; 37 } 38 // 插入的位置 39 if(pPre == NULL) // 头结点位置 40 { 41 pNew->m_pNext = *pHead; 42 *pHead = pNew; 43 } 44 else // 其他位置 45 { 46 pNew->m_pNext = pNode; 47 pPre->m_pNext = pNew; 48 } 49 } 50 } 51 } 52 53 void printList(ListNode *pHead) 54 { 55 while(pHead != NULL) 56 { 57 printf("%3d ", pHead->m_nValue); 58 pHead = pHead->m_pNext; 59 } 60 printf("\n"); 61 } 62 63 // 合并有序链表 64 ListNode *Merge(ListNode *leftHead, ListNode *rightHead) 65 { 66 if(!leftHead) 67 return rightHead; 68 else if(!rightHead) 69 return leftHead; 70 71 ListNode *mergeHead, *mergeTail; 72 mergeHead = mergeTail = NULL; 73 ListNode *pLeft = leftHead; 74 ListNode *pRight = rightHead; 75 while(pLeft != NULL && pRight != NULL) 76 { 77 if(pLeft->m_nValue < pRight->m_nValue) // 左链表结点值比右链表结点值大 78 { 79 if(mergeHead == NULL) // 头结点 80 { 81 mergeHead = mergeTail = pLeft; 82 } 83 else // 非头结点 84 { 85 mergeTail->m_pNext = pLeft; 86 mergeTail = pLeft; 87 } 88 pLeft = pLeft->m_pNext; 89 } 90 else// 右链表结点值比左链表结点值大 91 { 92 if(mergeHead == NULL) // 头结点 93 { 94 mergeHead = mergeTail = pRight; 95 } 96 else // 非头结点 97 { 98 mergeTail->m_pNext = pRight; 99 mergeTail = pRight; 100 } 101 pRight = pRight->m_pNext; 102 } 103 104 } 105 106 if(pLeft != NULL) 107 mergeTail->m_pNext = pLeft; 108 if(pRight != NULL) 109 mergeTail->m_pNext = pRight; 110 111 return mergeHead; 112 } 113 114 int main(int argc, char const *argv[]) 115 { 116 srand(time(NULL)); 117 118 ListNode *pHead1 = NULL; 119 ListNode *pHead2 = NULL; 120 121 createOrderedList(&pHead1, N); 122 printf("List1: "); 123 printList(pHead1); 124 125 createOrderedList(&pHead2, N); 126 printf("List2: "); 127 printList(pHead2); 128 129 ListNode *pMergeHead = Merge(pHead1, pHead2); 130 if(pMergeHead != NULL) 131 { 132 printf("The Merge Node: %d\n", pMergeHead->m_nValue); 133 } 134 printf("MergedList: "); 135 printList(pMergeHead); 136 137 return 0; 138 }
View Code
本文完。
转载于:https://www.cnblogs.com/xfxu/p/4588337.html
【剑指offer】面试题17、合并两个排序的链表相关推荐
- 剑指offer面试题[17]-合并两个排序的链表
题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 常考题: 假设两个链表如下: 链表1: 1 -> 3 -> 5 -> ...
- 剑指offer面试题25. 合并两个排序的链表(双指针)
题目描述 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的. 思路 详见链接 代码 class Solution:def mergeTwolists(self, l1:List ...
- 剑指offer(C++)-JZ25:合并两个排序的链表(数据结构-链表)
作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排 ...
- 《剑指Offer》题目:合并两个排序的链表
题目描述:输入两个单调递增的链表list1,list2,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 题目分析: 1.对于链表题目,首先考虑边界情况,即链表为空的情况,提升代码 ...
- 【剑指offer-Java版】17合并两个排序链表
合并两个排序链表:老生常谈的内容了 while循环或者递归 注意:输入链表存在一个空或者两个空 public class _Q17 {public ListNode<Integer> Me ...
- 剑指offer——面试题17:合并两个排序的链表
剑指offer--面试题17:合并两个排序的链表 Solution1: 不要犯低级错误... /* struct ListNode {int val;struct ListNode *next;Lis ...
- 剑指offer——面试题37:两个链表的第一个公共结点
剑指offer--面试题37:两个链表的第一个公共结点 20180906整理 Solution1: 时间复杂度为O(n2)O(n2)O(n^2)的垃圾算法 /* struct ListNode {in ...
- 剑指offer——面试题38:数字在排序数组中出现的次数
剑指offer--面试题38:数字在排序数组中出现的次数 20180906整理 Solution1: [注意]先利用二分查找扎到一个值然后再顺序遍历的做法时间复杂度也是O(n)O(n)O(n),代码也 ...
- 剑指offer——面试题5:从尾到头打印链表
剑指offer--面试题5:从尾到头打印链表 Solution1:我的答案 /** * struct ListNode { * int val; * struct ListNode *next; * ...
- 面试题25: 合并两个排序的链表
/******************************************************************* *<剑指Offer--名企面试官精讲典型编程题>C ...
最新文章
- 一文读懂基于神经网络的图片风格转移
- beanutils工具类_16 个超级实用的 Java 工具类!
- php实现socket编程
- java的队列_java实现队列
- 创建游戏场(实战演习)
- C++阶段01笔记07【指针(基本概念、变量定义和使用、内存空间、空指针和野指针、const修饰指针、指针和数组、指针和函数)】
- stm32l0的停止模式怎么唤醒_「正点原子STM32Mini板资料连载」第十九章 待机唤醒实验...
- html 正则表达式验证金额,js金额校验,js正则表达式,包含正负,小数点后两位...
- crontab实现以秒执行,很好很强大
- 应用安全-软件安全-漏洞修复整理
- 实现三级导航demo
- 评价微型计算机有哪些主要性能指标,计算机性能指标有哪些
- oracle reco进程停止,oracle的后台进程能否杀掉
- python中正则表达式的简单应用_Python正则表达式详细应用
- 不改变图片分辨率,减少图片存储大小
- Java简单知识点小结
- jpa mysql_Spring boot通过JPA访问MySQL数据库
- 造人先于造物——松下幸之助的人才观
- 从工作量证明(POW)到高阶工作量证明(HPOW)
- 统计矢量数据占用三调国有建设用地部分面积