C++实现顺序表及双向链表

2023-05-16

顺序表

#include <iostream>
#include <assert.h>
using namespace std;
typedef int DataType;

class SeqList
{
public:
	//默认的构造函数,并初始化列表
	SeqList()
		:_array(new DataType[3])//直接开辟空间
		, _size(0)
		, _capacity(3)
	{}
	//已有信息的构造函数,并拷贝信息到新空间上
	SeqList(DataType* array, size_t size)
		:_array(new DataType[size])
		, _size(size)
		, _capacity(size)
	{
		for (size_t i = 0; i < size; i++)
		{
			_array[i] = array[i];
		}
	}

	void PushBack(DataType data)
	{
		CheckCapacity();
		_array[_size++] = data;
	}

	void PopBack()
	{
		assert(_size);  //断言,当元素为0,再尾删进行报错
		_size--;
	}

	//增容,开辟新空间,拷贝元素,释放旧空间
	void CheckCapacity()
	{
		if (_size == _capacity)
		{
			DataType* temp = new DataType[_capacity << 1];
			if (temp == NULL)
			{
				perror("temp");
				exit(EXIT_FAILURE);
			}
			for (int i = 0; i < _size; i++)
			{
				temp[i] = _array[i];
				//temp[i++] = _array[i++];严重错误代码,i加了两次
			}
			delete[] _array;
			_array = temp;
			_capacity <<= 1; // 左移一位相当于乘以二
		}
	}

	//指定位置(下标)插入一个元素
	void Insert(size_t pos, DataType data)
	{
		assert(pos <= _size);
		CheckCapacity();
		for (int i = _size; i > pos; i--)
		{
			_array[i] = _array[i - 1];
		}
		_array[pos] = data;
		_size++;//插入一个元素,_size增大
	}

	//指定位置删除
	void Erase(size_t pos)
	{
		assert(pos < _size);
		for (int i = pos; i < _size - 1; i++)
		{
			_array[i] = _array[i + 1];
		}
		_size--;
	}

	size_t Size()const
	{
		cout << endl;
		cout << _size << endl;
		return _size;
	}

	size_t Capacity()const
	{
		cout << _capacity << endl;
		return _capacity;
	}

	//判断顺序表是否为空
	bool Empty()const
	{
		if (_size == 0)
		{
			cout << 0;
			return false;
		}
		else
		{
			cout << 1;
			return true;
		}

	}

	//输入一个下标,返回下标对应的数据(又能读又能写)
	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 Display()
	{
		if (_size != 0)
		{
			for (int i = 0; i < (int)_size; i++)
			{
				cout << _array[i] << " ";
			}
		}
		cout << "" << endl;
	}

	void Clear()
	{
		_size = 0;
	}

	//逆序顺序表
	void Reserve()
	{
		DataType* left = _array;
		DataType* right = _array + _size - 1;
		while (left <= right)
		{
			DataType tmp = *left;
			*left = *right;
			*right = tmp;
			left++;
			right--;
		}
	}

	//将元素表中的个数调整为newSize
	void ReSize(size_t newSize, const DataType& data = DataType())
	{
		if (newSize <= _size)
		{
			_size = newSize;
		}
		else if (newSize <= _capacity)
		{
			for (int i = _size; i < newSize; ++i)
			{
				_array[i] = data;
			}
			_size = newSize;
		}
		else
		{
			for (int i = _size; i < newSize; i++)
			{
				CheckCapacity();
				_array[i] = data;
				_size++;  //当比容量大的时候,让_size自增,到达容量时,自增
			}
		}
	}

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

	//赋值运算符的重载
	SeqList& operator=(const SeqList& s)
	{
		if (this != &s)
		{

			for (size_t i = 0; i < s._size; i++)
			{
				_array[i] = s._array[i];
			}
			_size = s._size;
			_capacity = s._capacity;
		}
		return *this;
	}

	friend ostream& operator<<(ostream& cout, const SeqList& s)
	{
		for (int i = 0; i < s._size; i++)
		{
			cout << s._array[i]<<" ";
		}
		cout << s._size << " " << s._capacity << endl;
		return cout;
	}

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

private:
	DataType* _array;
	size_t _size;
	size_t _capacity;
};

void Funtest1()
{
	int k[5] = { 1, 2, 3, 4, 5 };
	SeqList d1;
	SeqList d2(k,5);
	d1.PushBack(1);
	d1.PushBack(2);
	d1.PushBack(3);
	d1.Insert(2, 5);
	d1.Insert(1, 3);
	d1.Display();
	SeqList d3(d2);
	d3.Display();
	SeqList d4 = d3;
	d4.Display();
	/*d1.Erase(2);
	d1.Display();
	d1.Size();
	d1.Capacity();
	d1.Empty();*/
	//d2.Display();
	//SeqList d3(d2);
	cout << d4;
}

