C++实现简单顺序表

news/2024/5/20 8:54:02 标签: 顺序表, C++, 类的应用

          顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。即线性表采用顺序存储的方式存储就称之为顺序表。在C语言中,我们通过创建一个结构体的方式来实现了顺序表,在C++中可通过创建一个类的形式来创建一个顺序表

直接来看代码:

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

typedef int DataType;
class SeqList
{
public:
	// 思考两种方式的优缺点 
	SeqList(DataType* array, size_t size)//构造函数
		: _array(new DataType[size])
		, _capacity(size)
		, _size(size)
	{
		// 1、循环逐个搬移-缺陷:效率低 正确性 
		for (size_t i = 0; i < size; ++i)
			_array[i] = array[i];

		// 2、优点:效率高--->问题?---可能会出错 
		//memcpy(_array, array, size*sizeof(array[0])); 
	}

	// 三大big 
	SeqList(const SeqList& s);
	SeqList& operator=(const SeqList& s);//拷贝构造函数
	~SeqList()//析构函数
	{
		if (_array)
		{
			delete[] _array;
			_size = 0;
			_capacity = 0;
		}
	}

	void PushBack(int data);//后增
	void PopBack();//后删
	void Insert(size_t pos, DataType data);//任意位置增
	void Erase(size_t pos);//任意位置删
	size_t Size()const;//求顺序表大小
	size_t Capacity()const;//求顺序表容量
	bool Empty()const;//判断顺序表是否为空
	DataType& operator[](size_t index);//[]操作符重载
	const DataType& operator[](size_t index)const;

	DataType& Front();// 返回顺序表中的第一个元素 
	const DataType& Front()const; 
	
	DataType& Back();// 返回顺序表中最后一个元素
	const DataType& Back()const;

	void Clear();// 清空顺序表中的所有元素 

	// 将顺序表中元素个数改变到newSize 
	void ReSize(size_t newSize, const DataType& data = DataType());
	//输出运算符重载
	friend ostream& operator<<(ostream& _cout, const SeqList& s);

private:
	void _CheckCapacity();
private:
	DataType* _array;
	size_t _size;
	size_t _capacity;
};

