链式描述线性表(C++实现)
在链式描述中,线性表的元素在内存中的存储位置是随机的,每个元素都有一个明确的指针或链指向下一个元素的位置
chain类
在此使用单向链表实现了线性表,其中最后一个节点的指针域为NULL,即它用单向链接的一组节点实现线性表
template<class T>
class chain : public linearList<T>{
public:
chain(int initialCapacity = 10);
chain(const chain<T> &);
~chain();
bool empty() const { return listSize == 0; }
int size() const { return listSize; }
T& get(int theIndex) const;
int indexOf(const T &theElement) const;
void erase(int theIndex);
void insert(int theIndex,const T &theElement);
void output(std::ostream &out) const;
private:
void checkIndex(int theIndex) const;
chainNode<T> *firstNode;
int listSize;
};
构造函数
在构造函数中创建一个空链表,即令第一个节点指针firstNode的值为NULL
template<class T>
chain<T>::chain(int initialCapacity) {
if (initialCapacity < 1) {
ostringstream s;
s << "Initial capacity = " << initialCapacity << " Must be > 0";
throw illegalParameterValue(s.str());
}
firstNode = NULL;
listSize = 0;
}
复制构造函数要复制链表theList的每一个节点:
template<class T>
chain<T>::chain(const chain<T> &theList) {
listSize = theList.listSize;
if (listSize == 0) {
firstNode = NULL;
return;
}
chainNode<T> *sourceNode = theList.firstNode;
firstNode = new chainNode<T>(sourceNode->element);
sourceNode = sourceNode->next;
chainNode<T> *targetNode = firstNode;
while (sourceNode != NULL) {
targetNode->next = new chainNode<T>(sourceNode->element);
targetNode = targetNode->next;
sourceNode = sourceNode->next;
}
targetNode->next = NULL;
}
析构函数
析构函数要逐个清除链表的节点,实现的策略是重复清除链表的首元素节点,直到链表为空
template<class T>
chain<T>::~chain() {
while (firstNode != NULL) {
chainNode<T> *nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
基本方法
get方法在链表中,寻找索引为theIndex的元素,必须从第一个节点开始,跟踪链域next直至找到所需的元素节点指针
template<class T>
T& chain<T>::get(int theIndex) const {
checkIndex(theIndex);
chainNode<T> *currentNode = firstNode;
for (int i = 0; i<theIndex; i++)
currentNode = currentNode->next;
return currentNode->element;
}
indexOf方法搜索链表,寻找元素
template<class T>
int chain<T>::indexOf(const T &theElement) const {
chainNode<T> *currentNode = firstNode;
int index = 0;
while (currentNode != NULL && currentNode->element != theElement) {
currentNode = currentNode->next;
index++;
}
if (currentNode == NULL) {
return -1;
}
return index;
}
erase方法删除索引为theIndex的元素,要考虑三种情况:
- listSize < 0 && listSize >= listSize,即listSize在无效范围
- 删除非空表的第0个元素节点
- 删除其他元素节点
template<class T>
void chain<T>::erase(int theIndex) {
checkIndex(theIndex);
chainNode<T> *deleteNode;
if (theIndex == 0) {
deleteNode = firstNode;
firstNode = firstNode->next;
} else {
chainNode<T> *p = firstNode;
for (int i = 0; i < theIndex - 1; i++)
p = p->next;
deleteNode = p->next;
p->next = p->next->next;
}
listSize--;
delete deleteNode;
}
insert方法插入和删除的过程相似,在链表中索引为theIndex的位置上插入一个新元素,要首先找到索引为theIndex-1的元素节点,然后在该节点之后插入新元素节点
template<class T>
void chain<T>::insert(int theIndex, const T &theElement) {
if (theIndex < 0 || theIndex > listSize) {
ostringstream s;
s << "index = " << theIndex << " size = " << listSize;
throw illegalIndex(s.str());
}
if (theIndex == 0) {
firstNode = new chainNode<T>(theElement,firstNode);
} else {
chainNode<T> *p = firstNode;
for (int i = 0;i < theIndex - 1; i++)
p = p->next;
p->next = new chainNode<T>(theElement,p->next);
}
listSize++;
}
output方法用于输出链表
template<class T>
void chain<T>::output(ostream &out) const {
for (chainNode<T>* currentNode = firstNode;currentNode != NULL; currentNode = currentNode->next) {
out << currentNode->element << " ";
}
}
template<class T>
ostream& operator<<(ostream &out,const chain<T> &x) {
x.output(out); return out;
}
迭代器类
对于单链表,定义了一个向前迭代器
template<class T>
class iterator {
public:
iterator(chainNode<T>* theNode = NULL) { node = theNode; }
T& operator*() const { return node->element; }
T* operator->() const { return &node->element; }
iterator& operator++() { node = node->next; return *this; }
iterator& operator++(int) { iterator old = *this; node = node->next; return old; }
bool operator!=(const iterator right) const { return node != right.node; }
bool operator==(const iterator right) const { return node == right.node; }
protected:
chainNode<T> *node;
};
链式描述线性表(C++实现)的更多相关文章
- c++实验3 链式存储线性表
1.线性表链式存储结构及基本操作算法实现 (1)单链表存储结构类的定义: #include <iostream> using namespace std; template <cla ...
- java哈希表(线性探测哈希表。链式哈希表)
哈希表(散列表) 通过哈希函数使元素的存储位置与它 的关键码之间能够建立一一映射的关系,在查找时可以很快找到该元素. 哈希表hash table(key,value) 的做法其实很简单,就是把Key通 ...
- 数据结构 链式哈希表(Hash Table)的接口定义与实现分析(完整代码)
链式哈希表的接口定义 关于哈希表与链式哈希表的描述可以参阅:http://www.cnblogs.com/idreamo/p/7990860.html 链式哈希表的操作与属性有:初始化.销毁.插入元素 ...
- [C++]使用vector描述线性表定义及基本操作
#ifndef VECTORLIST_H #define VECTORLIST_H #include<iostream> #include"linearlist.h" ...
- C 线性表的链式存储实现及插入、删除等操作示例
一.链式存储的优势 线性表的存储可以通过顺序存储或链式存储实现,其中顺序存储基于数组实现(见本人上一篇博客),在进行插入删除等操作时,需对表内某一部分元素逐个移动,效率较低.而链式结构不依赖于地址连续 ...
- 队列链式存储 - 设计与实现 - API函数
队列相关基础内容参我的博文:队列顺序存储 - 设计与实现 - API函数 队列也是一种特殊的线性表:可以用线性表链式存储来模拟队列的链式存储. 主要代码: // linkqueue.h // 队列链式 ...
- PHP数据结构之三 线性表中的单链表的PHP实现
线性表的链式存储:用一组任意的存储单元存储线性表中的数据元素.用这种方法存储的线性表简称线性链表. 链式存储线性表的特点:存储链表中结点的一组任意的存储单元可以是连续的,也可以是不连续的,甚至是零散分 ...
- 线性表之顺序存储结构(C语言动态数组实现)
线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链 ...
- 数据结构与算法(C/C++版)【绪论/线性表】
声明:数据结构与算法系列博文参考了<天勤高分笔记>.<王道复习指导>.C语言中文网.非商业用途,仅为学习笔记总结! 第一章<绪论> 一.基本概念及入门常识 /// ...
- 线性表接口的实现_Java
线性表是其组成元素间具有线性关系的一种线性结构,对线性表的基本操作主要有插入.删除.查找.替换等,这些操作可以在线性表的任何位置进行.线性表可以采用顺序存储结构和链式存储结构表示. 本接口的类属于da ...
随机推荐
- IT工具知识-09:OpenWrt设置旁路由
0.使用背景 设备:N1 固件:filppy打包的60+ 1.使用方法 1.1知道主路由的IP地址(例如192.168.1.1) 1.2在OpenWrt管理界面下进行设置 进入OpenWrt管理界面 ...
- Qt之如何创建并显示一个柱状图
创建一个简单的柱状图 第一步:创建一个QBarSet对象:QBarSet类代表条形图中的一组条形. QBarSet *set0 = new QBarSet("Jane"); QBa ...
- 前端基础复习之HTML
1.web基础知识 1 1.Web基础知识 2 1.Internet 3 1.简介 4 Internet 实际上就是由计算机所组成的网络结构 5 6 服务: 7 1.Telnet 8 远程登录 9 2 ...
- Python之路径处理
路径处理,需导入 os包 1 import os # 导入 os 包 2 3 """获取运行脚本文件夹的路径""" 4 current_di ...
- JAVA获取MultipartFile文件的MD5
Java获取文件的MD5,核心都是通过JAVA自带的MessageDigest类来实现. 获取文件MD5值主要分为三个步骤: 第一步获取文件的byte信息, 第二步通过MessageDigest类进行 ...
- vs调试导入功能时莫名自动结束调试
新装了vs2022,默认下图所示的地方打勾,导致调试文件导入功能时触发了自动结束调试,真是坑爹~~
- 记录一次mybatis pagehelper count order by 不生效
https://sample.blog.csdn.net/article/details/119216433?spm=1001.2101.3001.6650.5&utm_medium=dist ...
- .bat 脚本替换文件内容
rem 定义变量延迟环境,关闭回显 @echo off&setlocal enabledelayedexpansion rem 读取a.txt所有内容 for /f "eol=* t ...
- .NET中委托性能的演变
.NET中的委托 .NET中的委托是一项重要功能,可以实现间接方法调用和函数式编程. 自.NET Framework 1.0起,委托在.NET中就支持多播(multicast)功能.通过多播,我们可以 ...
- Masa Framework源码解读-02缓存模块(分布式缓存进阶之多级缓存)
序言 今天这篇文章来看看Masa Framework的缓存设计,上一篇文章中说到的MasaFactory的应用也会在这章节出现.文章中如有错误之处还请指点,咱们话不多说,直入主题. Masa Fr ...