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

题目1519:合并两个排序的链表

题目描述:

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
(hint: 请务必使用链表。)

输入:

输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行为两个整数n和m(0<=n<=1000, 0<=m<=1000):n代表将要输入的第一个链表的元素的个数,m代表将要输入的第二个链表的元素的个数。
下面一行包括n个数t(1<=t<=1000000):代表链表一中的元素。接下来一行包含m个元素,s(1<=t<=1000000)。

输出:

对应每个测试案例,
若有结果,输出相应的链表。否则,输出NULL。

样例输入:
5 2
1 3 5 7 9
2 4
0 0
样例输出:
1 2 3 4 5 7 9
NULL

思路:由于这两个链表都已经排好序了,所以都是两个链表从前往后遍历,当小的那个加入到新表的后面,然后向后移动指针这题主要要考虑特殊情况,两个链表是否为空,还有是否已经到了一个链表的末尾的片判断。
  1 #include<iostream>
  2 #include<vector>
  3 using namespace std;
  4
  5 //链表的数据结构
  6 struct ListNode
  7 {
  8     int val;
  9     ListNode* next;
 10     ListNode(int x):val(x),next(NULL){}
 11 };
 12
 13 //创建一个单链表
 14 ListNode* product(vector<int>& vec,int n)
 15 {
 16     if(n==0)
 17         return NULL;
 18     ListNode* ptr1=new ListNode(vec[0]);
 19     int i=1;
 20     ListNode* ptr2=ptr1;
 21     while(i<n)
 22     {
 23         ptr2->next=new ListNode(vec[i]);
 24         ptr2=ptr2->next;
 25         i++;
 26     }
 27     return ptr1;
 28 }
 29
 30 //单链表每个结点的输出
 31 void cout_node(ListNode* root)
 32 {
 33     if(root==NULL)
 34         return;
 35     ListNode* ptr1=root;
 36     while(ptr1!=NULL)
 37     {
 38         cout<<ptr1->val<<‘ ‘;
 39         ptr1=ptr1->next;
 40     }
 41     cout<<endl;
 42     return;
 43 }
 44
 45 ListNode* merge(ListNode* root1,ListNode* root2)
 46 {
 47     ListNode* root=NULL;
 48     if(root1==NULL&&root2==NULL)//两个链表均为空
 49         return root;
 50     if(root1==NULL)//root2为空
 51         return root2;
 52     if(root2==NULL)//root1为空
 53         return root1;
 54     ListNode* ptr1=root1;
 55     ListNode* ptr2=root2;
 56
 57     //在确定两个链表都不为空下,将其中小的一个结点给root
 58     if(root1->val<root2->val)
 59     {
 60         root=root1;
 61         ptr1=ptr1->next;
 62     }
 63     if(root2->val<root1->val)
 64     {
 65         root=root2;
 66         ptr2=ptr2->next;
 67     }
 68     if(root1->val==root2->val)
 69     {
 70         root=root1;
 71         ptr1=ptr1->next;
 72         ptr2=ptr2->next;
 73     }
 74     ListNode* ptr0=root;
 75     ptr0->next=NULL;
 76
 77     //开始循环
 78     while(1)
 79     {
 80         //若其中一个链表已经到了末尾就截止
 81         if(ptr1==NULL)
 82         {
 83             ptr0->next=ptr2;
 84             return root;
 85         }
 86         if(ptr2==NULL)
 87         {
 88             ptr0->next=ptr1;
 89             return root;
 90         }
 91         //否则将小的那个给root链表,将指针都往后移动
 92         if(ptr1->val<ptr2->val)
 93         {
 94             ptr0->next=ptr1;
 95             ptr1=ptr1->next;
 96             ptr0=ptr0->next;
 97             ptr0->next=NULL;
 98         }
 99         else if(ptr1->val>ptr2->val)
100         {
101             ptr0->next=ptr2;
102             ptr2=ptr2->next;
103             ptr0=ptr0->next;
104             ptr0->next=NULL;
105         }
106         else
107         {
108             ptr0->next=ptr1;
109             ptr1=ptr1->next;
110             ptr2=ptr2->next;
111             ptr0=ptr0->next;
112             ptr0->next=NULL;
113         }
114     }
115     return root;
116 }
117
118 int main()
119 {
120     int ary1[10]={1,3,5,7,9};
121     vector<int> vec1(ary1,ary1+5);
122     ListNode* root1=product(vec1,5);
123     cout_node(root1);
124
125     int ary2[10]={2,4};
126     vector<int> vec2(ary2,ary2+2);
127     ListNode* root2=product(vec2,2);
128     cout_node(root2);
129
130     ListNode* root=merge(root1,root2);
131     cout_node(root);
132
133     system("pause");
134 }
 
