【Weiss】【第03章】链表例程的一些修改

主要是,感觉原来的链表例程通过Node的分配形成了链表,但是没有自动消除Node的办法比较危险,一旦在clear()之前把链表赋了其它值就内存泄漏了。

所以改了析构函数,自动清理分配出来的内存。既然改了析构同时就要改拷贝合成与拷贝赋值。

然后还给链表加了个尾指针,否则每次插入都要O(N)的时间真的很蛋疼……改了以后就是O(1)了

栈、队列、双链表的到时候再改。

添加的构造函数、赋值函数、析构函数如下:

 1 //构造函数,这部分直接增加在链表内部
 2 public:
 3     //拷贝构造函数,深拷贝
 4     List<T>(const List<T>& another)
 5     {
 6         length = 0;
 7         front = rear = nullptr;
 8         if (another.length != 0)
 9             for (Node<T>* another_iter = another.front; another_iter != nullptr; another_iter = another_iter->next)
10                 //additem会自动调整length等变量
11                 additem(another_iter->data);
12     }
13     //析构函数
14     ~List<T>(){ clear(); }
15     //拷贝赋值函数
16     List<T>& operator=(const List<T>& another)
17     {
18         //首先判断传入参数是否与当前为同一链表,如是,则不进行操作直接返回
19         if (front != another.begin())
20         {
21             clear();
22             if (another.length != 0)
23                 for (Node<T>* another_iter = another.front; another_iter != nullptr; another_iter = another_iter->next)
24                     //additem会自动调整length等变量
25                     additem(another_iter->data);
26         }
27         return *this;
28     }

添加尾指针后,需要相应改变的包括:additem、remove、clear

additem:

 1 template <typename T> bool List<T>::additem(const T &item)
 2 {
 3     Node<T>* pnew = new Node<T>(item);
 4     if (length == 0)
 5         front = rear = pnew;
 6     else
 7     {//修改后直接尾指针往后接
 8         rear->next = pnew;
 9         rear = pnew;
10     }
11     ++length;
12     return true;
13 }

remove:

 1 template <typename T> bool List<T>::remove(const T &item)
 2 {
 3     if (length == 0)                    //先判断链表是否空避免front->data未定义
 4     {
 5         cout << "No data!" << endl;
 6         return false;
 7     }
 8     Node<T>* iter = find_prev(item);
 9     if (iter == nullptr && front->data != item)
10     {
11         cout << "Can not find!" << endl;
12         return false;
13     }
14     Node<T>* save;
15     if (front->data == item)
16     {//相应地注意尾指针的位置
17         if (length == 1)
18             rear = nullptr;
19         save = front;
20         front = front->next;
21         free(save);
22     }
23     else
24     {//相应地注意尾指针的位置
25         if (iter->next == rear)
26             rear = iter;
27         save = iter->next;
28         iter->next = iter->next->next;
29         free(save);
30     }
31 
32     --length;
33     return true;
34 }

clear:

 1 template <typename T> void List<T>::clear()
 2 {
 3     Node<T>* iter;
 4     while (front != nullptr)
 5     {
 6         iter = front;
 7         front = front->next;
 8         delete iter;
 9     }
10     front = nullptr;
11     rear = nullptr;    //尾指针也要赋空
12     length = 0;
13 }
原文地址:https://www.cnblogs.com/catnip/p/4345241.html