C++实现顺序表与链表

2023-11-16

C++实现顺序表与链表
一、顺序表
之前已经对顺序表有了了解,需要注意的是读者如果疑惑以下代码没有实现头插与头删,是因为代码中任意插入与删除这两个函数可以实现此功能。下面有测试代码,读者也可以自行测试
代码如下:
#include<iostream>
using namespace std;
#include<assert.h>
typedef int DataType;
class SeqList
{
public:
	//构造函数
	SeqList()
		: _array(new DataType[3])
		, _capacity(3)
		, _size(0)
	{}

	//带参数的构造函数
	SeqList(DataType *array, size_t size)
		: _array(new DataType[size])
		, _capacity(size)
		, _size(size)
	{
		for (size_t i = 0; i < size; ++i)
			_array[i] = array[i];
	}

	//拷贝构造函数
	SeqList(const SeqList& s)
		:_array(new DataType[s._capacity])
		, _capacity(s._capacity)
		, _size(s._size)
	{
		for (size_t i = 0; i < s._size; ++i)
			_array[i] = s._array[i];
	}

	//运算符=重载
	SeqList& operator=(const SeqList& s)
	{
		DataType *tmp = new DataType[s._capacity];
		memcpy(tmp, s._array, s._size);
		delete[] _array;
		_array = tmp;
		_capacity = s._capacity;
		_size = s._size;
	}

	~SeqList()
	{
		if (_array)
		{
			delete[] _array;
			_size = 0;
			_capacity = 0;
		}
	}

	void PushBack(int data)
	{
		_CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	void PopBack()
	{
		_size--;
	}
	void Insert(size_t pos, DataType data)
	{
		_CheckCapacity();
		size_t end = _size;
		while (end >= pos)
		{
			_array[end] = _array[end - 1];
			end--;
		}
		_array[pos - 1] = data;
		_size++;
	}
	void Erase(size_t pos)
	{
		assert(pos < _size);
		size_t tmp = pos;
		while (tmp < _size)
		{
			_array[tmp-1] = _array[tmp];
			tmp++;
		}
		_array[tmp] = _array[_size-1];
		_size--;
	}
	size_t Size()const
	{
		return _size;
	}
	size_t Capacity()const
	{
		return _capacity;
	}
	bool Empty()const
	{
		return _size == 0;
	}
	DataType& operator[](size_t index)
	{
		return _array[index];
	}
	const DataType& operator[](size_t index)const
	{
		return _array[index];
	}

	// 返回顺序表中的第一个元素 
	DataType& Front()
	{
		return _array[0];
	}
	const DataType& Front()const
	{
		return _array[0];
	}
	// 返回顺序表中最后一个元素 
	DataType& Back()
	{
		return _array[_size-1];
	}
	const DataType& Back()const
	{
		return _array[_size - 1];
	}

	// 清空顺序表中的所有元素 
	void Clear()
	{
		_size = 0;
	}

	// reserve() 
	// 将顺序表中元素个数改变到newSize 
	void ReSize(size_t newSize, const DataType& data = DataType())
	{
		if (newSize <= _size)
		{
			_size = newSize;
		}
		else if ((newSize > _size)&&(newSize <= _capacity))
		{
			for (size_t i = _size; i < newSize; i++)
			{
				_array[i] = data;
			}
			_size = newSize;
		}
		else
		{
			DataType *tmp = new DataType[newSize];
			for (size_t i = 0; i < _size; i++)
			{
				tmp[i] = _array[i];
			}
			for (size_t j = _size; j < newSize; j++)
			{
				tmp[j] = data;
			}
			delete[] _array;
			_array = tmp;
			_size = newSize;
			_capacity = newSize;
		}
	}
	friend ostream& operator<<(ostream& _cout, const SeqList& s)
	{
		for (size_t i = 0; i < s._size; i++)
		{
			cout << s._array[i] << " ";
		}
		cout << endl;
		return cout;
	}
private:
	void _CheckCapacity()
	{
		if (_size == _capacity)
		{
			_capacity = _capacity * 2 + 3;
			DataType *tmp = new DataType[_capacity];
			for (size_t i = 0; i < _size; i++)
			{
				tmp[i] = _array[i];
			}
			delete _array;
			_array = tmp;
		}
	}
private:
	DataType *_array;
	size_t _size;
	size_t _capacity;
};
void test()
{
	SeqList s;
	s.PushBack(1);
	s.PushBack(2);
	s.PushBack(3);
	s.PushBack(4);
	cout << s;
	cout << s.Size() << endl;

	s.Insert(1, 0);            //头插0
	s.Erase(3);                //删除第三个数
	cout << s;

	s.PopBack();             
	s.ReSize(10);             //改变大小

	cout << s.Empty() << endl;
	cout << s.Back() << endl;
	cout << s.Front() << endl;

	cout << s.Size() << endl;
	cout << s.Capacity() << endl;
}
int main()
{
	test();
	system("pause");
	return 0;
}
测试结果:
二、双向链表
代码如下:
#include<iostream>
#include<assert.h>
using namespace std;
typedef int DataType;
struct Node
{
	Node()
	    : _pNext(NULL)
	    , _pPre(NULL)
	    , _data(NULL)
	{}

