C语言,链表中遇到棘手问题
/*
2014年8月10日15:20:06
单链表
*/
# include
# include
typedef struct Node
{
int data;
struct Node * pNext;
}NODE, * PNODE;
PNODE Createlist(void);
void Traverse(PNODE);
int length_list(PNODE);
int main(void)
{
int len;
PNODE pHead;
pHead = Createlist();
Traverse(pHead);
len = length_list(pHead);
printf("链表的长度为:%d", len);
return 0;
}
PNODE Createlist(void)
{
int len;
int val;
PNODE pHead = (PNODE)malloc(sizeof(NODE));
if (pHead == NULL)
{
printf("动态内存分配失败!");
exit(-1);
}
PNODE pTail = pHead;
pTail->pNext = NULL;
printf("请输入要创建的节点个数:___\b\b\b");
scanf("%d", &len);
for (int i=0; i
{
printf("请输入第%d个节点的值:",i+1);
scanf("%d", &val);
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if (NULL == pNew)
{
printf("动态内存分配失败!");
exit(-1);
}
pNew->data = val;
pTail->pNext = pNew;
pNew->pNext = NULL;
pTail = pNew;
}
return pHead;
}
void Traverse(PNODE pHead)
{
while (pHead->pNext != NULL)
{
printf("%d ", pHead->pNext->data);
pHead->pNext = pHead->pNext->pNext;
}
return;
}
int length_list(PNODE pHead)
{
int i = 0;
PNODE p = pHead->pNext;
while (p != NULL)
{
i = i + 1;
p = p->pNext;
}
return i;
}
这是一个链表程序,其中:void Traverse(PNODE pHead)
{
while (pHead->pNext != NULL)
{
printf("%d ", pHead->pNext->data);
pHead->pNext = pHead->pNext->pNext;
}
return;
}这段程序会导致函数length_list()出错。
当把Traverse函数程序改为:void traverse_list(PNODE pHead)
{
PNODE p = pHead->pNext;
while (NULL != p)
{
printf("%d ", p->data);
p = p->pNext;
}
return;
},这样的话,length_list()函数就能够给出正确的答案。
那么为什么用 pHead->pNext不行,而需要再定义一个指针变量p来存储pHead->pNext?
我在别的程序上也曾遇到过这样的问题。觉得不能再忽略了
------解决方案--------------------
遍历不应该改变链表,而你在Traverse遍历的时候改变了链表头的指向,也就是这句:
pHead->pNext = pHead->pNext->pNext;
循环结束了以后,pHead的pNext等于NULL了,链表变成了空链表。
再定义一个指针变量p来存储pHead->pNext,这样就不会改变main函数里的pHead,也就不会改变链表。
你可以将Traverse()和length_list()换个位置,先求长度再遍历:
len = length_list(pHead);
Traverse(pHead);
这样结果就正确了,证明你在Traverse时将链表变为了空链表。。。
------解决方案--------------------
phead虽然是值传递,但对它的->操作却是实在的指针操作,改变的是实际内存的地址
void Traverse(PNODE pHead)
{
while (pHead->pNext != NULL)
{
printf("%d ", pHead->pNext->data);
pHead = pHead->pNext;//把代码改成这样看看,改变phead的值可以,但改变phead->指向的值会有问题。
}
return;
}
------解决方案--------------------
链表代码示例
http://pan.baidu.com/s/17yIcQ