假设已有链表head,指针p1指向一个结点,p2指向p1的后继,pprev指向p1的前驱,请想一下,如何交换结点p1和p2?(分p1刚好是head,和p1不是head的情况)
我可以回答该问题。对于交换链表中指针p1和p2所指向的节点,具体步骤如下:
判断p1是否为头节点,若是,则需要更新头指针。如果p1为头节点,则p1的前一个节点没有,将pprev指向一个新的节点即可。
判断p2是否为尾节点,若是,则需要记录p2的前驱节点。如果p2为尾节点,则p2的后继节点为NULL。
判断p1是否紧挨着p2(即p2是否为p1的下一个节点),若是,则无需进行节点交换。
若p1和p2不相邻,则需要交换节点。具体步骤如下:
a. 将p1的前驱节点pprev的next指针指向p2。
b. 将p2的后继节点pnext的prev指针指向p1。
c. 将p1的next指针指向p2的后继节点pnext。
d. 将p2的prev指针指向p1的前驱节点pprev。
e. 交换p1和p2指向的节点。
下面是代码实现:
void swapNodes(Node **head, Node *p1, Node *p2, Node *pprev, Node *pnext) {
// 判断p1是否为头节点
if (*head == p1) {
*head = p2;
} else {
pprev->next = p2;
}
// 判断p2是否为尾节点
if (p2->next == nullptr) {
p2->next = p1->next;
} else {
pnext->prev = p1;
p1->next->prev = p2;
}
// 交换p1和p2指向的节点
Node *tmp = p1->next;
p1->next = p2->next;
p2->next = tmp;
p1->prev = p2->prev;
p2->prev = pprev;
}
其中,head表示链表头指针,p1和p2分别表示要交换的两个节点,pprev和pnext分别表示p1和p2的前驱和后继节点。若p1为头节点,则pprev指向一个新建的节点。若p2为尾节点,则p2的后继节点为NULL,不需要记录pnext。