void Funtest2()
{
	int k[5] = { 1, 2, 3 };
	SeqList d1(k, 3);
	d1[0] = 2;
	d1.Display();
	cout << d1.Front() << endl;
	cout << d1.Back() << endl;
	d1.Reserve();
	d1.Display();
	d1.ReSize(7,7);
	d1.Display();
	


}

int main()
{
	Funtest1();
	//Funtest2();
	getchar();
	return 0;
}

双向链表:

1.在Find中,查找到后返回当前节点的下一个节点;

2.在Erase中,需要知道pos节点的数据,接收Find查找到数据的地址,作为pos。

#include <iostream>
#include <assert.h>
using namespace std;
typedef int DataType;
//双向链表

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

class List
{
public:
	List()
		:_pHead(NULL)
	{}

	List(DataType* array, size_t size)
	{
		for (size_t i = 0; i < size; ++i)
			PushBack(array[i]);
	}

	~List()
	{
		if (_pHead == NULL)
		{
			return;
		}
		Node* _head = _pHead;
		Node* _tail = NULL;
		while (_head->_pNext)
		{
			_head = _head->_pNext;
		}
		while (_head != _pHead)  //删除最后一个节点,_tail往前移
		{
			_tail = _head->_pPre;
			delete _head;
			_head = _tail;
		}
		_pHead = NULL;
	}

	Node* BuyNode(const DataType data)
	{
		return new Node(data);
	}

	void PushBack(const DataType data)
	{
		if (_pHead == NULL)
		{
			_pHead = BuyNode(data);
			_pHead->_pPre = NULL;
			_pHead->_pNext = NULL;
			_pHead->_data = data;
		}
		else
		{
			Node* _head = _pHead;
			while (_head->_pNext)
			{
				_head=_head->_pNext;
			}
			_head->_pNext = BuyNode(data);
			_head->_pNext->_pPre = _head;
			_head->_pNext->_pNext = NULL;
		}
	}

	void PopBack()
	{
		if (_pHead == NULL)
		{
			return;
		}
		if (_pHead->_pNext == NULL)
		{
			_pHead= NULL;
			return;
		}
		Node* _head = _pHead;
		while (_head->_pNext)
		{
			_head = _head->_pNext;
		}
		_head->_pPre->_pNext = NULL;
	}

	void PushFront(const DataType data)
	{
		if (_pHead == NULL)
		{
			_pHead = BuyNode(data);
			_pHead->_pNext = NULL;
			_pHead->_pPre = NULL;
			_pHead->_data = data;
		}
		else
		{
			_pHead->_pPre = BuyNode(data);
			_pHead->_pPre->_pNext = _pHead;
			_pHead = _pHead->_pPre;
			_pHead->_pPre = NULL;
		}
	}

	void PopFront()
	{
		if (_pHead == NULL)
		{
			return;
		}
		if (_pHead->_pNext == NULL)
		{
			_pHead = NULL;
			return;
		}
		_pHead = _pHead->_pNext;
		_pHead->_pPre = NULL;
	}

	//指定位置删除,没有节点,删头结点,删尾节点,非头非尾,返回pos的后一个节点
	Node* Erase(Node* pos)
	{
		assert(pos);
		if (_pHead == NULL)
			return NULL;
		if (pos == _pHead)
		{
			PopFront();
		}
		else
		{
			Node* _head = _pHead;
			while (_head->_pNext)
				_head = _head->_pNext;
			if (pos == _head)
				PopBack();
		}
		Node* _head = _pHead;
		while (_head->_pNext)
		{
			_head = _head->_pNext;
			if (_head==pos)
			{
				pos->_pPre->_pNext = pos->_pNext;
				pos->_pNext->_pPre = pos->_pPre;
				delete pos;
				return _head->_pNext;
			}
		}
	}

	Node* Insert(Node* pos, const DataType& data)
	{
		assert(pos);
		if (pos == _pHead)
		{
			PushFront(data);
			return pos->_pNext;
		}
		Node* newnode=BuyNode(data);//既不是头结点也不是尾节点
		pos->_pPre->_pNext = newnode;
		newnode->_pNext = pos;
		newnode->_pPre = pos->_pPre;
		pos->_pPre = newnode;
		newnode->_data = data;
		return pos->_pNext;
	}