//拷贝构造
SeqList::SeqList(const SeqList& s)
{
	if (s._array != _array)
	{
		_array = new DataType[s._capacity];
		_size = s._size;
		_capacity = s._capacity;

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

//重载=
SeqList& SeqList::operator=(const SeqList& s)
{
	if (s._array != _array)
	{
		_size = s._size;
		_capacity = s._capacity;

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

//后增
void SeqList::PushBack(int data)
{
	if (_size < _capacity)
	{
		_array[_size] = data;
		_size += 1;
	}

	else
	{
		DataType * temp = new DataType[_capacity + _size];

		for (size_t i = 0; i < _size; i++)
		{
			temp[i] = _array[i];
		}

		temp[_size] = data;
		_capacity += _size;
		_size++;

		delete[] _array;
		_array = temp;
	}
}

//后删
void SeqList::PopBack()
{
	if (_size == 0)
	{
		return;
	}
	else
	{
		_size--;
	}
}

//任意位置增
void SeqList::Insert(size_t pos, DataType data)
{
	if (pos < _size)
	{
		if (_size < _capacity)
		{
			//将pos位置及之后的往后挪一个位置
			for (size_t i = _size; i>=pos; i--)
			{
				_array[i] = _array[i - 1];
			}

			_array[pos] = data;
			_size++;
		}

		else if (_size==_capacity)//增加元素就需要开辟新的空间
		{
			DataType * temp = new DataType[_capacity + _size];
			size_t i = 0;

			for (i = 0; i < _size; i++)//拷贝原来的元素
			{
				temp[i] = _array[i];
			}

			_array[pos] = data;

			delete[] _array;
			_array = temp;
		}
	}
	else
	{
		cout << "输入位置有误\n";
	}
}

//任意位置删
void SeqList::Erase(size_t pos)
{
	//将Pos位置的数据覆盖掉(前挪)
	for (size_t i = pos; i < _size; i++)
	{
		_array[i] = _array[i + 1];
	}
	_size--;
}

size_t SeqList::Size()const
{
	return _size;
}

size_t SeqList::Capacity()const
{
	return _capacity;
}

DataType& SeqList::operator[](size_t index)
{
	DataType * temp = _array;
	return temp[index];
}

const DataType& SeqList::operator[](size_t index)const
{
	DataType * temp = _array;
	return temp[index];
}

// 返回顺序表中的第一个元素 
DataType& SeqList::Front()
{
	assert(0 != _size);
	return _array[0];
}

const DataType& SeqList::Front()const
{
	assert(0 != _size);
	return _array[0];
}

// 返回顺序表中最后一个元素 
DataType& SeqList::Back()
{
	assert(0 != _size);
	return _array[_size - 1];
}

const DataType& SeqList::Back()const
{
	assert(0 != _size);
	return _array[_size - 1];
}

// 将顺序表中元素个数改变到newSize 
void SeqList::ReSize(size_t newSize, const DataType& data)
{
	if (newSize <= _capacity)
	{
		_size = newSize;
	}
	else
	{
		size_t i = 0;
		DataType * temp = new DataType[newSize];

		for (i = 0; i < _size; i++)
		{
			temp[i] = _array[i];
		}

		for (i = _size; i < newSize; i++)
		{
			temp[i] = data;
		}

		_size = newSize;
		_capacity = _size;
		delete[] _array;
		_array = temp;
	}
}

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

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

//对输出操作符<<重载
ostream& operator<<(ostream& _cout, const SeqList& s)
{
	for (size_t i = 0; i < s._size; i++)
	{
		_cout << s._array[i] << ' ';
	}

	_cout << endl;
	_cout << s._size << endl;
	_cout << s._capacity;
	return _cout;
}

DataType array[] = { 1, 2, 3, 4, 5 };
SeqList List(array,5);

void FunTest1()
{
	cout << List<<endl;

	cout << "后增" << endl;
	List.PushBack(6);
	List.PushBack(7);
	List.PushBack(8);
	cout << List << endl;

	cout << "后删" << endl;
	List.PopBack();
	List.PopBack();
	cout << List<<endl; 
	cout <<  endl;

	cout << "任意位置增、删" << endl;
	List.Insert(2, 7);
	cout << List << endl;
	List.Erase(3);
	cout << List << endl;
}

void FunTest2()
{
	cout << List << endl;

	size_t size = List.Size();
	cout << "size=" <<size << endl;

	size_t capacity = List.Capacity();
	cout << "capacity=" << capacity << endl;

	List.ReSize(8, 9);
	cout << "重置后" << endl;
	cout << List << endl;
}
void FunTest3()
{
	cout << List << endl;

	DataType ret1 = List.Front();
	cout << "first data is:" << ret1 << endl;

	DataType ret2 = List.Back();
	cout << "last data is:" << ret2 << endl;

	cout << List[1] << endl;
}

void FunTest4()
{
	cout << List << endl;

	List.Clear();
	cout << "cleared" << endl;

	bool ret = List.Empty();
	if (ret)
	{
		cout << "EMPTY" << endl;
	}
	else
	{
		cout << "NOT EMPTY" << endl;
	}
}

int main()
{
	FunTest1();//测试后增后删,任意位置增,删
	//FunTest2();//测试求大小、容量,重置容量
	//FunTest3();//测试获取首位、末位,任意位置元素
	//FunTest4();//测试清空函数及判断是否为空
	return 0;
}

说明:对于主函数里面调用的测试函数,想要测试哪部分函数功能就将相应的测试函数取消注释,这样更有利于观测其函数功能。



PS:欢迎提出任何建议,谢谢!



http://www.niftyadmin.cn/n/1014835.html

相关文章

郁闷--防火墙若的祸

今天是这么长时间来开始正式工作的第一天,早上去机房把两台机器换了下,然后就回公司了,昨天就听说今天要上机器了,满高兴的.因为好长时间都没服务器上了,今天算是开张了&#xff0c;以后就有希望了.早上2个客户带着服务器来到我们公司,老大给他们分配了ip,然后我帮他们把基本的…

QQ2007 Beta4来了,还不是一个“钱”字

今晚打开Firefox上网逛&#xff0c;看到QQ2007 Beta4版本于今日发布了&#xff0c;之前就听说推迟又推迟发布。在网上看了一下别人的新功能试用说明&#xff0c;还不就是更新一些无谓的东西&#xff0c;一个字——钱。一个即时通信工具搞得乱七八糟&#xff0c;大部分无谓的功能…

C++简单实现双链表

首先&#xff0c;来了解一下什么是双向链表。官方解释是这样的&#xff1a;双向链表也叫双链表&#xff0c;是链表的一种&#xff0c;它的每个数据结点中都有两个指针&#xff0c;分别指向直接后继和直接前驱。所以&#xff0c;从双向链表中的任意一个结点开始&#xff0c;都可…

C语言和C++的区别(函数重载)

C和C的区别主要分为三部分&#xff1a; 接下来详细介绍一下函数部分的区别 1、返回类型 2、参数列表 此外&#xff0c;在C中还支持缺省参数&#xff0c;而C语言不支持。 什么是缺省参数呢&#xff1f; 缺省参数是声明或定义时为函数的参数指定一个默认值。在调用函数时&#xf…

浅谈static关键字和extern关键字

一、static关键字 在C语言中 static可以用来修饰局部变量&#xff0c;全局变量和函数。不同情况下作用也不同。 &#xff08;1&#xff09;、修饰局部变量 局部变量一般存放于栈中&#xff0c;其作用域和生命周期都是在其定义的代码块内。当用static修饰局部变量时&#xff0c;…

一串珍珠

一  从哥本哈根通到柯尔索尔①的铁路&#xff0c;可算是丹麦唯一的铁路②&#xff0c;这等于是一串珠子&#xff0c;而欧洲却有不少这样的珠子。最昂贵的几颗珠子的名字是&#xff1a;“巴黎”、“伦敦”、“维也纳”和“那不勒斯”。但是有许多人不把这些大都市当做最美丽的…

项目一 简单的信息管理系统

(一) 基本界面设计<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /><?xml:namespace prefix v ns "urn:schemas-microsoft-com:vml" />(二) 数据库的建立和实现保存功能数据库设计界面如下&#xff1a;…

Cisco交换机端口安全介绍

在Cisco中有以下三种方案可供选择&#xff0c;方案1和方案2实现的功能是一样的&#xff0c;即在具体的交换机端口上绑定特定的主机的MAC地址&#xff08;网卡硬件地址&#xff09;&#xff0c;方案3是在具体的交换机端口上同时绑定特定的主机的MAC地址&#xff08;网卡硬件地址…