当前位置: 首页 > news >正文

C++数据结构之顺序表

顺序表头文件 sq_list.h

#ifndef __SQ_LIST_H__
#define __SQ_LIST_H__

#ifndef DEFAULT_SIZE
#define DEFAULT_SIZE 1000		// 缺省元素个数
#endif

// 顺序表类模板
template <class ElemType>
class SqList
{
protected:
	// 数据成员:
	ElemType* elems;					// 元素存储空间
	int maxSize;						// 顺序表最大元素个数
	int count;							// 元素个数

public:
	// 抽象数据类型方法声明及重载编译系统默认方法声明:
	SqList(int size = DEFAULT_SIZE);			// 构造函数模板
	virtual ~SqList();					// 析构函数模板
	int Length() const;					// 求线性表长度			 
	bool Empty() const;					// 判断线性表是否为空
	void Clear();						// 将线性表清空
	void Traverse(void (*visit)(const ElemType&)) const;		// 遍历线性表
	bool GetElem(int position, ElemType& e) const;				// 求指定位置的元素	
	bool SetElem(int position, const ElemType& e);				// 设置指定位置的元素值
	bool Delete(int position, ElemType& e);						// 删除元素		
	bool Delete(int position);			// 删除元素		
	bool Insert(int position, const ElemType& e);				// 插入元素
	SqList(const SqList<ElemType>& source);						// 复制构造函数模板
	SqList<ElemType>& operator =(const SqList<ElemType>& source); // 重载赋值运算符
};


// 顺序表类模板的实现部分

template <class ElemType>
SqList<ElemType>::SqList(int size)
// 操作结果:构造一个最大元素个数为size的空顺序表
{
	maxSize = size;						// 最大元素个数
	elems = new ElemType[maxSize];		// 分配存储空间
	count = 0;							// 空线性表元素个数为0
}

template <class ElemType>
SqList<ElemType>::~SqList()
// 操作结果:销毁线性表
{
	delete[] elems;						// 释放存储空间
}

template <class ElemType>
int SqList<ElemType>::Length() const
// 操作结果:返回线性表元素个数
{
	return count;						// 返回元素个数
}

template <class ElemType>
bool SqList<ElemType>::Empty() const
// 操作结果:如线性表为空,则返回true,否则返回false
{
	return count == 0;					// count == 0表示线性表为空
}

template <class ElemType>
void SqList<ElemType>::Clear()
// 操作结果:清空线性表
{
	count = 0;							// 空线性表元素个数为0
}

template <class ElemType>
void SqList<ElemType>::Traverse(void (*visit)(const ElemType&)) const
// 操作结果:依次对线性表的每个元素调用函数(*visit)
{
	for (int temPos = 1; temPos <= Length(); temPos++)
	{	// 对线性表的每个元素调用函数(*visit)
		(*visit)(elems[temPos - 1]);
	}
}

template <class ElemType>
bool SqList<ElemType>::GetElem(int position, ElemType& e) const
// 操作结果:当线性表存在第position个元素时,用e返回其值,返回true, 否则返回false
{
	if (position < 1 || position > Length())
	{	// position范围错
		return false;					// 元素不存在
	}
	else
	{	// position合法
		e = elems[position - 1];
		return true;					// 元素存在
	}
}

template <class ElemType>
bool SqList<ElemType>::SetElem(int position, const ElemType& e)
// 操作结果:将线性表的第position个元素赋值为e,
//	position的取值范围为1≤position≤Length(),
//	position合法时返回true,否则返回false
{
	if (position < 1 || position > Length())
	{	// position范围错
		return false;					// 范围错
	}
	else
	{	// position合法
		elems[position - 1] = e;
		return true;					// 成功
	}
}

