# 谈指神通

pezy

````cpp````struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
``````

## 链表的逆

`````` 1->2->3->4->5
^
root
``````

`````` 1->2->3->4->5 | ListNode* reverse(ListNode *root) {
^             |      ListNode *node = nullptr;
root          | }
|
null          |
^             |
node          |
``````

`````` 2->3->4->5    | ListNode* reverse(ListNode *root) {
^             |      ListNode *node = nullptr;
root          |      ListNode *next = root->next;     // next refer to 2
|      root->next = node;               // root point to node
1->null       |      node = root;                     // node refer to root(1)
^             |      root = next;                     // root refer to next(2)
node          | }
``````

````cpp````ListNode* reverse(ListNode *root) {
ListNode *node = nullptr;
while (root) {
ListNode *next = root->next;
root->next = node;
node = root;
root = next;
}
return node;
}
``````

## 链表除重

``````1->1->2->2->3->4
^
head
cur
``````

``````1->1->2->2->3->4    |  if (cur->val == cur->next->val) {
^  ^  ^             |      ListNode *next = cur->next->next;
cur   next          |      delete cur->next;
|     ^             |      cur->next = next;
|_____|             |  }
``````

````cpp````ListNode *removeDuplicates(ListNode *head) {
if (head == nullptr) return head;
for (ListNode *cur=head; cur->next; )
if (cur->val == cur->next->val) {
ListNode *next = cur->next->next;
delete cur->next;
cur->next = next;
} else { cur = cur->next; }
return head;
}
``````

## 链表合并

``````1->2->3
^
a
==>    1->4->2->5->3->6
4->5->6            ^
^                  new_list
b
``````

``````     a ------>         | while (a && b) {
0 -> 1   2   3         |     tail->next = a;
^    |  /|  /|         |     tail = a;
|    V / V / V         |     a = a->next;
|    4   5   6 -> null |     tail->next = b;
|    b ------>         |     tail = b;
dummy                  |     b = b->next;
``````

````cpp````ListNode *shuffleMerge(ListNode *a, ListNode *b) {
ListNode dummy(0), *tail = &dummy;
while (a && b) {
tail->next = a;
tail = a;
a = a->next;
tail->next = b;
tail = b;
b = b->next;
}
tail->next = a ? a : b;
return dummy.next;
}
``````

## 移动节点

``````1->2->3            2->3
^                  ^
a                  a
==>
1->2->3            1->1->2->3
^                  ^
b                  b
``````

``````    s->s        |
1  2->3     | void moveNode(ListNode **destRef, ListNode **sourceRef) {
->n           |     ListNode *newNode = *sourceRef;
|  |           |     *sourceRef = newNode->next;
|  V           |     newNode->next = *destRef;
|  1->2->3     |     *destRef = newNode;
---d           | }
``````

## 顺序合并

``````1->3->5
==>  1->2->3->4->5->6
2->4->6
``````

````cpp````ListNode *sortedMerge(ListNode *a, ListNode *b) {
ListNode dummy(0), *tail = &dummy;
for ( ;a && b; tail = tail->next) {
if (a->val <= b->val) moveNode(&(tail->next), &a);
else moveNode(&(tail->next), &b);
}
tail->next = a ? a : b;
return dummy.next;
}
``````

``````1->null
^
a
==>  1->2->3
2->3         ^  ^
^            a  b
b
``````

``````1->null
^
a
==> 1->2->3
2->3
^
b
``````

`````` ____    ______    ______     |
|null|  |0x2342|  |0x6787|    | ListNode **aRef = &a; // 0x9899
|____|  |__a___|  |__&a__|    | *aRef = b; //
0x2342   0x6787    0x9899     |
____    ______    ______     |  ______
| 2  |  |0x1221|  |0x3554|    | |0x1221|
|____|  |__b___|  |__&b__|    | |__&a__| // 当我们找指针 a 的地址时，实际却找到了 b.
0x1221   0x3554    0x0980     |  0x9899  // 所以现在的链表为：1->2->3.
``````

````cpp````ListNode *sortedMerge(ListNode *a, ListNode *b) {
ListNode *ret = nullptr, **lastPtrRef = &ret;
for (; a && b; lastPtrRef = &((*lastPtrRef)->next)) {
if (a->val <= b->val) moveNode(lastPtrRef, &a);
else moveNode(lastPtrRef, &b);
}
*lastPtrRef = a ? a : b;
return ret;
}
``````

````cpp````ListNode *sortedMerge(ListNode *a, ListNode *b) {
ListNode *ret = nullptr;
if (a == nullptr) return b;
else if (b == nullptr) return a;

if (a->val <= b->val) { ret = a; ret->next = sortedMerge(a->next, b); }
else { ret = b; ret->next = sortedMerge(a, b->next); }

return ret;
}
``````

## 顺序插入

``````4
^
newNode
==>  1->3->4->5->7->8
1->3->5->7->8
^
head
``````

1. 直接插入法（教科书法）
2. 傀儡节点
3. 引用法（指针的指针）

````cpp````1 2->3->4->5    |    if (*headRef == nullptr || (*headRef)->val >= newNode->val) {
^ ^             |        newNode->next = *headRef;
| head          |        *headRef = newNode;
newNode         |    } else {
----------------|        ListNode *curr = *headRef;
1->2        4->5|        while (curr->next != nullptr && curr->next->val < newNode->val)
^        ^   |            curr = curr->next;
curr->3--|   |        newNode->next = curr->next;
^      |        curr->next = newNode;
newNode|    }
``````

````cpp````void sortedInsert(ListNode **headRef, ListNode *newNode) {
ListNode dummy(0), *tail = &dummy;
dummy.next = *headRef;

while (tail->next != NULL && tail->next->val < newNode->val)
tail = tail->next;
newNode->next = tail->next;
tail->next = newNode;
*headRef = dummy.next;
}
``````

````cpp````1->3->5        | ListNode **currRef = headRef;
^        | while (*currRef != nullptr && (*currRef)->val < newNode->val)
4-> curr     |     currRef = &((*currRef)->next);
^            | newNode->next = *currRef;
newNode      | *currRef = newNode;
``````

## 链表排序

````cpp````void insertSort(ListNode **headRef) {
ListNode *newHead = nullptr;
for (ListNode *curr = *headRef, *next; curr; curr = next) {
next = curr->next;
sortedInsert(&newHead, curr);
}
*headRef = newHead;
}
``````

3.1k 声望
330 粉丝
0 条评论