Implement a function that merges two large-to-small ordered linked lists into a list, and the new list is a small-to-large ordered list.
Can be divided into two ideas:
1. Merge the two linked lists into a list, and the combined list is sorted from large to small
2. Reverse the chain list and get the list of linked lists merged from small to sorted
The most brutal method, traversing the node of the first list, and comparing each node of the second list, finds the smallest person to insert as a new node of the list, and the time complexity of this method is O (len1*len2).
Since the two linked lists are ordered, we can start by comparing the first node of the two linked lists, pointing to the list of links that point to the new linked list, which points to the larger of the head node value, and list1 the linked list. Then point to the second node of the List1, while Lsit2 does not move, still points to the head node, the second node of the List1 continues to compare, take the larger one as the new node.
If the two linked lists are not long, then there must be a list of links to go through, just to add the remaining parts of the list that have not been traversed to the new linked list.
In this way, you can complete the task in O (len1+len2) without having to construct a new storage space.
list_t *pnew = NULL;
list_t *pcur = NULL;
if (H1 = = NULL | | h2 = = NULL) {//If one of the linked lists is empty, no comparison is required, return null is returned
;
}
Find the larger list of head nodes, point the new linked list pointer to it
if (h1->data >= h2->data) {
pnew = h1;
H1 = h1->next;
}
else{
pnew = h2;
H2 = h2->next;
}
Pcur = pnew;
do{
//Fetch node larger value as node of new list
if (h1->data >= h2->data) {
pcur->next = h1;
Pcur = pcur->next;
H1 = h1->next;
}
else{
pcur->next = h2;
Pcur = pcur->next;
H2 = h2->next;
}
} while (H1! = null && H2! = null);//with Do-while, because the first H1 and H2 are definitely not empty, otherwise the front has returned
list_t *cnt;
if (H1 = = NULL && H2 = = null) {//Two linked lists are the same length, the new list has been combined and returned to return
pnew;
}
Pcur->next = h1?h1:h2;//must have an empty, directly link the remainder of the non-empty chain to the new linked list
Linked list Reverse
After getting the new linked list, to reverse the list, you might initially think of constructing a new linked list, traversing the original linked list, and then copying the nodes one after another.
In fact, just use two pointers to the adjacent two nodes, and then point to the reverse (next pointer), of course, before this is to save a node the original next pointer (the third node), or lose the trace of the list.
list_t *p2 = pnew->next;
Pnew->next = null;//The original head node becomes the tail node, pointing to NULL
list_t *tmp;
while (P2! = NULL) {
TMP = p2->next;//holds the address of the third node
P2->next = pnew;//reversal points to
pnew = p2;//pointer moves back, originally pointing to the first node, Now point to the second node
p2 = tmp;//pointer moves back, originally pointing to the second node, now pointing to the third node
}
This completes the list merge and reverse, complete code is as follows:
#include <string.h> #include <malloc.h> #include <iostream> #include <vector> #include <
math.h> #include <stdlib.h> #include <stdio.h> using namespace std;
typedef struct mlist{int data;
struct Mlist *next;
}list_t;
void Printdata (list_t* l) {list_t* tmp = L;
while (tmp! = NULL) {cout << tmp->data << "";
TMP = tmp->next;
} cout << Endl;
} list_t* mergelist (list_t* H1, list_t* h2) {list_t *pnew = NULL;
list_t *pcur = NULL;
if (H1 = = NULL | | h2 = = NULL) {//If one of the linked lists is empty, no comparison is required and return NULL is returned;
}//Find the larger list of head nodes, point the new list pointer to it if (H1->data >= h2->data) {pnew = h1;
H1 = h1->next;
} else{pnew = h2;
H2 = h2->next;
} pcur = Pnew;
do{//Fetch node larger value as node of new list if (H1->data >= h2->data) {pcur->next = h1;
Pcur = pcur->next; H1 = h1->next;
} else{pcur->next = h2;
Pcur = pcur->next;
H2 = h2->next;
}}while (H1! = null && H2! = null);//With Do-while because the first H1 and H2 are definitely not empty, otherwise the front has already returned list_t *cnt;
if (H1 = = NULL && H2 = = null) {//two lists as long, the new list has been combined and returned to return pnew;
} Pcur->next = h1?h1:h2;//must have an empty, directly to the remaining part of the non-empty chain to the new list printdata (pnew);
list_t *P2 = pnew->next;
Pnew->next = null;//The original head node becomes the tail node, pointing to NULL list_t *tmp; while (P2! = NULL) {tmp = p2->next;//holds the address of the third node P2->next = pnew;//reversal points to Pnew = p2;//pointer moves back,
Originally pointing to the first node, now pointing to the second node P2 = tmp;//pointer back, originally pointing to the second node, now pointing to the third node} printdata (Pnew);
return pnew;
} int main () {int data1[] = {100, 77, 52, 23, 10, 4, 0};
int data2[] = {83, 80, 26, 15, 3, 2, 1, 0};
int l1 = sizeof (data1)/sizeof (data1[0]);
list_t *q = NULL;
list_t *h1 = NULL; for (int idx = 0; idx < L1; idx++) {
list_t *p = (list_t*) malloc (sizeof (list_t));
P->data = Data1[idx];
P->next = NULL;
if (H1 = = NULL) {h1 = P;
} else{Q->next = p;
} q = P;
} int l2 = sizeof (DATA2)/sizeof (data2[0]);
Q = NULL;
list_t *h2 = NULL;
for (int idx = 0; idx < L2; idx++) {list_t *p = (list_t*) malloc (sizeof (list_t));
P->data = Data2[idx];
P->next = NULL;
if (H2 = = NULL) {h2 = P;
} else{Q->next = p;
} q = P;
} mergelist (H1,H2); }
Pairs of two sequences:
+, 4, 0
, 3, 2, 1, 0
Results after operation:
, Max.