template <class ElemType>
bool SqList<ElemType>::Delete(int position, ElemType& e)
// 操作结果:删除线性表的第position个元素, 并前用e返回其值,
//	position的取值范围为1≤position≤Length(),
//	position合法时返回true,否则返回false
{
	if (position < 1 || position > Length())
	{	// position范围错
		return false;					// 范围错
	}
	else
	{	// position合法
		GetElem(position, e);			// 用e返回被删除元素的值
		ElemType temElem;				// 临时元素
		for (int temPos = position + 1; temPos <= Length(); temPos++)
		{	// 被删除元素之后的元素依次左移
			GetElem(temPos, temElem); SetElem(temPos - 1, temElem);
		}
		count--;						// 删除后元素个数将自减1
		return true;					// 删除成功
	}
}

template <class ElemType>
bool SqList<ElemType>::Delete(int position)
// 操作结果:删除线性表的第position个元素,
//	position的取值范围为1≤position≤Length(),
//	position合法时返回true,否则返回false
{
	if (position < 1 || position > Length())
	{	// position范围错
		return false;					// 范围错
	}
	else
	{	// position合法
		ElemType temElem;				// 临时元素
		for (int temPos = position + 1; temPos <= Length(); temPos++)
		{	// 被删除元素之后的元素依次左移
			GetElem(temPos, temElem); SetElem(temPos - 1, temElem);
		}
		count--;						// 删除后元素个数将自减1
		return true;					// 删除成功
	}
}

template <class ElemType>
bool SqList<ElemType>::Insert(int position, const ElemType& e)
// 操作结果:在线性表的第position个元素前插入元素e,
//	position的的取值范围为1≤position≤Length()+1
//	如线性表已满,则返回false,
//	如position合法, 则返回true, 否则返回false
{
	if (count == maxSize)
	{	// 线性表已满返回false
		return false;
	}
	else if (position < 1 || position > Length() + 1)
	{	// position范围错
		return false;					// 范围错
	}
	else
	{	// 成功
		ElemType temElem;				// 临时元素
		for (int temPos = Length(); temPos >= position; temPos--)
		{	// 插入位置之后的元素右移
			GetElem(temPos, temElem); SetElem(temPos + 1, temElem);
		}
		count++;						// 插入后元素个数将自增1
		SetElem(position, e);			// 将e赋值到position位置处	
		return true;					// 插入成功
	}
}

template <class ElemType>
SqList<ElemType>::SqList(const SqList<ElemType>& source)
// 操作结果:由线性表source构造新线性表——复制构造函数模板
{
	maxSize = source.maxSize;			// 最大元素个数
	count = source.count;				// 线性表元素个数
	elems = new ElemType[maxSize];		// 分配存储空间
	for (int temPos = 1; temPos <= source.Length(); temPos++)
	{	// 复制数据元素
		elems[temPos - 1] = source.elems[temPos - 1];	// 复制元素值
	}
}

template <class ElemType>
SqList<ElemType>& SqList<ElemType>::operator =(const SqList<ElemType>& source)
// 操作结果:将线性表source赋值给当前线性表——重载赋值运算符
{
	if (&source != this)
	{
		maxSize = source.maxSize;		// 最大元素个数
		count = source.count;			// 线性表元素个数
		delete[]elems;					// 释放存储空间
		elems = new ElemType[maxSize];	// 分配存储空间
		for (int temPos = 1; temPos <= source.Length(); temPos++)
		{	// 复制数据元素
			elems[temPos - 1] = source.elems[temPos - 1];	// 复制元素值
		}
	}
	return *this;
}
#endif

测试程序:

#include <iostream>				// 编译预处理命令
using namespace std;			// 使用命名空间std 
#include "sq_list.h"			// 顺序表类

template <class ElemType>
void Show(const ElemType& e)
// 操作结果: 显示数据元素
{
	cout << e << "  ";
}

