在C上的一个简单的链接列表实现中,我找不到一行名为insert()的函数。 它需要一个字符并按字母顺序添加到链接列表。 该行是关于在列表为空时创建新节点。由于列表中只有一个节点,该行应该像我评论过的那样,我错了吗?
/****************************************************/
void insert( ListNodePtr *sPtr, char value ){
ListNodePtr newPtr;
ListNodePtr previousPtr;
ListNodePtr currentPtr;
newPtr = malloc( sizeof( ListNode) );
if( newPtr != NULL ){ //is space available
newPtr->data = value; //place value in node
newPtr->nextPtr = NULL; //node does not link to another node
previousPtr = NULL;
currentPtr = *sPtr; //indirection to startPtr
while( currentPtr != NULL && value > currentPtr->data ){
previousPtr = currentPtr; //walk to ...
currentPtr = currentPtr->nextPtr; //... next node
}
//insert new node at the beginning of the list
if( previousPtr == NULL ){
newPtr->nextPtr = *sPtr; /////////////////////////////////////////////// newPtr->nextPtr = NULL ???
*sPtr = newPtr;
}
else{ //insert new node between previousPtr and currentPtr
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
}
else
printf( "%c not inserted. No memory available.\n", value);
}//end-of insert
/*******************************************************/
main()中的typedef指令是;
typedef struct listNode ListNode;
typedef ListNode* ListNodePtr;
并在main()中调用函数insert(),就像这样;
insert( &startPtr, item);
在main();
中初始化startPointerListNodePtr startPtr = NULL;
答案 0 :(得分:3)
我想你忘记了一个案子。如果
,将标记您标记的行要理解第二种情况,请查看之前的代码:
while( currentPtr != NULL && value > currentPtr->data ){
previousPtr = currentPtr; //walk to ...
currentPtr = currentPtr->nextPtr; //... next node
}
条件value > currentPtr->data
在第二种情况下为真,因此您将到达previousPtr == NULL
和*sPtr != NULL
的行(包含其初始值,指向第一个节点的指针)列表)。
在第一种情况下,*sPtr
确实是NULL
,在第二种情况下,当使用NULL
并且最终只有一个字符时,您会错误地丢弃整个列表列表和内存泄漏。
答案 1 :(得分:1)
您正在将* sPtr传递给该函数。如果* sPtr指向非空列表中的节点,如果使用NULL而不是* sPtr,则将丢失对列表的引用。如果* sPtr为NULL,则行为相同。
你在暗示:
if( previousPtr == NULL ){
newPtr->nextPtr = NULL;
*sPtr = newPtr;
}
但如果* sPtr = Node1且列表为:
Node1->Node2->Node3
如果你想在Node1之前插入并使用你的实现
你将创建你的newPtr->指向NULL 然后设置* sPtr = newPtr并丢失原始列表
其他实现会将您的新节点添加到旧列表中。