c语言 - 这里的"tempPtr"不是多余的吗?( 链表 )



我正在练习链表,这是我们的讲师从Pearson的一本书中提供给我们的代码。

struct listNode {
char data;
struct listNode *nextPtr;
};
typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;

char delete( ListNodePtr *sPtr, char value )
{
ListNodePtr previousPtr;
ListNodePtr currentPtr;
ListNodePtr tempPtr;
/* delete first node */
if ( value == ( *sPtr )->data ) {
tempPtr = *sPtr;
*sPtr = ( *sPtr )->nextPtr;
free ( tempPtr );
return value;
}
else{
previousPtr = *sPtr;
currentPtr = ( *sPtr )->nextPtr;
/* loop to find correct location in the list */
while ( currentPtr != NULL && currentPtr->data != value ) {
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
/* delete node at currentPtr */
if ( currentPtr != NULL ) {
tempPtr = currentPtr;
previousPtr->nextPtr = currentPtr->nextPtr;
free ( tempPtr );
return value;
}       
}
return '';
}

我不明白为什么我需要使用"tempPtr"。我不能就这么做吗:

/* delete first node */
if ( value == ( *sPtr )->data ) {
*sPtr = ( *sPtr )->nextPtr;
free ( *sPtr );
return value;
}

if ( currentPtr != NULL ) {
previousPtr->nextPtr = currentPtr->nextPtr;
free ( currentPtr );
return value;
}   

(传递给delete函数的是main中定义的LinkedListPtr对象,并通过引用传递。它负责保存列表中第一个元素的地址。(

简化版本:


struct listNode {
struct listNode *next;
char data;
};
char delete(struct listNode  **pp, char value )
{
struct listNode  *this;
while ((this = *pp)) {
if (this->data != value) { pp= &this->next; continue; }
*pp = this->next; // this is why you need a temp pointer
free(this);       // ::because you want to free() it
return value;     // nonsense return
}
return ''; // nonsense return
}

和一个小型驱动程序测试功能:


#include <stdio.h>
#include <stdlib.h>
struct listNode {
struct listNode *next;
char data;
};
struct listNode *root = NULL;
void push(char val)
{
struct listNode *new;
new = malloc (sizeof *new);
new->data = val;
new->next = root;
root = new;
}
void print(struct listNode *p)
{
for (; p; p = p->next) {
printf(" %c", p->data);
}
printf("n");
}
int main(void)
{
push('o');
push('l');
push('l');
push('e');
push('H');
print(root);
delete( &root, 'o');
print(root);
delete( &root, 'H'); // <<-- test if we can delete the **first** node of the chain
print(root);
return 0;
}

我不能直接做吗:

if ( value == ( *sPtr )->data ) {
*sPtr = ( *sPtr )->nextPtr;           # this line changes *sPtr value
free ( *sPtr );                       # frees `(*sPtr)->nextPtr`, not the old `*sPtr`
return value;
}

不,这不是等价的。在您的代码中,您释放的是(*sPtr)->nextPtr,而不是*sPtr。您想要释放*sPtr的值,并将其更改为下一个指针的值。因此,您必须有一个临时值——指针或新值。替代原始代码,您可以保存nextPtr并释放当前指针,然后将其分配给下一个:

if ( value == ( *sPtr )->data ) {
tempPtr = (*sPtr)->nextPtr;
free(*sPtr);
*sPtr = tempPtr;
return value;
}

if ( currentPtr != NULL ) {
previousPtr->nextPtr = currentPtr->nextPtr;
free ( currentPtr );
return value;
}

当然,该代码是等效的。

相关内容

  • 没有找到相关文章

最新更新