gpt4 book ai didi

c - 双链表: swapping function doesn't always work

转载 作者:行者123 更新时间:2023-11-30 16:09:04 26 4
gpt4 key购买 nike

我已经编写了这段代码,一般来说效果很好,但是当我们到达 i == 74 列表元素为 4 - 11 - 18 - 4 - 10 - 18 - 17 - 22 - 14 - 29swapNodes() 函数必须用键 18 交换两个节点,但是相反,我得到这些元素:4 - 18 - 4 - 10 - 18 - 17 - 22 - 14 - 29。我尝试使用“交换”之前的确切值初始化列表,然后尝试交换这两个节点,一切都按预期进行。

PS:如果有人能帮助我用更少的行数编写 swapNodes() 函数,我将不胜感激,但目前这不是必需的。

typedef struct _node{
int key;
struct _node *next;
struct _node *prev;
}node;

node* createNode(int key){
node* a = (node*)malloc(sizeof(struct _node));
a->key = key;
a->next = NULL;
a->prev = NULL;
return a;
}

void printList(node* head){
while (head != NULL){
printf("%d", head->key);
if(head->next != NULL) printf(" - ");
head = head->next;
}
printf("\n");
}

void fillList(node** head, int dim){
int i;
for(i=0; i<dim; i++)
listInsert(head, createNode(rand()%30));
}

//findes a node given an index, the indices start from 1
node** findNode(node** head, int index){
int i;
for(i=1; i<index; i++)
head = &(*head)->next;
if(head != NULL) return head;
else return NULL;
}

void listInsert(node** head, node* node){
if((*head) == NULL){
(*head) = node;
return;
}
node->next = (*head);
(*head)->prev = node;
(*head) = node;
}

int main(){
node* list = NULL;
fillList(&list, 10);
int i, a, b;
for(i=0; i<100; i++){
printList(list);
a = rand()%10 +1;
b = rand()%10 +1;
swapNodes(&list, *findNode(&list, a), *findNode(&list, b));
printList(list);
printf("\n");
}
return 0;
}
<小时/>

编辑:

我设法重写了 swapNodes() 函数,但这次在 main 中执行相同的行,我在 i==15 的列表中得到了一个循环,a==4b==2。同样,如果我尝试手动交换任何节点,该功能工作正常。

void swapNodes(node** head, node* a, node* b){
node* aPrev = a->prev;
node* aNext = a->next;
node* bPrev = b->prev;
node* bNext = b->next;
if(a == b) return;
if(a->prev == b ||
(b->prev == NULL && a->next == NULL) ||
(b->prev == NULL && b->next == a) ||
a->next == NULL) return swapNodes(head, b, a);
if(a->prev == NULL)
(*head) = b;
else if(b->prev == NULL)
(*head) = a;

if(a->next == b){
if(aPrev != NULL) aPrev->next = b;
b->prev = aPrev;
b->next = a;
bNext->prev = a;
a->prev = b;
a->next = bNext;
}else{
b->next = aNext;
a->next = bNext;

if(a->prev != NULL)
aPrev->next = b;
if(b->prev != NULL)
bPrev->next = a;

if(a->next != NULL)
aNext->prev = b;
if(bNext != NULL)
bNext->prev = a;

if(b != NULL)
b->prev = aPrev;
if(a != NULL)
a->prev = bPrev;
}
}

最佳答案

按照 @ggorlen 给我的想法,我重写了 swapNodes() 函数,添加了一些新函数,最后它完美地工作了。为了在提取节点之前跟踪节点的位置,我创建了一个 struct ,其中包含从 findIndex() 函数返回的索引和节点本身。我还更改了 findNode() 函数,使其返回 node* 类型的变量,而不是 node** 类型。当然,这不是很有效,但我会凑合的。

typedef struct _extractedNode{
struct _node* node;
int index;
}extractedNode;

int findIndex(node* head, node* node){
int i=1;
node* temp = head;
while(node != temp){
temp = temp->next;
i++;
}
return i;
}

extractedNode extractNode(node** head, node* node){
extractedNode extracted;
extracted.index = 0;
if(node == NULL){
printf("extractNode(): il nodo non esiste!\n");
extracted.node = NULL;
extracted.index = -1;
}else{
node* prev = node->prev;
node* next = node->next;
if(prev == NULL){
(*head) = next;
extracted.index = 1;
}
if(extracted.index != 1)
extracted.index = findIndex(*head, node);
if(prev != NULL)
prev->next = next;
if(next != NULL)
next->prev = prev;
node->next = NULL;
node->prev = NULL;
extracted.node = node;
}
return extracted;
}

void listInsertAsIndex(node** head, int index, node* node){
if(index <= 0) return;
if(index == 1) return listInsert(head, node);
else{
node* prev = findNode(*head, index-1);
node* next = prev->next;
prev->next = node;
node->prev = prev;
if(next != NULL){
node->next = next;
next->prev = node;
}
}
}

void swapNodes(node** head, node* a, node* b){
if(a == b) return;
extractedNode aX, bX;
if(a->prev == NULL && a->next == b){
aX = extractNode(head, a);
listInsertAsIndex(head, 2, aX.node);
}else if(b->prev == NULL && b->next == a){
bX = extractNode(head, b);
listInsertAsIndex(head, 2, bX.node);
}else if(a->next == b){
aX = extractNode(head, a);
listInsertAsIndex(head, aX.index +1, aX.node);
}else if(b->next == a){
bX = extractNode(head, b);
listInsertAsIndex(head, bX.index +1, bX.node);
}else{
aX = extractNode(head, a);
bX = extractNode(head, b);
if(aX.index < bX.index){
listInsertAsIndex(head, aX.index, bX.node);
listInsertAsIndex(head, bX.index +1, aX.node);
}else{
listInsertAsIndex(head, bX.index, aX.node);
listInsertAsIndex(head, aX.index, bX.node);
}
}
}

关于c - 双链表: swapping function doesn't always work,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59216399/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com