链表的回收
众所周知,在堆区开辟的空间,需要由程序员自己释放。
而我们初始化链表,建立链表,对其进行插入、删除、查找等操作后,动态开辟的空间并没有被释放掉,
所以我们写一个链表回收的函数。
由于链表是由指针链起来的,很容易出现断链,
所以我们需要借助一个临时指针变量ret,来帮助我们进行逐点回收。
先看一个小例子:
int a = 10;
int b = 20;
int* pa = &a;
int* p = pa;
cout << pa << endl;
cout << p << endl;
pa = &b;
cout << pa << endl;
cout << p << endl;
这里的输出是:
由此我们可以得知:
使用指针进行赋值运算,赋的是指针指向的地址。
即使另一个指针变了,
被赋值的那个指针仍然指向开头的那块内存空间。
那如果这样写:
int a = 10;
int b = 20;
int* pa = &a;
int*& p = pa;
cout << pa << endl;
cout << p << endl;
pa = &b;
cout << pa << endl;
cout << p << endl;
由于p是pa的引用,
所以不管pa变到哪里,他们会指向同一块空间。
代码:
void LinkedListFree(LinkedList& L)
{
cout << "执行释放函数" << endl;
Node* ret;
do
{
ret = L;
L = L->next;
free(ret);
} while (L != NULL);
if (L == NULL)
{
cout << "执行完毕" << endl;
}
}
首先创造一个临时变量ret,
它先指向L,
再让L指向下一个元素;
一开始我用的while循环,
但是使用while有一个弊端:对仅有头结点的空链表需要进行分支语句。
所以我采用了do...while循环,让程序至少执行一次。
第一次直接释放第一个结点,
直到最后一个结点是NULL。
再来看形参,
因为我们需要改变实参,
所以必须使用引用。
测试代码:
int main()
{
cout << "请输入单链表的数据:";
LinkedList list,start;
list = LinkedListCreatT();
LinkedListDelete(list, 3);
for (start = list->next; start != NULL; start = start->next)
{
cout << start->data<<endl;
}
if (list != NULL)
{
cout << "链表未进行释放" << endl;
}
LinkedListFree(list);
if (list == NULL)
{
cout << "链表已释放完毕" << endl;
}
return 0;
}
运行截图:
成功。