📅  最后修改于: 2023-12-03 15:27:10.151000             🧑  作者: Mango
在链表中,交换两个节点的指针常常需要交换节点的数据,但有时我们需要仅仅交换节点指针,而不改变节点数据。本文介绍一种用于交换链表中节点指针而不改变节点数据的 C 程序。
在链表中交换两个节点的指针,需要修改它们各自前面节点的指针和它们各自的后面节点的指针,如下图所示:
prev1 -> node1 -> next1 -> node2 -> next2
交换 node1 和 node2 的指针后:
prev1 -> node2 -> next1 -> node1 -> next2
但如果我们需要仅仅交换节点指针,不改变节点数据,我们就不能修改节点指针所指向的数据,因为这会改变链表中各个节点的数据。但是,我们可以使用指向指针的指针(或者叫二级指针)来实现这个目标。具体来说,我们将指向 node1 的指针指针(即 prev1->next 或者 next1->prev)和指向 node2 的指针指针(即 node2->prev 或者 node1->next)互相交换,这样就能够交换节点指针而不改变节点数据了。
下面是一个用于交换链表中节点指针而不改变节点数据的 C 程序的代码,其中的 swap_nodes
函数接受一个指向头节点的指针的指针、两个待交换的节点的值,返回交换后的头节点指针的指针。
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
struct node* prev;
};
void print_list(struct node* head) {
while (head != NULL) {
printf("%d ", head->data);
head = head->next;
}
printf("\n");
}
struct node* create_list(int* arr, int n) {
struct node *head, *tail, *p;
head = tail = NULL;
for (int i = 0; i < n; i++) {
p = (struct node*) malloc(sizeof(struct node));
p->data = arr[i];
p->prev = tail;
p->next = NULL;
if (tail != NULL)
tail->next = p;
else
head = p;
tail = p;
}
return head;
}
struct node** swap_nodes(struct node** head_ref, int x, int y) {
if (x == y)
return head_ref;
struct node **p1 = NULL, **p2 = NULL, **prev1 = NULL, **prev2 = NULL;
/* Find pointers to nodes x, y and their previous nodes */
p1 = head_ref;
while (*p1 != NULL && (*p1)->data != x) {
prev1 = p1;
p1 = &((*p1)->next);
}
p2 = head_ref;
while (*p2 != NULL && (*p2)->data != y) {
prev2 = p2;
p2 = &((*p2)->next);
}
/* Do the actual swapping */
if (*p1 != NULL && *p2 != NULL) {
/* Swap the next pointers */
struct node* tmp = (*p1)->next;
(*p1)->next = (*p2)->next;
(*p2)->next = tmp;
/* Swap the prev pointers */
tmp = (*p1)->prev;
(*p1)->prev = (*p2)->prev;
(*p2)->prev = tmp;
/* Fix the pointers of the nodes before x and y */
if (prev1 != NULL)
(*prev1)->next = *p2;
else
*head_ref = *p2;
if (prev2 != NULL)
(*prev2)->next = *p1;
else
*head_ref = *p1;
/* Swap the pointers of x and y */
tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
return head_ref;
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
int n = sizeof(arr) / sizeof(arr[0]);
struct node* head = create_list(arr, n);
printf("Originally: ");
print_list(head);
/* Swap nodes 2 and 4 */
head = *swap_nodes(&head, 2, 4);
printf("After swapping: ");
print_list(head);
return 0;
}
本文介绍了一种用于交换链表中节点指针而不改变节点数据的 C 程序。这个程序利用指向指针的指针(或者叫二级指针)来实现交换节点指针而不改变节点数据,具有一定的实用价值。