	Node* Find(const DataType& data)
	{
		Node* _head = _pHead;
		if (_head == NULL)
		{
			return NULL;
		}
		while (_head->_pNext)
		{
			if (_head->_data == data)
			{
				return _head;
			}
			_head = _head->_pNext;
		}
		if (_head->_data == data)
		{
			return _head;
		}
		return NULL;
	}

	size_t Size()
	{
		int count=1;
		if (_pHead == NULL)
		{
			return 0;
		}
		else
		{
			while (_pHead->_pNext!= NULL)
			{
				_pHead = _pHead->_pNext;
				++count;
			}
		}
		return count;
	}

	//从后往前删,找出最后节点的前一个节点为tail,删除最后一个节点
	void Clear()
	{
		if (_pHead == NULL)
		{
			return;
		}
		Node* _head = _pHead;
		Node* _tail = NULL;
		while (_head->_pNext)
		{
			_head = _head->_pNext;
		}
		while (_head!= _pHead)  //删除最后一个节点,_tail往前移
		{
			_tail = _head->_pPre;
			delete _head;
			_head = _tail;
		}
		_pHead = NULL;
	}

	void Display()
	{
		if (_pHead == NULL)
		{
			return;
		}
		Node* head = _pHead;
		while (head)// 最后一个节点的下一指针指向空
		{

			cout << head->_data << " " ;
			head=head->_pNext;
		}
		cout << endl;
	}

	bool Empty()
	{
		if (_pHead == NULL)
		{
			return true;
		}
		return false;
	}

private:
	Node* _pHead;
};

void Funtest()
{
	List L1;
	L1.PushBack(1);
	L1.PushBack(2);
	L1.PushBack(3);
	/*L1.PushBack(4);
	L1.PushFront(2);
	L1.PushFront(3);
	L1.PushFront(4);*/
	//L1.Display();
	/*L1.PopFront();
	L1.PopFront();
	L1.PopFront();*/
	//L1.Clear();
	L1.Display();
	/*L1.Erase(L1.Find(3));*/
	L1.Insert(L1.Find(3),4);
	L1.Display();
	int arr[] = { 1, 2, 3, 4, 5 };
	List L2(arr, 5);
	L2.Display();
}

int main()
{
	Funtest();
	getchar();
	return 0;
}


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