	Node(const DataType& data)
	: _pNext(NULL)
	, _pPre(NULL)
	, _data(data)
	{}

	Node* _pNext;
	Node* _pPre;
	DataType _data;
};

class List
{
public:
	List()
	{
		_pHead = new Node;
	}

	List(DataType* array, size_t size)
	{
		for (size_t i = 0; i < size; ++i)
			PushBack(array[i]);
	} 
	void PushBack(const DataType data)
	{
		Node* pTail = _pHead;
		while (pTail->_pNext != NULL)
		{
			pTail = pTail->_pNext;
		}
		Node* pNewNode = new Node(data);
		pTail->_pNext = pNewNode;
		pNewNode->_pPre = pTail;
	}

	void PopBack()
	{
		assert(this);
		if (_pHead->_pNext == NULL)  //空链
		{
			cout << "空链" << endl;
			return;
		}
		Node *tmp = _pHead;
		while ((tmp != NULL)&&(tmp->_pNext != NULL))
		{
			tmp = tmp->_pNext;
		}
		Node *node = tmp->_pPre;
		delete tmp;
		node->_pNext = NULL;
	}

	void PushFront(const DataType data)
	{
		assert(this);
		if (_pHead->_pNext == NULL)
		{
			PushBack(data);
		}
		else
		{
			Node *node = new Node(data);
			Node *Cur = _pHead->_pNext;
			_pHead->_pNext = node;
			node->_pPre = _pHead;
			node->_pNext = Cur;
			Cur->_pPre = node;
		}
	}

	void PopFront()
	{
		assert(this);
		if (_pHead->_pNext == NULL)
		{
			cout << "空链" << endl;
			return;
		}
		Node *node = _pHead->_pNext->_pNext;
		delete (_pHead->_pNext);
		if (node == NULL)           //只有一个节点
		{
			_pHead->_pNext = NULL;
			return;
		}
		node->_pPre = _pHead;
		_pHead->_pNext = node;
	}

	void Erase(Node* pos)
	{
		assert(this);
		Node *cur = pos->_pPre;
		Node *next = pos->_pNext;
		cur->_pNext = next;
		next->_pPre= cur;
		delete pos;
		pos = NULL;
	}

	Node *Find(const DataType d)   //查询节点位置
	{
		assert(this);
		Node *tmp = _pHead;
		while (tmp != NULL)
		{
			if (tmp->_data == d)
			{
				return tmp;
			}
			tmp = tmp->_pNext;
		}
	}

	void Insert(Node* pos, const DataType& data)   //指定位置插入
	{
		assert(this);
		Node *cur = pos->_pNext;
		Node *tmp = new Node(data);
		pos->_pNext = tmp;
		tmp->_pPre = pos;
		tmp->_pNext = cur;
		cur->_pPre = tmp;
	}

	size_t Size()              //链表元素个数
	{
		int count = 0;
		Node *cur = _pHead->_pNext;
		while (cur != NULL)
		{
			cur = cur->_pNext;
			count++;
		}
		return count;
	}   