时间: 2024-10-19 13:00:45

剑指offer面试题17——合并两个排序的链表的相关文章

剑指offer之面试题17合并两个排序的链表

问题描述: 输入两个递增的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的. 实现代码如下: #include <stdio.h> #include <stdlib.h> #include <stdbool.h> struct List{ int date; struct List *next; }; struct List* doMergeList(struct List *P1head,struct List *P2head){ if(P1head==NU

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

题目: 输入两个递增排序的链表,合并这两个链表并使得新链表中的节点仍然是按照递增排序的. 基本思想: 当我们得到两个链表中值较小的头结点并把它连接到已经合并的链表之后,两个链表剩余的节点依然是排序的,因此合并的步骤和之前的而不周是一样的.这就是典型的递归的过程. #include <iostream> using namespace std; typedef int ElemType;//数据类型模板 typedef struct Node//结点 { ElemType data; struc

剑指offer_面试题17_合并两个排序的链表(两种思维)

题目:输入两个递增排序的链表,合并这两个链表,并使新链表中的结点仍然是按照递增排序的. 第一种思维:合并两个排序的链表,类似于合并两个排序数组,所不同的仅是一个用链表保存数据,一个用数组保存数据. 算法如下:(下面的算法前提是:头结点 不是 链表的第一个数据节点.) /**方法一:合并两个排序链表,使用了新创建的链表来保存,没有改动两个原始链表*/ ListNode *merge_tow_list(ListNode *pHead1,ListNode *pHead2) { if(NULL == p

剑指offer系列源码-合并两个排序的链表

题目1519:合并两个排序的链表 时间限制:1 秒内存限制:128 兆特殊判题:否提交:1309解决:615 题目描述: 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. (hint: 请务必使用链表.) 输入: 输入可能包含多个测试样例,输入以EOF结束. 对于每个测试案例,输入的第一行为两个整数n和m(0<=n<=1000, 0<=m<=1000):n代表将要输入的第一个链表的元素的个数,m代表将要输入的第二个链表的元素的个数. 下面

剑指offer系列10:合并两个排序的链表

我拿到这个题的时候举的例子是链表1:1.3.5.7和链表2:2.4.6.8.我的思路是以:1为基础,将表2的每个结点插入表1.也就是说我一次性是要给新建立的链表中加入两个元素,分别是两个原始链表的头结点.这个思路我做了半天头脑一片混乱,中间指针实在不知道怎么弄了.于是我去睡了一觉,哈哈,我大概是这个世界上最会逃避的人了…… 看了答案使用了递归的方法,其实我做的时候我有想到要用递归,但是没用的原因是我一般写代码不喜欢用递归,原因有两个,一个是递归容易死循环,一个是递归的复杂度太高.但这道题真的太适

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

题目描述:输入两个单调递增的链表list1,list2,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 题目分析: 1.对于链表题目,首先考虑边界情况,即链表为空的情况,提升代码的鲁棒性. 2.合并完一个结点后,剩余的链表仍然是有序的,再合并下一个结点时的过程是一样的,这是一种递归的思想,因此采用递归来合并. Java代码: public class MergeSortedList { public ListNode Merge(ListNode list1,ListNod

【剑指Offer】16、合并两个排序的链表

题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 解法一:使用ArrayList 1 public static ListNode Merge(ListNode list1,ListNode list2) { 2 if(list1==null||list2==null){ 3 if(list1==null){ 4 return list2; 5 }else{ 6 return list1; 7 } 8 } 9 ArrayList<ListNo

剑指offer(16)合并两个排序的链表

题目描述: 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 解题代码: /*function ListNode(x){ this.val = x; this.next = null; }*/ function Merge(pHead1, pHead2) { // write code here if(pHead1 == null && pHead2 == null){ return null; } if(pHead1 == null){ ret

面试题 17:合并两个排序的链表

题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按 照递增排序的. 两个指针指向两个链表的头结点,取其中值小的作为新链表的头结点,和之前的结点串联,如此递归. 注意用例: 两个链表都为null: 其中一个链表为null: 两个链表有多个结点,有相同的值,不同的值. package offer; /*面试题 17:合并两个排序的链表 题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按 照递增排序的.*/ public class Problem17 { st