我正在尝试为链接列表构建头部删除和尾部删除功能。
我已成功删除头部,但我的尾部删除功能实际上并没有删除尾部。
首先,如何创建链接列表:
typedef struct node
{
int data;
struct node *next;
} node;
typedef struct LinkedList
{
node *head;
node *tail;
} LinkedList;
node *createNode(int data)
{
node *new_node;
if ((new_node = malloc(sizeof(node))) == NULL)
return NULL;
new_node->data = data;
new_node->next = NULL;
return new_node;
}
LinkedList *createLinkedList(void)
{
LinkedList *LL;
if ((LL = calloc(1, sizeof(LinkedList))) == NULL)
return NULL;
return LL;
}
void tailInsert(LinkedList *LL, int data)
{
if (LL == NULL)
return;
if (LL->tail == NULL)
{
LL->head = LL->tail = createNode(data);
return;
}
LL->tail->next = createNode(data);
LL->tail = LL->tail->next;
}
这是两个功能:
这个不起作用:
int tail_Delete(LinkedList *list)
{
int retval;
node *temp;
if (list == NULL || list->head == NULL)
return EMPTY_LIST_ERR;
// if only one node
if (list->head->next == NULL)
{
retval = list->head->data;
free(list->head);
list->head = NULL;
list->tail = NULL;
return retval;
}
// make temp the node before the tail
for (temp = list->head; temp->next != list->tail; temp = temp->next)
;
retval = list->tail->data;
free(list->tail);
list->tail = temp;
return retval;
}
这个确实有效:
int head_delete(LinkedList *list)
{
int retval;
node *temp;
if (list == NULL || list->head == NULL)
return EMPTY_LIST_ERR;
retval = list->head->data;
temp = list->head->next;
free (list->head);
list->head = temp;
if (list->head == NULL)
list->tail = NULL;
return retval;
}
打印功能和主要:
void print_Linked_list(LinkedList *LL)
{
node *temp;
if (LL == NULL || LL->head == NULL)
return;
for (temp = LL->head; temp != NULL; temp = temp->next)
printf("%d%c", temp->data, (temp->next == NULL) ? '\n' : ' ');
}
int main(void)
{
LinkedList *LL;
int val;
LL = createLinkedList();
tailInsert(LL, 1);
tailInsert(LL, 2);
tailInsert(LL, 3);
print_Linked_list(LL);
val = tail_Delete(LL);
//val = head_delete(LL);
printf("%d\n", val);
print_Linked_list(LL);
return 0;
}
head_delete的输出:
1 2 3
Deleted node: 1
2 3
tail_delete的输出:
1 2 3
Deleted node: 3
1 2 3
这可能是一个简单的错误,但它们似乎实际上是等效的功能。
感谢您的帮助。
答案 0 :(得分:2)
执行temp->next
循环时,应该为for
指针赋值0。通过这个你指出这个元素是最后一个。
for (temp = list->head; temp->next != list->tail; temp = temp->next)
;
temp->next = 0; // <---
retval = list->tail->data;
答案 1 :(得分:1)
需要在尾部之前从节点管理尾部删除。如果你没有在列表中有一个后退指针(双重链接),那么你需要向前走到尾部。
未经测试,尾部删除(没有后退指针)应如下所示。
LinkedList *node = list->head;
LinkedList *next = node->next;
while(next != list->tail) { // walk to the end
node = next;
next = node->next;
}
// now node is the node before the tail and next is the tail
int retval = next->data;
free(next);
// this is why we needed to walk here
node->next = NULL;