2012-03-18 46 views
0

所以我在玩弄链表,试图让我的大脑围绕在他们身上,并且我决定为列表中的每个节点添加“序数”值。这样,我可以通过序号而不是价值来删除,并且稍后再做一些其他很酷的事情。重置链接列表序号

只有当我从列表中删除一个元素时,所有的序号才会被击晕(相当明显),所以我认为“好吧,我只是在不同的函数中运行列表,重新设置所有的序号的序号“。从技术上讲,我可以在被删除的元素上启动这个函数,并将其从该节点的序号中传递出来以节省时间,因为之前的节点应该是未触及的,但现在我以不那么优雅的方式来做,因为我这样说。

“你的问题是什么?”。我知道你会问这个! “继续吧!”我知道你会这么说!

测试程序,我可以链接到或包含在这里,只是创建一个5个节点的列表,删除第三个节点,然后添加一个节点到最后。

预期输出是:DEBUG: resetting ordinals: 0 1 2 3 4

实际的输出是:DEBUG: resetting ordinals: 1 2 4 5 5

所以,没有任何废话少说,下面是我的问题:为什么是我的预期不同的实际输出?

void ll_fix(node_t* list) 
{ 
    node_t* root = list; 
    int ordinal = 0; 
    printf("DEBUG: resetting ordinals: "); 
    while(list->next != NULL) 
    { 
    list->ordinal = ordinal; 
    list = (node_t*)list->next; 
    printf("%d ",list->ordinal); 
    ordinal++; 
    } 
    printf("%d\n",list->ordinal); 
    list = root; // rewind the list 
} 
+0

好点,编辑预期输出(代码复制粘贴,所以它是真正的代码)。 – 2012-03-18 21:52:58

回答

2

您在更改之前正在打印序号。所以你看到以前的值。

大概应该是:

list->ordinal = ordinal; 
printf("%d ",list->ordinal); 
list = (node_t*)list->next; 
ordinal++; 

这虽然不会改变最后的价值,更好的解决方法是:

while(list != NULL) { // as per wildplasser comment, I moved the check to the beginning 
    list->ordinal = ordinal; 
    printf("%d ",list->ordinal); 
    ordinal++; 
    list = list->next; 
} 
+0

仔细一看,我正在打印“list-> ordinal”并更改“序数”。我想我应该对变量进行不同的命名,以避免混淆。 – 2012-03-18 21:54:56

+0

您在打印'list-> ordinal'之前移到下一个'参见我的示例。 – MByD 2012-03-18 21:55:33

+0

@ChrisBrowne你正在改变'list',所以'list-> ordinal'不是你刚刚设置的。 +1,很好被发现。 – cnicutar 2012-03-18 21:56:05

1

您正在设置序和印刷

之间,该列表指针
while(list->next != NULL) 
{ 
    list->ordinal = ordinal; 
    list = (node_t*)list->next; 
    printf("%d ",list->ordinal); 
    ordinal++; 
} 

所以你打印错误的值。此外,“倒回列表”是多余的,因为list是一个局部变量,它不影响函数外的任何东西。

list = root; // rewind the list 
+0

它通过引用传递,所以倒带不是多余的。 – 2012-03-18 21:58:32

+0

不,你是通过值传递一个指针,而不是通过引用的节点。所以你可以修改节点,但不能传递指针。 – 2012-03-18 22:00:29

+0

你说得对。指针的值。我可以安全地从我的代码中删除“倒带”位。谢谢! – 2012-03-18 22:01:56

0

你是不是在while环路测试取消引用它next之前检查listNULL。这可能会导致分段错误。我会做这样的事情:

while(list != NULL) 
    { 
    list->ordinal = ordinal; 
    printf("%d ",list->ordinal); 
    ordinal++; 
    list = list->next; 
    } 

这应该给你的输出:

DEBUG: resetting ordinals: 0 1 2 3 4 
0

您检查 - >下一个指针,而你应该检查当前元素。

void ll_fix(node_t *list) 
{ 
    node_t *tmp; 
    int ordinal = 0; 
    printf("DEBUG: resetting ordinals:"); 
    for (tmp=list; tmp; tmp = tmp->next) 
    { 
    tmp->ordinal = ordinal++; 
    printf(" %d", tmp->ordinal); 
    } 
    printf("\n"); 
}