在链式描述中,线性表的元素在内存中的存储位置是随机的,每个元素都有一个明确的指针或链指向下一个元素的位置

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的元素,要考虑三种情况:

  1. listSize < 0 && listSize >= listSize,即listSize在无效范围
  2. 删除非空表的第0个元素节点
  3. 删除其他元素节点
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++实现)的更多相关文章

  1. c++实验3 链式存储线性表

    1.线性表链式存储结构及基本操作算法实现 (1)单链表存储结构类的定义: #include <iostream> using namespace std; template <cla ...

  2. java哈希表(线性探测哈希表。链式哈希表)

    哈希表(散列表) 通过哈希函数使元素的存储位置与它 的关键码之间能够建立一一映射的关系,在查找时可以很快找到该元素. 哈希表hash table(key,value) 的做法其实很简单,就是把Key通 ...

  3. 数据结构 链式哈希表(Hash Table)的接口定义与实现分析(完整代码)

    链式哈希表的接口定义 关于哈希表与链式哈希表的描述可以参阅:http://www.cnblogs.com/idreamo/p/7990860.html 链式哈希表的操作与属性有:初始化.销毁.插入元素 ...

  4. [C++]使用vector描述线性表定义及基本操作

    #ifndef VECTORLIST_H #define VECTORLIST_H #include<iostream> #include"linearlist.h" ...

  5. C 线性表的链式存储实现及插入、删除等操作示例

    一.链式存储的优势 线性表的存储可以通过顺序存储或链式存储实现,其中顺序存储基于数组实现(见本人上一篇博客),在进行插入删除等操作时,需对表内某一部分元素逐个移动,效率较低.而链式结构不依赖于地址连续 ...

  6. 队列链式存储 - 设计与实现 - API函数

    队列相关基础内容参我的博文:队列顺序存储 - 设计与实现 - API函数 队列也是一种特殊的线性表:可以用线性表链式存储来模拟队列的链式存储. 主要代码: // linkqueue.h // 队列链式 ...

  7. PHP数据结构之三 线性表中的单链表的PHP实现

    线性表的链式存储:用一组任意的存储单元存储线性表中的数据元素.用这种方法存储的线性表简称线性链表. 链式存储线性表的特点:存储链表中结点的一组任意的存储单元可以是连续的,也可以是不连续的,甚至是零散分 ...

  8. 线性表之顺序存储结构(C语言动态数组实现)

    线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链 ...

  9. 数据结构与算法(C/C++版)【绪论/线性表】

    声明:数据结构与算法系列博文参考了<天勤高分笔记>.<王道复习指导>.C语言中文网.非商业用途,仅为学习笔记总结! 第一章<绪论> 一.基本概念及入门常识  /// ...

  10. 线性表接口的实现_Java

    线性表是其组成元素间具有线性关系的一种线性结构,对线性表的基本操作主要有插入.删除.查找.替换等,这些操作可以在线性表的任何位置进行.线性表可以采用顺序存储结构和链式存储结构表示. 本接口的类属于da ...

随机推荐

  1. Linux命令 之 contrab

    crontab 命令是用来在linux平台上执行 定时任务的命令: 默认是在安装完操作系统之后,便会启动此任务的调度 crontab 会在每分钟检查是否有要执行的任务,如果有便会执行该任务:新建的cr ...

  2. nodejs批量重命名

    const fs = require("fs"); // directory path let config = {   affix: null,   src: null, }; ...

  3. 初学,Markdown的使用

    Markdown学习 一级标题:"#"+空格+"标题" 二级标题 二级标题:"##"+空格+"标题" 三级标题 三级标题 ...

  4. mysql知识点二

    1.mysql中的语言有哪些?分别代表什么意思1.DDL(Data Define Language) 数据定义语言2.DML(Data Manipulation Language) 数据操作语言3.D ...

  5. ElasticSearch 单点部署

    1.下载指定的ES版本(7.17.3) https://www.elastic.co/downloads/past-releases/elasticsearch-7-17-3 2.单点部署elasti ...

  6. mysql安装调试

    mysql安装 1.下载mysql的压缩包 tar -xvzf mysql-5.6.38-linux-glibc2.12-i686.tar.gz2.安装之后密码是随机的,所以我们需要重新修改密码: [ ...

  7. jenkins脚本

    1.统计代码 pipeline { agent any parameters { choice( description: '你需要选择当前哪个分支进行统计 ?', name: 'branchNow' ...

  8. lavarel导航分类不显示,因为域名问题不一致导致

    $front_menu = isset($category_map['hz9y.hzboso.com']) ? $category_map['hz9y.hzboso.com']->childre ...

  9. Command Injection-命令注入(命令执行)

    什么是命令注入? 命令注入是滥用应用程序的行为在操作系统上执行命令,使用与设备上的应用程序运行时相同的权限.例如,在作为名为joe的用户运行的web服务器上实现命令注入将在该joe用户下执行命令,从而 ...

  10. 痞子衡嵌入式:分享一个i.MXRT系列配套DRAM压力测试上位机工具(i.MXRT DRAM Tester)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦SE团队制作的i.MXRT配套DRAM压力测试上位机工具. 事情源于痞子衡的技术交流群里的提问,有群友在恩智浦官方技术公众号 [恩 ...