如何在不交换数据的情况下交换两个节点
how can i swap two nodes without exchanging data
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head;
void createnodeatbeg(int key) {
struct node *new = (struct node*)malloc(sizeof(struct node));
new->data = key;
new->next = head;
head = new;
}
void printlist() {
struct node *temp = head;
printf("list is:");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
void swapnodes(int x, int y) {
struct node *prevX = NULL;
struct node *prevY = NULL;
struct node *currX = head;
struct node *currY = head;
while (currX->data != x && currX != NULL) {
prevX = currX;
currX = currX->next;
}
printf("not found\n");
while (currY->data != y && currY != NULL) {
prevY = currY;
currY = currY->next;
}
if (currX == NULL || currY == NULL) {
printf("elements not found\n");
return;
}
struct node *swap = currY->next;
prevX->next = currY;
currY->next = prevY;
prevY->next = currX;
currX->next = swap;
}
int main() {
head = NULL;
int nodes, key;
printf("enter number of nodes\n");
scanf("%d", &nodes);
for (int i = 0; i < nodes; i++) {
int data;
printf("enter number\n");
scanf("%d", &data);
createnodeatbeg(data);
}
printlist();
int x, y;
printf("enter the values from the list to be swapped\n");
scanf("%d %d", &x, &y);
swapnodes(x, y);
printf("swapped list is:\n");
printlist();
}
我的代码在列表中存在元素(x 和 y)时有效,但如果列表中不存在,则错误为 ./a.out terminated by signal SIGSEGV (Address boundary error)
。
问题是控件不是从 swapNodes()
函数中的第一个 while 循环中出来的。
该代码接受用户输入并在开头创建一个节点。
问题出在以下相同的行中:
while(currX->data!=x && currX!=NULL)
while(currY->data!=y && currY!=NULL)
这是因为您不是先检查 NULL
然后再使用它,而是检查 NULL
后使用。因此,当 x
或 y
不存在时,您正在尝试访问 NULL->data
,这会导致 分段错误 (SIGSEGV)
分别改为:
while(currX!=NULL && currX->data!=x)
while(currY!=NULL && currY->data!=y)
while 语句条件中的操作数顺序错误。
while(currX->data!=x && currX!=NULL)
{
prevX=currX;
currX=currX->next;
}
//...
while(currY->data!=y && currY!=NULL)
{
prevY=currY;
currY=currY->next;
}
这里一定是
while(currX != NULL && currX->data!=x)
{
prevX=currX;
currX=currX->next;
}
//...
while(currY != NULL && currY->data!=y)
{
prevY=currY;
currY=currY->next;
}
所以如果例如 currX
等于 NULL
那么表达式 currX->data!=x
将不会被评估。
这段代码
struct node *swap = currY->next;
prevX->next = currY;
currY->next = prevY;
prevY->next = currX;
currX->next = swap;
也是错误的,因为例如 prevX
或 prevY
可以等于 NULL
.
而且你必须通过引用来处理函数中的头部。否则头节点不会改变。
您应该将函数拆分为两个函数。第一个找到具有给定值的节点,第二个将交换找到的节点,如果它们不等于 NULL
.
当函数依赖于全局变量时,这也是一个坏主意。事实上你的程序不能同时处理两个列表。
这是一个演示程序,展示了如何实现功能交换。
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node ** find( struct node **head, int data )
{
while ( *head && ( *head )->data != data ) head = &( *head )->next;
return head;
}
void swap( struct node **head, int data1, int data2 )
{
struct node **left, **right;
if ( *( left = find( head, data1 ) ) && *( right = find( head, data2 ) ) )
{
struct node *tmp = *left;
*left = *right;
*right = tmp;
tmp = ( *left )->next;
( *left )->next = ( *right )->next;
( *right )->next = tmp;
}
}
int push_front( struct node **head, int data )
{
struct node *tmp = malloc( sizeof( struct node ) );
int success = tmp != NULL;
if ( success )
{
tmp->data = data;
tmp->next = *head;
*head = tmp;
}
return success;
}
void display( struct node **head )
{
for ( struct node *current = *head; current; current = current->next )
{
printf( "%d ", current->data );
}
}
int main(void)
{
const int N = 10;
struct node *head = NULL;
for ( int i = 0; i < N; i++ ) push_front( &head, i );
display( &head );
putchar( '\n' );
for ( int i = 0; i < N; i+=2 )
{
swap( &head, i, i + 1 );
}
display( &head );
putchar( '\n' );
return 0;
}
它的输出是
9 8 7 6 5 4 3 2 1 0
8 9 6 7 4 5 2 3 0 1
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head;
void createnodeatbeg(int key) {
struct node *new = (struct node*)malloc(sizeof(struct node));
new->data = key;
new->next = head;
head = new;
}
void printlist() {
struct node *temp = head;
printf("list is:");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
void swapnodes(int x, int y) {
struct node *prevX = NULL;
struct node *prevY = NULL;
struct node *currX = head;
struct node *currY = head;
while (currX->data != x && currX != NULL) {
prevX = currX;
currX = currX->next;
}
printf("not found\n");
while (currY->data != y && currY != NULL) {
prevY = currY;
currY = currY->next;
}
if (currX == NULL || currY == NULL) {
printf("elements not found\n");
return;
}
struct node *swap = currY->next;
prevX->next = currY;
currY->next = prevY;
prevY->next = currX;
currX->next = swap;
}
int main() {
head = NULL;
int nodes, key;
printf("enter number of nodes\n");
scanf("%d", &nodes);
for (int i = 0; i < nodes; i++) {
int data;
printf("enter number\n");
scanf("%d", &data);
createnodeatbeg(data);
}
printlist();
int x, y;
printf("enter the values from the list to be swapped\n");
scanf("%d %d", &x, &y);
swapnodes(x, y);
printf("swapped list is:\n");
printlist();
}
我的代码在列表中存在元素(x 和 y)时有效,但如果列表中不存在,则错误为 ./a.out terminated by signal SIGSEGV (Address boundary error)
。
问题是控件不是从 swapNodes()
函数中的第一个 while 循环中出来的。
该代码接受用户输入并在开头创建一个节点。
问题出在以下相同的行中:
while(currX->data!=x && currX!=NULL)
while(currY->data!=y && currY!=NULL)
这是因为您不是先检查 NULL
然后再使用它,而是检查 NULL
后使用。因此,当 x
或 y
不存在时,您正在尝试访问 NULL->data
,这会导致 分段错误 (SIGSEGV)
分别改为:
while(currX!=NULL && currX->data!=x)
while(currY!=NULL && currY->data!=y)
while 语句条件中的操作数顺序错误。
while(currX->data!=x && currX!=NULL)
{
prevX=currX;
currX=currX->next;
}
//...
while(currY->data!=y && currY!=NULL)
{
prevY=currY;
currY=currY->next;
}
这里一定是
while(currX != NULL && currX->data!=x)
{
prevX=currX;
currX=currX->next;
}
//...
while(currY != NULL && currY->data!=y)
{
prevY=currY;
currY=currY->next;
}
所以如果例如 currX
等于 NULL
那么表达式 currX->data!=x
将不会被评估。
这段代码
struct node *swap = currY->next;
prevX->next = currY;
currY->next = prevY;
prevY->next = currX;
currX->next = swap;
也是错误的,因为例如 prevX
或 prevY
可以等于 NULL
.
而且你必须通过引用来处理函数中的头部。否则头节点不会改变。
您应该将函数拆分为两个函数。第一个找到具有给定值的节点,第二个将交换找到的节点,如果它们不等于 NULL
.
当函数依赖于全局变量时,这也是一个坏主意。事实上你的程序不能同时处理两个列表。
这是一个演示程序,展示了如何实现功能交换。
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node ** find( struct node **head, int data )
{
while ( *head && ( *head )->data != data ) head = &( *head )->next;
return head;
}
void swap( struct node **head, int data1, int data2 )
{
struct node **left, **right;
if ( *( left = find( head, data1 ) ) && *( right = find( head, data2 ) ) )
{
struct node *tmp = *left;
*left = *right;
*right = tmp;
tmp = ( *left )->next;
( *left )->next = ( *right )->next;
( *right )->next = tmp;
}
}
int push_front( struct node **head, int data )
{
struct node *tmp = malloc( sizeof( struct node ) );
int success = tmp != NULL;
if ( success )
{
tmp->data = data;
tmp->next = *head;
*head = tmp;
}
return success;
}
void display( struct node **head )
{
for ( struct node *current = *head; current; current = current->next )
{
printf( "%d ", current->data );
}
}
int main(void)
{
const int N = 10;
struct node *head = NULL;
for ( int i = 0; i < N; i++ ) push_front( &head, i );
display( &head );
putchar( '\n' );
for ( int i = 0; i < N; i+=2 )
{
swap( &head, i, i + 1 );
}
display( &head );
putchar( '\n' );
return 0;
}
它的输出是
9 8 7 6 5 4 3 2 1 0
8 9 6 7 4 5 2 3 0 1