我的与链表有关的 c 程序有什么问题?
What's wrong with my c program concerned with linked list?
它只是一个用在与链表有关的c程序中的函数。
它的作用是从1,2,3,4,5,...,n这样的列表中挑出第m个数,放到第一位,一般情况下,原来的位置会被删除。
如果我糟糕的英语不能很好地解释我的想法,你可以在程序中得到它。
示例:
输入:7 2
输出:2 1 3 4 5 6 7
输入:7 6
输出:6 1 2 3 4 5 7
输入:7 8
输出:1 2 3 4 5 6 7
现在的问题是它没有正确地 运行 甚至根本没有 运行 当前者的数字小于后者时 one.It 只是出现了一个错误。
void movenode(SNODE *head, int m)
{
SNODE* t,* q;
t=head;
int len=0;
while(t->next!=NULL)
{
t=t->next;
len++;
}
//printf("%d",len);
if(!(m>len||m==0||m==1))
{
while(t->next->num!=m)
t=t->next;
//printf("%d",t->next->num);
q=t->next;
t->next=q->next;
free(q);
SNODE * T;
T = ( SNODE * ) malloc( sizeof( SNODE ) );
T->next=head->next;
head->next=T;
T->num=m;
}
}
您的代码有几处错误:
您想遍历列表两次,但不要在第一次遍历后重置迭代指针。这意味着您最终将取消引用 NULL
指针。
您应该决定 m
表示位置还是值。您的代码以某种方式使用了这两个定义,这是不一致的。
您既没有创建新节点,也没有删除旧节点。您只需在同一列表中重新定位现有节点。 (您可以删除旧节点并在列表的前面创建一个具有相同 num
的新节点,但更新指针可能更有效。)
你改变了列表的头部,但是调用代码不会知道这个改变,因为当你 [=73] 时你对 movenode
中 head
的更新丢失了=] 来自函数。您应该 return 新头部或通过引用传递头部,或者在您作为参考传递的列表周围编写一个包装器结构。
当你考虑你的问题时,你也不需要双循环。当您遍历列表时,跟踪位置并在满足条件时重新排序指针。如果你不能满足你的条件,m
超出范围,你什么都不做。
这是一个示例实现:
/*
* Move the m-th node in the list to the front. The index 0
* refers to the list's head. Returns 1 if a node was moved or
* 0 otherwise.
*/
int movenode(SNODE **head, int m)
{
SNODE **t = head;
if (m < 1) return 0; /* nothing to do! */
while ((*t)->next != NULL) {
if (m == 1) {
SNODE *p;
/* extract node */
p = (*t)->next;
(*t)->next = p->next;
/* insert at front */
p->next = *head;
*head = p;
return 1;
}
t = &(*t)->next;
m--;
}
return 0;
}
你这样称呼它:
movenode(&head, 1); /* swap first two nodes */
注意事项:
head
作为指向指针的指针传递,即通过引用传递。在你 return 之后, head
将持有新的头部,以便调用代码看到更新后的列表。
迭代器t
也是一个指向指针的指针。这就是节点提取工作的原因:您的列表是单链接的,没有指向前一个节点的指针。通过在列表中保留指向该节点的指针地址(最初为 head
)并查看下一个节点,您可以在提取节点时更新该指针。
因为迭代的时候看的是下一个节点,所以条件是m == 1
,而不是m == 0
。 m
在迭代过程中减少。您也可以保持递增计数(就像您对 len
所做的那样)并将其与 m
.
进行比较
函数returns 1或0,表示节点是否被移动
它只是一个用在与链表有关的c程序中的函数。 它的作用是从1,2,3,4,5,...,n这样的列表中挑出第m个数,放到第一位,一般情况下,原来的位置会被删除。 如果我糟糕的英语不能很好地解释我的想法,你可以在程序中得到它。
示例:
输入:7 2
输出:2 1 3 4 5 6 7
输入:7 6
输出:6 1 2 3 4 5 7
输入:7 8
输出:1 2 3 4 5 6 7
现在的问题是它没有正确地 运行 甚至根本没有 运行 当前者的数字小于后者时 one.It 只是出现了一个错误。
void movenode(SNODE *head, int m)
{
SNODE* t,* q;
t=head;
int len=0;
while(t->next!=NULL)
{
t=t->next;
len++;
}
//printf("%d",len);
if(!(m>len||m==0||m==1))
{
while(t->next->num!=m)
t=t->next;
//printf("%d",t->next->num);
q=t->next;
t->next=q->next;
free(q);
SNODE * T;
T = ( SNODE * ) malloc( sizeof( SNODE ) );
T->next=head->next;
head->next=T;
T->num=m;
}
}
您的代码有几处错误:
您想遍历列表两次,但不要在第一次遍历后重置迭代指针。这意味着您最终将取消引用
NULL
指针。您应该决定
m
表示位置还是值。您的代码以某种方式使用了这两个定义,这是不一致的。您既没有创建新节点,也没有删除旧节点。您只需在同一列表中重新定位现有节点。 (您可以删除旧节点并在列表的前面创建一个具有相同
num
的新节点,但更新指针可能更有效。)你改变了列表的头部,但是调用代码不会知道这个改变,因为当你 [=73] 时你对
movenode
中head
的更新丢失了=] 来自函数。您应该 return 新头部或通过引用传递头部,或者在您作为参考传递的列表周围编写一个包装器结构。
当你考虑你的问题时,你也不需要双循环。当您遍历列表时,跟踪位置并在满足条件时重新排序指针。如果你不能满足你的条件,m
超出范围,你什么都不做。
这是一个示例实现:
/*
* Move the m-th node in the list to the front. The index 0
* refers to the list's head. Returns 1 if a node was moved or
* 0 otherwise.
*/
int movenode(SNODE **head, int m)
{
SNODE **t = head;
if (m < 1) return 0; /* nothing to do! */
while ((*t)->next != NULL) {
if (m == 1) {
SNODE *p;
/* extract node */
p = (*t)->next;
(*t)->next = p->next;
/* insert at front */
p->next = *head;
*head = p;
return 1;
}
t = &(*t)->next;
m--;
}
return 0;
}
你这样称呼它:
movenode(&head, 1); /* swap first two nodes */
注意事项:
head
作为指向指针的指针传递,即通过引用传递。在你 return 之后,head
将持有新的头部,以便调用代码看到更新后的列表。迭代器
t
也是一个指向指针的指针。这就是节点提取工作的原因:您的列表是单链接的,没有指向前一个节点的指针。通过在列表中保留指向该节点的指针地址(最初为head
)并查看下一个节点,您可以在提取节点时更新该指针。因为迭代的时候看的是下一个节点,所以条件是
m == 1
,而不是m == 0
。m
在迭代过程中减少。您也可以保持递增计数(就像您对len
所做的那样)并将其与m
. 进行比较
函数returns 1或0,表示节点是否被移动