重置链表序号

时间:2012-03-18 21:47:25

标签: c linked-list

所以我正在玩链接列表,试图绕过它们,我决定在列表中的每个节点上添加“序数”值。这样,我可以通过序数而不是值来删除,并在以后做一些其他很酷的东西。

只有当我从列表中删除一个元素时,所有的序数都会被抛出(很明显,那个),所以我想“好吧,我只是在另一个函数中运行列表,重置所有的顺序“。从技术上讲,我可以在已删除的元素上启动此函数,并在该节点的序号中传递它以节省时间,因为之前的节点应该不受影响,但是现在我这样做的方式不那么优雅,因为我这么说。

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

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

预期输出为: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
}

4 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:1)

您正在设置序号和打印之间移动列表指针

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

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

list = root; // rewind the list

答案 2 :(得分:0)

listNULL循环测试中为next取消引用之前,您没有检查while while(list != NULL) { list->ordinal = ordinal; printf("%d ",list->ordinal); ordinal++; list = list->next; } 。这可能导致分段错误。我会做这样的事情:

DEBUG: resetting ordinals: 0 1 2 3 4

这应该给你输出:

{{1}}

答案 3 :(得分: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" );
}