标题不言自明。下面是我为此目的编写的函数:
void wipeLoneCells()
{
cell *tmp;
tail = head;
while (1)
{
if (head == tail && !tail->flag)
{
head = head->next;
free(tail);
tail = head;
continue;
}
tmp = tail->next;
/***/ if (tmp->next == NULL && !tmp->flag)
{
tail->next = NULL;
free(tmp);
break;
}
else if (!tmp->flag)
{
tail->next = tmp->next;
free(tmp);
continue;
}
tail = tail->next;
}
}
列表的头和尾是全局的,并且在调用此函数时构建列表,其中头指向第一个节点,尾指向最后一个节点(其下一个节点为NULL)。我几乎可以肯定我的链表是正确构建的,因为我可以打印它们而没有错误。有时这个函数可以完美地工作,有时它会在标有星号的行处导致访问冲突。我知道这不是完全错误的,因为当我得到我想要的结果时,它不会产生错误,尽管我经常得到错误,所以一定有什么我忽略了。提前感谢您的帮助。
编辑:这是固定代码:
void wipeLoneCells()
{
cell *tmp;
tail = head;
while (1)
{
if (head == tail && !tail->flag)
{
head = head->next;
free(tail);
tail = head;
continue;
}
tmp = tail->next;
if (tmp->next == NULL && !tmp->flag)
{
tail->next = NULL;
free(tmp);
break;
}
else if (tmp->next == NULL)
{
tail = tmp;
break;
}
else if (!tmp->flag)
{
tail->next = tmp->next;
free(tmp);
continue;
}
tail = tail->next;
}
}
如果
tmp = tail->next;
是NULL
?下一行试图解引用NULL
指针,这会导致未定义的行为—可能导致崩溃。
您应该检查这种情况并采取适当的措施。
单链表中正确的deleteitem()
如下:
您可以避免递归并提出迭代版本(尝试一下,但如果需要帮助请告诉我)。我不会在这种情况下使用while(1)
!
typedef struct node {
int data;
struct node *next;
}NODE;
/*
(1) deleting head
delete element and adjust head pointer
(2) deleting tail
delete element and adjust tail pointer
(3) one element list
if data is the data for the only element
then delete the list and set head and tail
pointers to NULL
(4) all the other cases
traverse through the list and hold the
previous pointer. delete element and adjust
the next pointers.
(5) if not the above cases, then element not
present.. do nothing..
*/
void deleteitem(int data)
{
printf("%s: %d - ", __FUNCTION__, data);
NODE *cur = head;
NODE *prev = cur;
NODE *temp = NULL;
if (head == NULL) {
assert (tail == NULL);
printf("Empty list n");
return;
}
if (head->data == data) {
temp = head;
// one element list
if (head == tail)
head = tail = NULL;
else
// list has more than one element
head = head->next;
printf("%d n", temp->data);
free(temp);
deleteitem(data);
return;
}
while (cur != NULL) {
if (cur->data == data) {
if (cur == tail) {
tail = prev;
}
prev->next = cur->next;
printf(" %d deletedn", cur->data);
free(cur);
assert(tail->next == NULL);
deleteitem(data);
return;
}
prev =cur;
cur = cur->next;
}
printf(" %d not foundn", data);
return;
}