	void Clear()                //清空
	{
		assert(this);
		if (_pHead == NULL)
		{
			cout << "空链" << endl;
			return;
		}
		Node *tmp = _pHead->_pNext;
		Node *next = tmp->_pNext;
		while (tmp->_pNext!= NULL)
		{
			delete tmp;
			tmp = next;
			next = next->_pNext;
		}
		_pHead->_pNext = NULL;
	}    

	void display()
	{
		assert(this);
		Node *cur = _pHead->_pNext;
		if (cur == NULL)
		{
			cout << "空链" << endl;
			return;
		}
		while (cur != NULL)
		{
			cout << cur->_data << " ";
			cur = cur->_pNext;
		}
		cout << endl;
	}
private:
	Node* _pHead;
};
int main()
{
	List l1;
	l1.PushFront(4);
	l1.PushFront(3);
	l1.PushFront(2);
	l1.PushFront(1);

	l1.PushBack(5);
	l1.PushBack(6);
	l1.display();

	l1.PopBack();
	l1.PopFront();
	l1.display();
	cout << l1.Size() << endl;

	l1.Erase(l1.Find(4));
	l1.display();
	l1.Insert(l1.Find(2), 3);
	l1.display();

	l1.Clear();
	cout << l1.Size() << endl;

	system("pause");
	return 0;
}
运行结果如下:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++实现顺序表与链表 的相关文章

随机推荐

  • ppt转换成pdf免费软件

    为什么80 的码农都做不了架构师 gt gt gt ppt转换成pdf免费软件 导读 使用 ppt转换成pdf转换器当然是转换ppt文件的一个方法 但毕竟好的转换工具并不多 对于从事大量文案处理的工作人员来讲 没有一款专业好用的ppt转换成
  • Linux下使用鼠标滚轮

    Linux下使用鼠标滚轮 让acrobat pdfreader支持滚轮鼠标 这些天用acroread看pdf文件 发现不支持鼠标滚轮 很不爽 最终在水母上搜到了解决方法 将如下内容加到 Xresources文件中 AcroRead XmSc
  • 方差、标准差、协方差、协方差矩阵、散度矩阵

    方差 统计中的方差 样本方差 是每个样本值与全体样本值的平均数之差的平方值的平均数 概率论中方差用来度量随机变量和其数学期望 即均值 之间的偏离程度 1 统计 方差用来计算每一个变量 观察值 与总体均数之间的差异 为避免出现离均差总和为零
  • 小程序实现滚动加载(懒加载)

    前言 小程序是一项很受欢迎的技术 随着其能力的不断增强 越来越多的人开始使用小程序来完成各种任务 当我面面临一个页面有非常多的数据时 该如何处理呢 显然一次性全部加载完 会非常消耗性能的 为了解决这些问题从而出现了一种叫滚动加载的数据处理方
  • 数字时钟仿真电路设计

    课题设计要求 时间以24小时为一个周期 显示时 分 秒 具有校时功能 可以分别对时分秒进行单独校时 使其校正到标准时间 计时过程具有报时功能 当时间到达整点前十秒进行蜂鸣报时 为了保证计时的稳定及准确 须由晶体振荡器提供表针时间基准信号 准
  • 微信公众号开发config:fail,Error: invalid url domain总结自己遇到的几种原因

    1 JS接口安全域名配置错误 不要http 2 设置安全域名时 txt文件未在域名根目录下 3 appid错误 用了其他公众号的 4 ios手机 获取的当前url与实际不一致 详情见下一篇文章
  • Gradle版本7+ AAR包的引入应用

    ARR包的使用 作为一个安卓的初学者 因为某些个客户需要我们提供安卓SDK 我们压根没有移动端业务 为了赚钱 硬着头皮从0开始写一个SDK 终于我这个 百度战士 也靠百度打出了aar包 问题来了 当你搜索安卓如何引用aar 包的时候 是不是
  • Unity物体拖拽系统(一)