C++实现顺序表及双向链表 的相关文章

  • QT QWebEngineProcess注意事项及扫码登录回调

    一 pro文件中需要添加模块 二 程序打包 除了使用windeployqt exe打包依赖库以外 xff0c 还需要手动添加两项文件 第一步 xff1a 在你程序bin目录下的translations文件中添加文件夹qtwebengine
  • QT 防止按钮快速重复点击

    一 实现间隔一秒只能点击一次按钮 xff08 没到时间之前 xff0c 点击不能按 xff09 span class token keyword void span span class token class name MainWindo
  • QT QButtonGroup 与 QStackedWidget 实现菜单(Tab)切换

    一 效果图 三个菜单互斥点击 xff0c 点击后跳转至相应页面 二 QButtonGroup 按钮互斥 1 UI结构 2 代码 span class token keyword void span span class token func
  • 对于程序多核优化的思考

    针对处理器的多核心多线程进行优化 现在的处理器很少有单核的 xff0c 2核的都很少了 在用python计算2的10000000次方的时候 xff0c 我观察了我的任务管理器 xff0c 首先第3个线程的使用率达到了100 xff0c 然后
  • QT QListWidget的添加与删除,滚动条显示或隐藏,判断是否滑到顶部或底部,并使QListWidgetItem自适应大小

    注意 xff1a QListWidget添加子Item时 xff0c 最外层最好设置完整背景颜色 xff0c 否则移入Item会自带淡蓝色背景 一 QListWidget 中使 QListWidgetItem自适应大小 父部件ListWid
  • QT 网络请求设置自定义cookie请求头失败的问题

    文章目录 一 背景二 示例代码1 自己组装HTTP请求 xff08 成功 xff09 2 采用项目网络组件库 xff08 失败 xff09 3 解决办法 xff08 成功 xff09 一 背景 我准备在每一次HTTP请求头中加入自己定义的c
  • QT 三角气泡提示框(文字自适应、自定义三角位置)

    文章目录 一 效果图二 实现代码1 调用示例2 BubbleTipsWidget h3 BubbleTipsWidget cpp 一 效果图 二 实现代码 1 调用示例 span class token keyword void span
  • QT 代码添加QScrollArea

    一 QScrollArea 一 这是一个控件容器类 xff0c 可以在UI中直接拖拽 xff0c 也可以使用代码进行添加 xff0c 当我们UI添加时 xff0c QScrollArea这个容器套了两层 xff0c 我们放入的控件 xff0
  • QML入门----创建qml项目(一)

    文章目录 导语一 选择菜单二 选择文件类型三 填写项目名称四 项目创建成功五 Hello World六 运行图 导语 今天开始学习qml xff0c 从hello world开始 xff0c 本来计划之前开始学的 xff0c 但是看了好多资
  • QML入门----基本语法(二)

    文章目录 基础语法1 import 导入语句2 Loader 一 类型二 对象1 id2 属性 xff08 property xff09 3 信号和信号处理器特性4 方法特性 function5 附加属性和附加信号处理器6 枚举 四 注释五
  • QML入门----图形动画基础(一)

    文章目录 一 图形动画基础1 颜色2 渐变 xff08 Gradient xff09 二 图片1 图片2 边界图片3 动态图片 三 缩放 旋转 平移变换1 使用属性2 高级变换 xff08 Transform xff09 四 状态改变使用过
  • QT Signal and slot arguments are not compatible

    一 原因 信号和槽绑定的参数不同 signals span class token operator span span class token keyword void span span class token function run
  • QML入门----图形动画基础(二)

    文章目录 导语一 混合效果二 颜色效果1 亮度对比度 xff08 BrightnessContrast xff09 2 颜色叠加3 着色4 饱和度 三 渐变效果 xff08 Gradient xff09 四 阴影效果五 模糊效果六 动感模糊
  • EXCEL基本办公操作 (求和、相除、填充日期、交换列、排序)

    文章目录 一 求和二 相除三 自动填充日期四 交换列五 进行排序 一 求和 1 拖动鼠标选中 2 同时按住 alt 跟 61 二 相除 假如要计算A列除以B列 1 先选中显示结果的框 2 在上面的框输入 61 号 xff0c 然后点击A1位
  • Ubuntu的VirtualBox虚拟机怎么识别物理机的U盘?我教你。

    首先确保 你的VBOX虚拟机安装了扩展 1 到官网上下载扩展吧 2 用VBOX打开扩展包 3 打开VBOX管理器 xff0c 点击设置 4 新建一个usb筛选器 xff0c 名字随便起 最后点击确定 正常关闭 你的虚拟机 xff0c 然后重
  • QML入门----设计器详解(拖拽添加控件)

    文章目录 导语1 基本视图2 文件类型 一 界面说明1 库 xff08 Library xff09 2 导航 xff08 Navigator xff09 3 属性 xff08 Properties xff09 4 连接视图 导语 设计器的基
  • C++11 非常方便的特性

    文章目录 C 43 43 11一 nullptr1 含义2 作用3 NULL存在的问题 二 auto1 含义2 限制3 使用场景 三 lambda1 含义2 优点3 用法 四 基于范围的for循环1 作用2 用法3 循环内更改数组 C 43
  • QML入门----C++与QML交互快速应用

    文章目录 前言一 Qt中有关QML的C 43 43 类1 QQmlEngine2 QQmlContext3 QQmlComponent4 QQmlExpresssssion 二 其他1 使用C 43 43 属性 xff08 Q PROPER
  • QML错误:Component is not ready

    一 原因 终极原因 xff1a 组件没有构建好 xff0c 有可能是加载的QML路径不对 xff0c 或者是QML代码错误 xff0c 或者是QML组件还没有加载完 二 解决办法 打印详细错误 QQmlEngine engine span
  • QT 打开程序闪烁cmd窗口

    包含多种原因 xff0c 我的原因是Pro文件多写了一些其他的 xff0c 删除了下面这句OK了 DISTFILES span class token operator 43 span span class token operator 6

