菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
242
0

线性时间将两个有序链表合成一个有序链表(constant additional space)

原创
05/13 14:22
阅读数 29279

标签:des   com   class   blog   code   div   size   string   ext   color   tab   

description:

given two sorted singly list, merge them into one using constant additional space

algorithm:

we will reference the two linked list as list1 and list2 for convenience,

since list1 is sorted,just find the right position for each element in list2,

detailed comments are added to the following code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
class Node{
public:
    int value;
    Node* Next;
    Node(int v_ = 0, Node* Next_ = NULL):value(v_),Next(Next_){}
};
/*Node* Merge2(Node* head1, Node* head2)
{
    Node* res,*ret;
    if(head1 == NULL) return head2;
    if(head2 == NULL) return head1;
    Node* p = head1;
    Node* q = head2;
     
    if(p->value < q->value)
    {
        res = p;
        p = p->Next;
    }
    else
    {
        res = q;
        q = q->Next;
    }
    ret = res;
    while(p && q)
    {
        if(p->value < q->value)
        {
            res->Next = p;
            res = p;
            p = p->Next;
        }
        else
        {
            res->Next = q;
            res = q;
            q = q->Next;
        }
    }
    while(p)
    {
             res->Next = p;
                  res = p;
        p = p->Next;
    }
    while(q)
    {
        res->Next = q;
        res = q;
        q = q->Next;
    }
    return ret;
}*/
Node* Merge2(Node*p1,Node*p2){
    if(p1 == NULL)
        return p2;
    if(p2 == NULL)
        return p1;
    Node *tmpp1 = p1,*tmpp2 = p2;
    Node*head;
    bool first = true;
    /*core optimization: if tmpp2 find its place in list1, then tmpp2->next must be after its position,so both list1 and list2
      are enumerated only once, which implements linear algorithm*/
    while(tmpp1 != NULL && tmpp2 != NULL){
        Node* tmpformer = NULL;
        while(tmpp1 != NULL && tmpp2->value > tmpp1->value){
            tmpformer = tmpp1;
            tmpp1 = tmpp1->Next;
        }
        if(tmpp1 == NULL){
            tmpformer->Next = tmpp2;
            if(first){
                first = false;
                head = p1;
            }
            break;
        }
        //tmpp2的value值比tmpp1的value值小但是比tmpformer的value值大
        Node* tmprecordp2 = tmpp2->Next;
        tmpp2->Next = tmpp1;
        if(tmpformer != NULL){
            tmpformer->Next = tmpp2;
            if(first){
                first = false;
                head = p1;
            }
        }
        else{
            if(first){
                first = false;
                head = p2;
            }
        }
        tmpp2 = tmprecordp2;
    }
    return head;
}
int main(){
    Node* p1[10], *p2[10];
    memset(p1,0,sizeof(p1));
    memset(p2,0,sizeof(p2));
    int a[25] = {1,3,6,7,8,9,56,67,211,763,2,4,5,10,11,12,13,300,500,800};
    /*initalization*/
    for(int i = 0; i < 10; ++i){
        p1[i] = new Node(a[i]);
    }
    for(int i = 0; i < 10; ++i){
        p2[i] = new Node(a[10+i]);
    }
    Node* pp1,*pp2;
 
    for(int i = 0; i < 9; ++i){
    //  cout << &(p1[i]->Next) << endl;
        p1[i]->Next = p1[i+1];
    }
    for(int i = 0; i < 9; ++i){
        p2[i]->Next = p2[i+1];
    }
        pp1 = p1[0];
    while(pp1 != NULL){
        cout << pp1->value << ‘\t‘;
        pp1 = pp1->Next;
    }
    cout << endl;
    pp2 = p2[0];
    while(pp2 != NULL){
        cout << pp2->value << ‘\t‘;
        pp2 = pp2->Next;
    }
    cout << endl;
    /*initialization end*/
    Node* res = Merge2(p1[0],p2[0]);
    while(res!=NULL){
        cout << res->value << endl;
        res = res->Next;
    }
    for(int i = 0; i < 10; ++i){
        delete p1[i];
    }
    for(int i = 0; i < 10; ++i){
        delete p2[i];
    }
    return 0;
}

key points:

1.pay special attention to keep head pointer, which is easily lost,

  my solution is to set a flag bool variance, which is linear complexity but somewhat inefficient

  perhaps it has potential to improve

2.avoid misorder of pointer

3.special condition: if (p1 == NULL) return p2;

                            if(p2 == NULL ) return p1;

4.when search for the postion for a certain element in list1, note that it might be above any element in list1 so tmpp1 might reach its end(value equals NULL) during search

线性时间将两个有序链表合成一个有序链表(constant additional space),码迷,mamicode.com

线性时间将两个有序链表合成一个有序链表(constant additional space)

发表评论

0/200
242 点赞
0 评论
收藏
为你推荐 换一批