int main()
{
	char select = '0';
	SqList<double> la, lb;
	double e;
	int position;

	while (select != '7')
	{
		cout << endl << "1. 生成线性表.";
		cout << endl << "2. 显示线性表.";
		cout << endl << "3. 检索元素.";
		cout << endl << "4. 设置元素值.";
		cout << endl << "5. 删除元素.";
		cout << endl << "6. 插入元素.";
		cout << endl << "7. 退出";
		cout << endl << "选择功能(1~7):";
		cin >> select;
		switch (select)
		{
		case '1':
			cout << endl << "输入e(e = 0时退出):";
			cin >> e;
			while (e != 0)
			{
				la.Insert(la.Length() + 1, e);
				cin >> e;
			}

			break;
		case '2':
			lb = la;
			lb.Traverse(Show<double>);
			break;
		case '3':
			cout << endl << "输入元素位置:";
			cin >> position;
			if (!la.GetElem(position, e))
				cout << "元素不存储." << endl;
			else
				cout << "元素:" << e << endl;
			break;
		case '4':
			cout << endl << "输入位置:";
			cin >> position;
			cout << endl << "输入元素值:";
			cin >> e;
			if (!la.SetElem(position, e))
				cout << "位置范围错." << endl;
			else
				cout << "设置成功." << endl;
			break;
		case '5':
			cout << endl << "输入位置:";
			cin >> position;
			if (!la.Delete(position, e) && !la.Delete(position))
				cout << "位置范围错." << endl;
			else
				cout << "被删除元素值:" << e << endl;
			break;
		case '6':
			cout << endl << "输入位置:";
			cin >> position;
			cout << endl << "输入元素值:";
			cin >> e;
			if (!la.Insert(position, e))
				cout << "位置范围错." << endl;
			else
				cout << "成功。" << e << endl;
			break;
		}
	}

	return 0;               		// 返回值0, 返回操作系统
}


例程均来自清华大学出版社 《数据结构与算法》(C++版)作者:唐宁九 游洪跃。主要学习模板(模板类、模板函数)在这里的使用,如果原理知识还不懂,可以找本数据结构的数看看,不管是用C、C++还是java实现的,数据结构的原理是通用的,只是呈现形式不同。

相关文章:

  • C++数据结构之单链表
  • (8)STL算法之替换
  • (9)STL算法之逆转旋转
  • NFS安装使用
  • STL之map(关联式容器)
  • STL之unordered_map
  • 动态规划
  • 算法分析
  • 编写一个函数,实现将char类型的字符串,循环右移n个位置
  • 类构造、析构、赋值函数示例
  • 数组指针指针数组
  • LeeCode 20.有效的括号
  • LeeCode 26 删除排序数组中的重复项,返回数组新长度
  • LeeCode 27 移除元素,返回数组新长度
  • LeeCode 2125 合并两个(K个)有序链表
  • 10个确保微服务与容器安全的最佳实践
  • Android Studio:GIT提交项目到远程仓库
  • android图片蒙层
  • ERLANG 网工修炼笔记 ---- UDP
  • JAVA_NIO系列——Channel和Buffer详解
  • JavaScript 基本功--面试宝典
  • laravel 用artisan创建自己的模板
  • Node + FFmpeg 实现Canvas动画导出视频
  • Nodejs和JavaWeb协助开发
  • SpiderData 2019年2月13日 DApp数据排行榜
  • windows-nginx-https-本地配置
  • 订阅Forge Viewer所有的事件
  • 简单基于spring的redis配置(单机和集群模式)
  • 离散点最小(凸)包围边界查找
  • 利用jquery编写加法运算验证码
  • 聊一聊前端的监控
  • 深入浏览器事件循环的本质
  • 深入浅出webpack学习(1)--核心概念
  • 推荐一个React的管理后台框架
  • 正则学习笔记
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​ArcGIS Pro 如何批量删除字段
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #{} 和 ${}区别
  • (1)常见O(n^2)排序算法解析
  • (16)Reactor的测试——响应式Spring的道法术器
  • (3)nginx 配置(nginx.conf)
  • (C语言)fgets与fputs函数详解
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (Python) SOAP Web Service (HTTP POST)
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (附源码)spring boot基于小程序酒店疫情系统 毕业设计 091931
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (转)jdk与jre的区别
  • .htaccess配置常用技巧
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .Net Remoting(分离服务程序实现) - Part.3