【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 }
时间: 2024-10-14 13:07:02

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

【Weiss】【第03章】练习3.2

[练习3.2] 给你一个链表L和另一个链表P,它们包含以升序排列的整数.操作printlots(L,P)将打印L中那些由P所指定的位置上的元素. 例如,如果p=1,3,4,6,那么,L的第一.第三.第四和第六个元素被打印出来. 你应该只使用基本的表操作,该过程的运行时间是多少? Answer: 老样子,先放折叠的实测代码. 1 #include <iostream> 2 #include <string> 3 #include "linklist.cpp" 4

异步编程系列第03章 自己写异步代码

p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提高下英文,用我拙劣的英文翻译一些重要的部分,纯属娱乐,简单分享,保持学习,谨记谦虚. 如果你觉得这件事儿没意义翻译的又差,尽情的踩吧.如果你觉得值得鼓励,感谢留下你的赞,愿爱技术的园友们在今后每一次应该猛烈突破的时候,不选择知难而退.在每一次应该独立思考的时候,不选择随波逐流,应该全力以赴的时候,不选择尽力而

第十五章 链表

/** 数组与链表的区别:数组易随机访问,链表易插入和删除 链表组成:储存数据元素的数据域,储存下一结点地址的指针域 链表易于插入与删除 lists 的用法????????????????????? *///建立一个图书链表 #include<iostream> #include <string> using namespace std; struct book //第一步: 用于建立节点. class 默认为私有 struct 默认为公有 //节点组成:①数据域 ②指针域(*ne

第03章-VTK系统概述(1)

[译者:这个系列教程是以Kitware公司出版的<VTK User's Guide -11th edition>一书作的中文翻译(出版时间2010年,ISBN: 978-1-930934-23-8),由于时间关系,我们不能保证每周都能更新本书内容,但尽量做到一周更新一篇到两篇内容.敬请期待^_^.欢迎转载,另请转载时注明本文出处,谢谢合作!同时,由于译者水平有限,出错之处在所难免,欢迎指出订正!] 本章旨在介绍VTK系统的总体概述,并讲解运用C++.Java.Tcl和Python等语言进行VT

&lt;&lt;Python基础教程&gt;&gt;学习笔记 | 第03章 | 字符串

第03章: 使用字符串 ------ 支持的操作 索引 切片 增加元素 删除元素 更新元素 查找元素(检查某个元素是否是序列中的一员) 序列长度 最大值 最小值 其他内建函数 >>> website='http://www.python.org' >>> website[-3:]='com' #此操作不合法,因为字符串是不变,不能做修改 Traceback (most recent call last): File "<pyshell#162>&q

JavaScript权威指南第03章 类型、值和变量

类型.值和变量 数据类型分类: 原始类型(primitive type):数字 字符串 布尔值 null undefined 对象类型(object type): 对象是属性的集合,每个属性都由"名/值"对构成. javascript解释器有自己的内存管理机制,可以自动对内存进行垃圾回收. 3.1数字 javascript不区分浮点和整型,所有的数字都是按照浮点型处理. 3.1.1整型直接量 3.1.2浮点型直接量 3.1.3算数运算 3.1.4二进制浮点数和四舍五入错误 当进行小数进

JavaScript权威指南第03章 类型、值和变量(2)

题目链接:https://oj.leetcode.com/problems/set-matrix-zeroes/ Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. 一个个找肯定会超时,我们可以分别用一个行向量和一个列向量进行维护.这样O(m*n) 能出来 class Solution { public: void setZeroes(vector<vector

第03章-VTK系统概述(3)

[译者:这个系列教程是以Kitware公司出版的<VTK User's Guide -11th edition>一书作的中文翻译(出版时间2010年,ISBN: 978-1-930934-23-8),由于时间关系,我们不能保证每周都能更新本书内容,但尽量做到一周更新一篇到两篇内容.敬请期待^_^.欢迎转载,另请转载时注明本文出处,谢谢合作!同时,由于译者水平有限,出错之处在所难免,欢迎指出订正!] [本节对应原书中的第29页至第39页] 3.2创建VTK应用程序 本章内容包括利用Tcl,C++

groovy入门 第03章 字符串和正则表达式

字符串和正则表达式 3.1字符串字面值 可以使用单引号.双引号.三引号来封装字符串. 使用单引号封装的字符串就是字符串序列本身. 使用双引号可以嵌套单引号,并可以将表达式包含进来. 使用三引号可以包含多行文本. def age=25 'My age is ${age}'            // 输出My age is ${age} "My age is ${age}"           //输出My age is 25 """'My age is $