StaticLinkList
文章目录
- 1 静态单链表的出现原因
- 2 静态单链表的实现思路
- 3 继承关系图
- 4 代码实现
- 5 StaticLinkList需要增加析构函数吗
1 静态单链表的出现原因
如果需要频繁的删除元素,并且数据元素的最大个数固定,我们该怎么选择线性表呢?
很明显,当需要频繁的删除元素时,使用单链表是明智的选择。但是目前的单链表却有如下的缺陷:当我们长时间使用单链表对象频繁增加和删除元素时,可能会导致堆空间产生大量的内存碎片,导致系统运行缓慢。
由于数据元素的最大个数固定,我们可以设计一种新的线性表:
在单链表内部增加一片预留的空间,所有的Node对象都在这片空间中动态创建和动态销毁。
2 静态单链表的实现思路
- 通过模板定义静态单链表类(StaticLinkList)。
- 在类中定义固定大小的空间(unsigned char [])。
- 重写create和destroy函数,改变内存的分配和归还方式。
- 在Node类中重载operator new,用于在指定的内存上创建对象。
3 继承关系图
4 代码实现
StaticLinkList
#ifndef STATICLINKLIST_H
#define STATICLINKLIST_H#include "Linklist.h"namespace LemonLib {template < typename T, int N >
class StaticLinkList : public LinkList<T>
{protected:/* 由于模板的二阶段编译,所以这里我们必须采用这种方式使用父类中的类型 */typedef typename LinkList<T>::Node Node;unsigned char m_space[sizeof(Node)*N];int m_used[N];/* 为了能够在指定的内存空间上调用构造函数,所以我们需要重载Node的new操作符 */struct SNode : public Node{/** 虽然new操作符返回的为void*类型,但编译器会自动处理类型问题* 需要注意的是,当new操作符返回null时,编译器就不会自动调用构造函数*/void* operator new(unsigned int size, void* loc){(void)size; // 避免编译器发出警告return loc;}};Node* create(){Node* ret = NULL;for (int i=0; i<N; i++){if (m_used[i] == 0){ret = reinterpret_cast<Node*>(m_space) + i;ret = new(ret) SNode(); // 调用构造函数m_used[i] = 1;break;}}return ret;}void destroy(Node* pn){SNode* spn = dynamic_cast<SNode*>(pn); // static_cast用于有继承关系的对象指针之间的转换SNode* addr = reinterpret_cast<SNode*>(m_space);for (int i=0; i<N; i++){if (spn == (addr + i)){m_used[i] = 0;spn->~SNode(); // 调用析构函数break;}}}public:StaticLinkList(){for (int i=0; i<N; i++){m_used[i] = 0;}}int capacity(){return N;}
};
}#endif // STATICLINKLIST_H
main.cpp
#include <iostream>
#include "Object.h"
#include "Exception.h"
#include "List.h"
#include "Seqlist.h"
#include "Staticlist.h"
#include "Dynamiclist.h"
#include "Staticarray.h"
#include "DynamicArray.h"
#include "Linklist.h"
#include "Staticlinklist.h"using namespace std;
using namespace LemonLib;int main()
{StaticLinkList<int, 5> list;for (int i=0; i<5; i++){list.insert(0, i);}for (list.move(0); !list.end(); list.next()){cout << list.current() << endl;}return 0;
}
5 StaticLinkList需要增加析构函数吗
当前实现版本的StaticLinkList类并无析构函数,对于如下代码:
构造比较简单,不用多说。对于析构来说,会自动调用父类的析构函数。而父类的析构函数直接调用了clear函数,在clear中调用destroy函数释放申请的空间。那么,思考如下问题:clear函数调用的真的是子类的destroy函数吗?
构造函数和析构函数中不会发生多态,不管是直接调用还是间接调用,所调用的都是当前类中实现的版本。 所以对于以上分析的问题,会调用父类的destroy函数,这将导致delete释放的有可能不是堆空间,会造成程序的不稳定。在实际工程开发中,这个问题必须避免。那么,我们有必要为StaticLinkList增加析构函数:
~StaticLinkList(){this->clear();}
在子类析构函数中完成空间的释放,那么在父类的析构函数中就不会再重复释放空间,如上问题也就完美的解决了。
StaticLinkList相关推荐
- java静态链表_数据结构笔记:静态链表(C语言)
void CreateList(StaticLinkList *P)//创建一个静态链表 { int i; for(i=0;i此时并没有已占用空间,所以第一个节点中的指针(cur)的值为1,也就是说空 ...
- 典型问题分析(十五)
在经过一段时间的编写,我们的数据结构库已经有了一定的规模.那么我们之前编写的代码就没有一点 bug 吗?之前每个代码都是经过测试了的,因此阔能是没有 bug 的,但是我们还是来对它进行分析,看看究竟是 ...
- 静态链表的插入和删除
静态链表相当于是用一个数组来实现线性表的链式存储结构,在静态链表中操作的是数组. 结构体数组 一.静态链表的插入操作 静态链表的插入操作包含两部分,首先是获得空闲量的下标,程序代码如下; int ge ...
- 数据结构 - 静态单链表的实行(C语言)
静态单链表的实现 1 静态链表定义 静态链表存储结构的定义如下: /* 线性表的静态链表存储结构 */ #define MAXSIZE 1000 /* 假设链表的最大长度是1000 */ typede ...
- 《大话数据结构》读书笔记-线性表
写在前面:本文仅供个人学习使用.<大话数据结构>通俗易懂,适合整体做笔记输出,构建体系.并且文中很多图片来源于该书. 文章目录 3.2 线性表的定义 3.3 线性表的抽象数据类型 3.4 ...
- DualCircleList
文章目录 1 Linux内核链表介绍 1.1 移植Linux内核链表 1.1.1 Linux内核链表的位置及依赖 1.1.2 移植时的注意事项 1.2 Linux内核链表剖析 1.2.1 Linux内 ...
- DualLinkList
文章目录 1 单链表的缺陷 2 双向链表的实现 2.1 设计思路 2.2 双向链表的继承层次结构 2.3 DualLinkList的定义 2.4 双向链表的特点 3 代码实现 4 开放性问题 1 单链 ...
- CircleList
文章目录 1 循环链表的实现 1.1 什么是循环链表 1.2 循环链表的逻辑构成 1.3 循环链表的继承层次结构 1.4 循环链表的实现思路 1.5 循环链表的实现要点 2 代码实现 3 循环链表的应 ...
- SharedPointer
文章目录 1 继承关系类图 2 SharedPointer设计要点 3 代码实现 4 智能指针相关注意点 1 继承关系类图 2 SharedPointer设计要点 SharedPointer肯定是类模 ...
最新文章
- CMake命令之set_property和get_property
- 把Python的200个标准库分类整理了下,供参考
- go map并发写错误问题
- mysql集群mysql-cluster安装
- LeetCode : Binary Tree Paths
- android上最好的linux终端,如何在带有Termux的Android上使用Linux命令行 | MOS86
- Kali Linux 秘籍 第六章 漏洞利用
- 《软件建模与设计: UML、用例、模式和软件体系结构》一一3.2 设计验证和确认...
- 深度学习入门笔记(五):神经网络的学习
- vi/vim: 文件浏览和缓冲区浏览
- python的优点有哪些-Python为何这么火,究竟有哪些优势?
- Leetcode 931.下降路径最小和
- 动态代理 aop切面实现事务管理
- wps怎么生成html,wps如何自动生成页码 wps页码设置详细方法
- 修改注册表禁用谷歌浏览器提示保存密码
- NVIDIA显卡驱动更新方法
- 2021年中国百香果果汁进出口贸易分析:贸易逆差明显,越南是主要进口国[图]
- 倒计时 4天,COSCon'22 会议议程全览 精彩亮点抢鲜看!
- CHAR 和 VARCHAR 的区别?
- lepus mysql 复制监控_lepus 天兔监控Mysql部署
热门文章
- 列举ospf的5种报文类型_9种语言的应用场景,程序员的候选清单,你最看好哪一门语言...
- 【控制】《鲁棒控制-线性矩阵不等式处理方法》-俞立老师-第9章-时滞系统的分析和综合
- 2.14 向量化 Logistic 回归的梯度输出-深度学习-Stanford吴恩达教授
- 6.6 二分 K-Means 算法-机器学习笔记-斯坦福吴恩达教授
- 1.4 正规方程-机器学习笔记-斯坦福吴恩达教授
- 物联网云平台-贝壳物联入门详细使用方法
- 【树莓派】可能是最简单粗暴的树莓派搭建个人网站教程
- Qt中rcc工具简介
- 我的第一个Scrapy 程序 - 爬取当当网信息
- 入职五年回顾(十六) 2013年11月