我尝试使用函数(swapNodes)来交换链表中的节点。
在这里,我存储了要交换的节点的上一个和下一个地址。
但我的代码陷入无限循环。
这段代码可以作为工作代码制作,还是错误的方法?
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *next;
};
void push(struct Node** head_ref, int new_data)
{
struct Node* new_node =
(struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void printList(struct Node *node)
{
while(node != NULL)
{
printf("%d ", node->data);
node = node->next;
}
}
void swapNodes(struct Node** headr,int key1,int key2)
{
struct Node* temp1 = *headr;
struct Node* temp2 = *headr;
if(key1 == key2)
return;
struct Node* prev1 =NULL;
struct Node* next1 =temp1;
while(temp1->data !=key1 && next1 !=NULL)
{
prev1 =temp1;
temp1 =temp1->next;
next1 =temp1->next;
}
struct Node* prev2 =NULL;
struct Node* next2 =temp2;
while(temp2->data !=key2 && next2 !=NULL)
{
prev2 =temp2;
temp2 =temp2->next;
next2 =temp2->next;
}
if(next1 == NULL||next2 == NULL)
return;
prev1->next =temp2;
temp2->next =next1;
prev2->next =temp1;
temp1->next =next2;
}
int main()
{
struct Node *start = NULL;
push(&start, 7);
push(&start, 6);
push(&start, 5);
push(&start, 4);
push(&start, 3);
push(&start, 2);
push(&start, 1);
printf("\n Linked list before calling swapNodes() ");
printList(start);
swapNodes(&start, 4, 3);
printf("\n Linked list after calling swapNodes() ");
printList(start);
return 0;
}
答案 0 :(得分:2)
该函数具有未定义的行为,因为它没有考虑到例如headr
可以等于NULL
或prev1
而prev2
可以等于{{ 1}}。
再写一个函数来查找与给定数据相对应的节点会更好。
然而,函数NULL
可以通过以下方式编写。它找到要交换的节点,然后将指针交换到节点及其数据成员swapNodes
。
你在这里
next
这是一个示范程序。
void swap( struct Node **first, struct Node **second )
{
struct Node *tmp = *first;
*first = *second;
*second = tmp;
}
void swapNodes( struct Node **headr, int key1, int key2 )
{
if ( key1 == key2 ) return;
struct Node **first = headr;
while ( *first && ( *first )->data != key1 ) first = &( *first )->next;
if ( *first == NULL ) return;
struct Node **second = headr;
while ( *second && ( *second )->data != key2 ) second = &( *second )->next;
if ( *second == NULL ) return;
swap( first, second );
swap( &( *first )->next, &( *second )->next );
}
它的输出是
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
void push(struct Node** head_ref, int new_data)
{
struct Node* new_node =
(struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void printList(struct Node *node)
{
while(node != NULL)
{
printf("%d ", node->data);
node = node->next;
}
}
void swap( struct Node **first, struct Node **second )
{
struct Node *tmp = *first;
*first = *second;
*second = tmp;
}
void swapNodes( struct Node **headr, int key1, int key2 )
{
if ( key1 == key2 ) return;
struct Node **first = headr;
while ( *first && ( *first )->data != key1 ) first = &( *first )->next;
if ( *first == NULL ) return;
struct Node **second = headr;
while ( *second && ( *second )->data != key2 ) second = &( *second )->next;
if ( *second == NULL ) return;
swap( first, second );
swap( &( *first )->next, &( *second )->next );
}
int main( void )
{
struct Node *start = NULL;
push(&start, 7);
push(&start, 6);
push(&start, 5);
push(&start, 4);
push(&start, 3);
push(&start, 2);
push(&start, 1);
printf("\n Linked list before calling swapNodes() ");
printList(start);
swapNodes(&start, 4, 3);
printf("\n Linked list after calling swapNodes() ");
printList(start);
return 0;
}
事实上,函数 Linked list before calling swapNodes() 1 2 3 4 5 6 7
Linked list after calling swapNodes() 1 2 4 3 5 6 7
在编写时(没有单独的函数来查找给定数据的节点)做了两件事:1)找到两个节点,然后2)交换它们。搜索节点可能不成功。因此该函数应该向用户报告节点是否被交换。在这种情况下,希望将函数声明为具有返回类型swapNodes
。
例如
int
如果要编写一个单独的函数来搜索上面提到的节点,那么交换节点的函数看起来会更清晰,更简单。
例如
int swapNodes( struct Node **headr, int key1, int key2 )
{
int success = key1 != key2;
if ( success )
{
struct Node **first = headr;
struct Node **second = headr;
while ( *first && ( *first )->data != key1 ) first = &( *first )->next;
success = *first != NULL;
if ( success )
{
while ( *second && ( *second )->data != key2 ) second = &( *second )->next;
success = *second != NULL;
}
if ( success )
{
swap( first, second );
swap( &( *first )->next, &( *second )->next );
}
}
return success;
}
答案 1 :(得分:1)
你应该稍微改写一下{ ["98f13708210194c475687be6106a3b84"]=> array(10)
{ ["product_id"]=> int(20)
["variation_id"]=> int(0)
["variation"]=> array(0) { }
["quantity"]=> int(2)
["line_total"]=> float(3001.98)
["line_subtotal"]=> float(3001.98)
["line_tax"]=> int(0)
["line_subtotal_tax"]=> int(0)
["line_tax_data"]=> array(2) {
["total"]=> array(0) { }
["subtotal"]=> array(0) { } }
["data"]=> array(0) { } } }`
函数:
swapNodes
正如您所看到的,您不需要void swapNodes(struct Node** headr, int key1, int key2)
{
struct Node* temp1 = *headr;
struct Node* temp2 = *headr;
if(key1==key2)
return;
struct Node* prev1=NULL;
while(temp1 && temp1->data!=key1)
{
prev1=temp1;
temp1=temp1->next;
}
struct Node* prev2=NULL;
while(temp2 && temp2->data!=key2)
{
prev2=temp2;
temp2=temp2->next;
}
if(temp1==NULL || temp1==NULL)
return;
// temp1 is a head
if (prev1 == NULL) {
*headr = temp2;
} else {
prev1->next = temp2;
}
// temp2 is a head
if (prev2 == NULL) {
*headr = temp1;
} else {
prev2->next = temp1;
}
struct Node *buff = temp2->next;
temp2->next = temp1->next;
temp1->next = buff;
}
和next1
指针。但是您必须检查next2
或temp1
是否是头部:当您需要将头部替换为另一个节点时,这是一种特殊情况。其余的都是微不足道的 - 只需通过缓冲节点交换节点。