    在游戏制作的过程中 我们经常会遇到拖拽物体到某个位置并做其他操作的需求 比如我们会把装备拖动到装备栏来使用这个装备 为了方便的解决这个问题 我制作了一套耦合性比较低的拖拽系统 这套拖拽会适配我们之前制作的按键系统 很简单的就可以添加上手柄的
  • 哈希表查找失败的平均查找长度_哈希算法高大上?也不过如此

    01 知识框架 02 知识点详解 1 散列表的相关概念 什么是散列表和散列函数 是根据关键码值 Key value 而直接进行访问的数据结构 也就是说 它通过把关键码值映射到表中一个位置来访问记录 以加快查找的速度 这个映射函数叫做 散列函
  • VTK(0)---CMake工程

    VTK 0 CMake工程 目录 前言 一 指定cmake版本 二 设置工程 三 针对Qt 自动使用moc uic rcc程序预处理 h文件 ui文件等 四 平台移植问题 五 设置编译模式 六 找到包 七 包含头文件等 八 链接库文件 九
  • 自定义进度条,支持显示浮点数

    思路 QT原生的进度条默认只支持显示整型值 这里重新封装了进度条 支持显示浮点数 内部同时设置了进度条样式 支持显示提示信息 GitHub下载链接 https github com caochuanlin progressbar 头文件 c
  • 01.项目目录搭建以及styled-Components和Reser.css的结合使用

    首先 我们使用脚手架创建了一个新的项目 这里我们对项目的一些基本文件进行整理 首先将一些不需要的文件删除 删除之后留下一些需要的文件 如下 这里我们将原来的style css已经重命名为style js文件 下面安装styled Compo
  • NPM Magic

    NPM Magic package json package json 最起码要包含 name 和 version 快速初始化 package json npm init yes dependencies 生产环境依赖的包 devDepen
  • 安规电容,X电容,Y电容

    什么是安规电容 首先要说一下 安规 是安全规范的简称 安全规范对产品的装置与电子组件有明确的陈述及指导 以避免由于设计不良或使用不当而导致电击 能量 打火 拉弧 爆炸 火灾 辐射 机械与热 高温危险 化学危险等事故和灾害 要求生产厂商尽可能
  • Vue3训练营笔记

    vue3脚手架的详细使用说明 文档下载 https download csdn net download qq 42740465 87939368 spm 1001 2014 3001 5503
  • ROS学习(1)—Ubuntu20.04系统安装noetic学习日志

    1 前言 ROS知识自学 现有博文比较多 而且参差不齐 为了梳理自己的学习思路 形成自身的知识体系 撰写自己的学习日志文档 参考文章及链接均在文章末尾显示 2 主要安装步骤 2 1 更换源文件 添加软件源文件则是将国外服务器的下载地址更改为
  • 标识符和关键字的规则

    大家好 我是耀曜 这段事件没有怎么更新文章 主要是最近换工作 有一年的工作经验 说白了就是一个初级Java后端开发的新手 这段时间面了很多家 我也很纳闷问的都是基础差不多都忘掉了的 以后这段事间耀曜会发布一些关于面试的问题的总结 希望对看到
  • Android 数据的保存,检索,删除之Cursor

    今天遇到的一个问题是如何将数据删除后 将原来的id也相应的做改变呢 如果说对其id值进行逐个修改这也是可以的 但是当数据增多的时候 我们这么做就会很大程度上的降低程序的性能 所以我们想到的就是不要根据id的检索来获取数据库中的值 因为这样做
  • face-api.js中加入MTCNN:进一步支持使用JS实时进行人脸跟踪和识别

    如果你现在正在阅读这篇文章 那么你可能已经阅读了我的介绍文章 JS使用者福音 在浏览器中运行人脸识别 或者之前使用过face api js 如果你还没有听说过face api js 我建议你先阅读介绍文章再回来阅读本文 和往常一样 本文中为
  • C++实现顺序表与链表

    C 实现顺序表与链表 一 顺序表 之前已经对顺序表有了了解 需要注意的是读者如果疑惑以下代码没有实现头插与头删 是因为代码中任意插入与删除这两个函数可以实现此功能 下面有测试代码 读者也可以自行测试 代码如下 include