题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。例如输入图中的链表 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、合并两个排序的链表相关推荐

  1. 剑指offer面试题[17]-合并两个排序的链表

    题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 常考题: 假设两个链表如下: 链表1:   1  ->  3 -> 5 -> ...

  2. 剑指offer面试题25. 合并两个排序的链表(双指针)

    题目描述 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的. 思路 详见链接 代码 class Solution:def mergeTwolists(self, l1:List ...

  3. 剑指offer(C++)-JZ25:合并两个排序的链表(数据结构-链表)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排 ...

  4. 《剑指Offer》题目:合并两个排序的链表

    题目描述:输入两个单调递增的链表list1,list2,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 题目分析: 1.对于链表题目,首先考虑边界情况,即链表为空的情况,提升代码 ...

  5. 【剑指offer-Java版】17合并两个排序链表

    合并两个排序链表:老生常谈的内容了 while循环或者递归 注意:输入链表存在一个空或者两个空 public class _Q17 {public ListNode<Integer> Me ...

  6. 剑指offer——面试题17:合并两个排序的链表

    剑指offer--面试题17:合并两个排序的链表 Solution1: 不要犯低级错误... /* struct ListNode {int val;struct ListNode *next;Lis ...

  7. 剑指offer——面试题37:两个链表的第一个公共结点

    剑指offer--面试题37:两个链表的第一个公共结点 20180906整理 Solution1: 时间复杂度为O(n2)O(n2)O(n^2)的垃圾算法 /* struct ListNode {in ...

  8. 剑指offer——面试题38:数字在排序数组中出现的次数

    剑指offer--面试题38:数字在排序数组中出现的次数 20180906整理 Solution1: [注意]先利用二分查找扎到一个值然后再顺序遍历的做法时间复杂度也是O(n)O(n)O(n),代码也 ...

  9. 剑指offer——面试题5:从尾到头打印链表

    剑指offer--面试题5:从尾到头打印链表 Solution1:我的答案 /** * struct ListNode { * int val; * struct ListNode *next; * ...

  10. 面试题25: 合并两个排序的链表

    /******************************************************************* *<剑指Offer--名企面试官精讲典型编程题>C ...

最新文章

  1. 一文读懂基于神经网络的图片风格转移
  2. beanutils工具类_16 个超级实用的 Java 工具类!
  3. php实现socket编程
  4. java的队列_java实现队列
  5. 创建游戏场(实战演习)
  6. C++阶段01笔记07【指针(基本概念、变量定义和使用、内存空间、空指针和野指针、const修饰指针、指针和数组、指针和函数)】
  7. stm32l0的停止模式怎么唤醒_「正点原子STM32Mini板资料连载」第十九章 待机唤醒实验...
  8. html 正则表达式验证金额,js金额校验,js正则表达式,包含正负,小数点后两位...
  9. crontab实现以秒执行,很好很强大
  10. 应用安全-软件安全-漏洞修复整理
  11. 实现三级导航demo
  12. 评价微型计算机有哪些主要性能指标,计算机性能指标有哪些
  13. oracle reco进程停止,oracle的后台进程能否杀掉
  14. python中正则表达式的简单应用_Python正则表达式详细应用
  15. 不改变图片分辨率,减少图片存储大小
  16. Java简单知识点小结
  17. jpa mysql_Spring boot通过JPA访问MySQL数据库
  18. 造人先于造物——松下幸之助的人才观
  19. 从工作量证明(POW)到高阶工作量证明(HPOW)
  20. 统计矢量数据占用三调国有建设用地部分面积

热门文章

  1. 神经网络十大学习率衰减提效策略!
  2. 信念很简单,把书念下去,然后走出去,不枉活一世 —转自动化所一篇博士论文致谢...
  3. 为什么Bert的三个Embedding可以进行相加?
  4. 五分钟快速了解EM算法
  5. 【python】见过if else组合,但是你见过for else组合吗?
  6. 【NLP论文推荐】 掌握实体关系抽取必读的文章
  7. python基础7-函数
  8. 用逻辑回归实现图像识别
  9. Java网络编程之流的详解
  10. 我所理解的Cocos2d-x