【发布时间】:2019-12-06 15:54:24
【问题描述】:
我已经编写了这段代码并且通常运行良好,但是当我们到达i == 74 列表的元素是4 - 11 - 18 - 4 - 10 - 18 - 17 - 22 - 14 - 29 和swapNodes() 函数的点时,尝试在 main 中运行这些特定的行必须用键 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==4 和b==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;
}
}
【问题讨论】:
-
交换函数不应该只交换节点中的键吗?
-
我没有仔细查看您的代码,但
swapNodes函数对我来说看起来非常复杂。您确定列表创建工作正常吗? -
好吧,我只能交换密钥,但此时我需要交换节点本身。如果将来我决定在每个节点中存储更多信息怎么办?我将不得不重写一个新的交换函数(就像我必须与大多数其他函数一样)
-
我知道交换函数写得很糟糕,但现在我想找出导致该错误的原因。我还在关于函数本身的问题的结尾写了这篇文章
-
@ggorlen 我重写了函数,但问题仍然存在。我已经更新了代码