随机推荐

  • QT UTC(T和Z格式)时间转换为北京时间

    一 UTC 协调世界时 xff0c 又称世界统一时间 世界标准时间 国际协调时间 由于英文 xff08 CUT xff09 和法文 xff08 TUC xff09 的缩写不同 xff0c 作为妥协 xff0c 简称UTC 和北京时间相差八小
  • QT 文件操作大全

    文章目录 常用文件模式一 创建文件二 读文件三 写文件四 清空文件夹五 计算文件夹个数六 计算文件夹总大小七 转换大小为B KB M G八 批量修改文件名 常用文件模式 模式含义QIODevice ReadOnly只读方式QIODevice
  • QT QScrollArea 滑动到指定item位置

    一 QT自带的api QListWidget QTableWidget QTreeWidget都有自带的api可以调用 xff0c 如下示例 但是当自定义一个QScrollArea区域 xff0c 布局中插入多个item时 xff0c 就需
  • 马克飞象常用操作(markdown )

  • QT 移入控件展示卡片

    功能 xff1a 移入widget显示卡片 xff0c 并且可以进入卡片不消失 xff08 widget与卡片距离离得很近 xff09 xff0c 移出卡片才离开 span class token keyword bool span spa
  • 树莓派pico入门第一站:让主板上的小灯闪起来。(附代码)

    首先配置你的树莓派pico xff0c 把它插在你的电脑上 xff0c 你的电脑会多出来一个 U盘 xff0c 把这个文件复制 xff0c 粘贴 到你的树莓派pico里面 xff0c 你多出来的 U盘 会自动 消失 xff0c 这时候 xf
  • QT 网格布局插入固定列数的item

    一 场景 在网格布局插入固定列数的item xff0c 比如三列item xff0c 根据item的总数计算 span class token macro property span class token directive hash s
  • QT QMetaEnum枚举与字符串互转

    一 示例 span class token macro property span class token directive hash span span class token directive keyword include spa
  • QT 抓取widget转换为图片

    QString folder span class token operator 61 span span class token class name QStandardPaths span span class token operat
  • window11 安装linux子系统(一键安装)并连接到vs code

    文章目录 一 window 使用linux环境的几种方式二 安装wsl1 进入这个目录下 xff0c 将cmd exe已管理员身份运行2 命令行输入以下命令 xff0c 然后重启计算机3 再次已管理员身份打开 xff0c 执行命令 xff0
  • QT 利用URL Protocol实现网页调起本地程序

    一 QT 安装时脚本注入注册表或者自己添加 span class token comment 依次为目录 键 值 xff0c 34 URL Protocol 34 这个键必须有 span WriteRegStr HKCR span clas
  • PC 配置jenkins自动打包

    文章目录 一 下载jenkins运行环境二 下载jenkins三 安装 qt 5 12 2 和 VS 2017四 安装git并配置gitlab五 jenkins配置git 一 下载jenkins运行环境 java jdk 11 镜像下载地址
  • 心系Flyme

    我来自陕西省神木县 xff0c 大学我考入了陕西科技大学 xff0c 成为了一名信息与计算科学专业的学生 xff0c 希望在以后的道路中 xff0c 通过我自己的努力 xff0c 提升自己的价值 在大二大三学习编程 xff0c 希望自己可以
  • C语言的编译链接过程

    编写的一个C程序 xff08 源程序 xff09 xff0c 转换成可以在硬件上运行的程序 xff08 可执行程序 xff09 xff0c 需要进行翻译环境和运行环境 翻译环境则包括两大过程编译和链接 xff0c 经过编译和链接过程便可形成
  • 函数的调用过程(栈帧的创建和销毁)

    为了更好地认识函数的调用过程 xff0c 我们可以用反汇编代码去理解学习 一 基本概念 1 栈帧 xff08 过程活动记录 xff09 xff1a 是编译器用来实现函数调用的一种数据结构 xff0c 每个栈帧对应一个未运行完的函数 xff0
  • 树莓派pico刚买来怎么用?

    第一次使用 xff0c 首先按住主板上的白色按钮 xff0c 然后另一只手把数据线插在主板上 xff0c 直到你的电脑提示有新设备输入 xff0c 提示可以是声音 xff0c 可以是设备管理器多了一个U盘 要想得到提示 xff0c 你要打开
  • C语言动态顺序表

    顺序表是将表中的节点依次存放在计算机内存中一组地址连续的存储单元中 xff0c 表可以动态增长 xff0c 尾插元素 xff0c 尾删元素 xff0c 头插元素 xff0c 头删元素 xff0c 打印元素 xff0c 查找元素 xff0c
  • C语言笔记1

    假定程序运行环境为VC6 0 xff0c 缺省为四字节对齐 xff0c CPU xff08 32小字节序处理器 xff09 1 char x 61 34 ab0defg 34 char y 61 39 a 39 39 b 39 39 0 3
  • 【C++三大特性】继承

    如有疑问 xff0c 欢迎讨论 xff0c QQ xff1a 1140004920 一 继承的概念 1 原有的类为基类 xff0c 又称父类 xff0c 对基类进行扩展产生的新类称为派生类 xff0c 又称子类 xff0c 继承可以使代码复
  • C++实现顺序表及双向链表

    顺序表 include lt iostream gt include lt assert h gt using namespace std typedef int DataType class SeqList public 默认的构造函数