利用C++模版类创建顺序表

目录

前言:

     1.主要代码结构:

2.运行截图

​编辑

3.同级目录下data.txt文件

​编辑 

 4.源代码

linerlist.h

seqlist.h

seqlist.cpp

mian.cpp

5.总结

前言:

        本文章代码参考《数据结构:c++描述》,主要原因是因为发现自己c++的特性平时用的太少了,又由于大三了要迷迷糊糊开始考研了,数据结构作为必考内容所以要学习一下,虽然c++模版类的代码风格与考研数据结构代码有点不同指针方面用的少,但是可以了解编程的主要思想。其中这一次的demo采用了类继承、模版类、虚函数这方面的知识,我自己平时掌握的也不好。经常忘记,所以我认为作为一个合格的c++程序员,对于基本的c++知识都改掌握。俗话说基础不牢地动山摇。以后在编程路上会吃亏。我现在感觉这方面的亏,我吃了好多。但是又下不下决心再去系统的学习一遍。很少苦恼,希望看见我这段话的刚刚入门的同道能够引起重视。

       注意:demo采用vs2019编辑。

     1.主要代码结构:

2.运行截图

3.同级目录下data.txt文件

 

 4.源代码

linerlist.h

#pragma once
#ifndef  LINERLIST_H
#define  LINERLIST_H

template <typename T>
class LinerList 
{
public:
	LinerList() {};
	~LinerList() {};
	//将不涉及内容更改的函数设为常函数 使const对象也可以调用 
	virtual int Size() const = 0;						//查询表的容量
	virtual int Length() const = 0;						//查询表的长度
	virtual int Search(T& x) const = 0;					//查询表中是否存在x
	virtual int Locate(int i) const = 0;				//查询表中第i个元素
	virtual bool GetData(int i, T& x) const = 0;		//取第i个元素的值
	virtual void SetData(int i, T& x) = 0;				//修改第i个元素的值
	virtual bool Insert(int i, T& x) = 0;				//在第i个位置插入x
	virtual bool Remove(int i, T& x) = 0;				//删除第i元素
	virtual bool IsEmpty() const = 0;					//判空
	virtual bool IsFull() const = 0;					//判满
	virtual void Sort() = 0;							//排序
	virtual void Input() = 0;							//输入
	virtual void Output() = 0;							//输出
};

#endif // ! LINERLIST_H

seqlist.h

#ifndef SEQLIST_H
#define SEQLIST_H

#include "linerlist.h"
#include <iostream>
#include <cstdlib>
#include <cassert>	//作用是如果它的条件返回错误,则终止程序执行


const int defaultSize = 100;


void SeqList_demo();

template<typename T>
class SeqList :public LinerList<T>
{
public:
	SeqList(int size = defaultSize);
	SeqList(SeqList<T>& L);
	~SeqList()
	{
		delete[] data_;
	}

public:
	void reSize(int newSize);
	virtual int Size() const override;						//查询表的容量
	virtual int Length() const override;						//查询表的长度
	virtual int Search(T& x) const override;					//查询表中是否存在x
	virtual int Locate(int i) const override;				//查询表中第i个元素
	virtual bool GetData(int i, T& x) const override;		//取第i个元素的值
	virtual void SetData(int i, T& x) override;				//修改第i个元素的值
	virtual bool Insert(int i, T& x) override;				//在第i个位置插入x
	virtual bool Remove(int i, T& x) override;				//删除第i元素
	virtual bool IsEmpty() const override;					//判空
	virtual bool IsFull() const override;					//判满
	virtual void Sort() override;							//排序
	virtual void Input() override;							//输入
	virtual void Output() override;

	SeqList<T> operator = (SeqList<T>& L);

public:
	friend std::istream& operator >> (std::istream& in, SeqList<T>& R)
	{
		R.last_ = -1;
		while (!in.eof())
		{
			R.last_++;
			if (R.last_ == R.maxSize_)
			{
				R.reSize(2 * R.maxSize_);
				
			}
			assert(in >> R.data_[R.last_]);
			
		}
		return in;
	}
	friend std::ostream& operator << (std::ostream& out, SeqList<T>& R)
	{
		for (int i = 0; i <= R.last_; i++)
		{
			std::cout << "#" << i + 1 << ":\t" << R.data_[i] << std::endl;
		}
		return out;
	}
protected:
	T* data_;					//存放数组
	int maxSize_;				//最大可容纳数
	int last_;					//当前已存放的最后位置 相当于“尾指针”
};



template<typename T>
inline SeqList<T>::SeqList(int size)
{
	//构造函数,通过指定参数定义数组长度
	if (size > 0)
	{
		maxSize_ = size;
		last_ = -1;			    //空表
		data_ = new T[maxSize_];//创建顺序表数组
		if(data_ == NULL)
		{
		std::cerr << "分配空间失败" << std::endl;
		exit(1);
		}
	}
	else
	{
		maxSize_ = 0;
		last_ = -1;
		data_ = nullptr;
		std::cerr << "分配空间失败" << std::endl;
		exit(1);
	}
}

template<typename T>
inline SeqList<T>::SeqList(SeqList<T>& L)
{
	//拷贝构造函数,用参数表中给出的已有顺序表初始化新建的顺序表
	maxSize_ = L.Size();
	last_ = L.Length() - 1;
	T value;
	data_ = new T[maxSize_];	//创建顺序表
	if (data_ == nullptr)		//分配空间失败
	{
		std::cerr << "分配空间失败" << std::endl;
		exit(1);
	}
	for (int i = 1; i <= last_+1 ; i++)
	{
		L.GetData(i, value);   //获取第i位置的元素
		data_[i - 1] = value;
	}
}

template<typename T>
inline void SeqList<T>::reSize(int newSize)		//重新分配空间
{
	//扩充顺序表存储空间大小,新数组为newsize
	if (newSize <= 0)
	{
		std::cerr << "输入数据错误" << std::endl;
		return;
	}
	//输入新数组大小
	if (newSize != maxSize_)
	{
		T* newarray = new T[newSize];
		if (newarray == nullptr)
		{
			std::cerr << "输入数据错误" << std::endl;
			exit(1);
		}
		int n = last_+1;		//获取数组实际长度
		T* srcptr = data_;      //原数组首地址
		T* destptr = newarray;	//新数组首地址
		while (n--)
		{
			*destptr++ = *srcptr++; //拷贝
		}
		delete[] data_;				//删除原数组元素
		data_ = newarray;			//复制新数组
		maxSize_ = newSize;			//更新新表最大容量
	}
	else
	{
		std::cerr << "输入数据错误" << std::endl;
		exit(1);
	}
}

//获取最大容量
template<typename T>
inline int SeqList<T>::Size() const
{
	return this->maxSize_;      
}

//获取表长
template<typename T>
inline int SeqList<T>::Length() const
{
	return this->last_+1;
}

//搜索
template<typename T>
inline int SeqList<T>::Search(T& x) const
{
	for (int i = 0; i < last_ + 1; i++)
	{
		if (data_[i] == x)
		{
			return i + 1;
		}
	}
	return 0;
}

template<typename T>
inline int SeqList<T>::Locate(int i) const
{
	if (i >= 1 && i <= last_ + 1)
	{
		return i;
	}
	else
	{
		return 0;
	}
	
}

template<typename T>
inline bool SeqList<T>::GetData(int i, T& x) const
{
	if (i > 0 && i <= last_ + 1)
	{
		x = data_[i - 1];
		return true;
	}
	else
	{
		return false;
	}
	
}

template<typename T>
inline void SeqList<T>::SetData(int i, T& x)
{
	if (i > 0 && i <= last_ + 1)
	{
		data_[i - 1] = x;
	}

	return;
}

template<typename T>
inline bool SeqList<T>::Insert(int i, T& x)
{
	if (last_ == maxSize_ - 1)
	{
		return false;
	}
	if (i<0 || i>last_ + 1)
	{
		return false;
	}
	for (int j = last_; j>=i; j--)
	{
		data_[j + 1] = data_[j];     //移位
	}
	data_[i] = x;					//放入
	last_++;						//+1
	return true;
}

template<typename T>
inline bool SeqList<T>::Remove(int i, T& x)
{
	if (last_ == -1)    
	{
		return false;
	}
	if (i<1 || i>last_ + 1)
	{
		return false;
	}
	x = data_[i - 1];
	for (int j = i; j < last_; j++)
	{
		data_[j - 1] = data_[j];	
	}
	last_--;
	return true;
}

template<typename T>
inline bool SeqList<T>::IsEmpty() const
{
	return (this->last_ == -1);
}

template<typename T>
inline bool SeqList<T>::IsFull() const
{
	return (this->maxSize_ - 1);
}

template<typename T>
inline void SeqList<T>::Sort()
{
	for (int i = 1; i <= last_; i++)
	{
		for (int j = last_; j >= i; j--)
		{
			if(data_[j-1]>data_[j])
			{
				int temp = data_[j - 1];
				data_[j - 1] = data_[j];
				data_[j] = temp;
			}
			
		}
	}
}

template<typename T>
inline void SeqList<T>::Input()
{
	std::cout << "请输入创建的链表大小:";
	while (1)
	{
		assert(std::cin >> last_);
		last_--;
		if (last_ < 0)
		{
			std::cout << "输入错误,数字太小\n";
			std::cout << "请重新输入:";
		}
		else if(last_>maxSize_-1)
		{
			std::cout << "输入错误,数字太大\n";
			std::cout << "请重新输入:";
		}
		else
		{
			break;
		}
	}
	std::cout << "\n请输入顺序表中的数据:\n";
	for (int i = 0; i < last_ + 1; i++)
	{
		std::cout << "*" << i + 1 << ":";
		assert(std::cin >> data_[i]);
	}

}

template<typename T>
inline void SeqList<T>::Output()
{
	std::cout << "\n顺序表的长度是:" << last_ + 1 << std::endl;
	for (int i = 0; i <= last_; i++)
	{
		std::cout << "*" << i + 1 << ":\t" << data_[i] << std::endl;
	}

}

template<typename T>
inline SeqList<T> SeqList<T>::operator=(SeqList<T>& L)
{
	maxSize_ = L.Size();
	last_ = L.Length() - 1;
	delete[] data_;
	data_ = new T[maxSize_];
	if(data_ == nullptr)
	{
		std::cerr << "分配空间失败\n";
		exit(1);
	}

	for (int i = 1; i <= last_ + 1; i++)
	{
		data_[i - 1] = L.GetData(i);
	}

	return L;
}

#endif // !SEQLIST_H

 seqlist.cpp

#include "seqlist.h"
#include <fstream>
#include <cassert>
using namespace std;

void SeqList_demo()
{
	SeqList<int> list(30);
	ifstream fin("data.txt");
	assert(fin); //如果为空,就返回
	fin >> list;
	cout << "初始化文件:\n" << list << endl;
	list.Sort();
	cout << "排序之后\n" << list << endl;

	cout << "========================================\n";
	int i, elem;
	cout << "测试插入、删除、查找函数:\n";
	cout << "请通过控制台进行输入";
	cout << "退出当前功能请输入i的值不大于0\n";
	cout << "\n----------------------------------------\n";

	cout << "1.测试插入元素Insert(int i, T &elem):\n";
	while (1) {
		cout << "请在插入删除函数输入位置i和数据elem:";
		cin >> i >> elem;
		if (!cin) {
			cin.clear();
			cin.ignore(100, '\n');
			break;
		}
		if (i < 0)
		{
			cout << "退出成功!" << endl;
			break;
		}
		if (list.Insert(i, elem))
		{
			cout << "插入成功!\n";
		}
		else
		{
			cout << "插入失败!\n";
		}
	}
	cout << "\n插入之后的数据\n" << list << endl;

	cout << "----------------------------------------\n";
	cout << "2. 测试删除元素Remove(int i, T &elem):\n";
	while (1) {
		cout << "Input the index i in which you want to remove: ";
		cin >> i;
		if (!cin) {
			cin.clear();
			cin.ignore(100, '\n');
			break;
		}
		if (i < 0)
		{
			cout << "退出成功!" << endl;
			break;
		}
		if (list.Remove(i, elem))
		{
			cout << "元素 " << elem << " 已经被删除!\n";
		}
		else
		{
			cout << "删除失败!\n";
		}
	}
	cout << "\n删除之后\n" << list << endl;

	cout << "----------------------------------------\n";
	cout << "3.测试查找元素Search(T &elem):\n";
	while (1)
	{
		cout << "请输入你想要查找的元素: ";
		cin >> elem;
		if (!cin) {
			cin.clear();
			cin.ignore(100, '\n');
			break;
		}
		if (elem < 0)
		{
			cout << "退出成功!" << endl;
			break;
		}
		i = list.Search(elem);
		if (i != 0)
		{
			cout << "元素" << elem << " 是顺序表第" << i << "元素" << ".\n";
		}
		else
		{
			cout << "元素在顺序表内不存在!\n";
		}
	}
	cout << "\n----------------------------------------\n";
	cout << "测试结束" << endl;
}

mian.cpp

#include "seqlist.h"

#include <fstream>
#include <cassert>
using namespace std;


int main() {

	SeqList_demo();
	return 0;
}

5.总结

        以上就是项目的源代码,之后还会创作C语言版本的,便于自己理解,结合王道考研书后的内容来进行创作,我希望自己可以坚持下去。加油。废话很多一方面是自己激励自己,另一方面则是CSDN这个无法描述的审核机制。有着字数的要求。不让人开心。希望的这个内容能够帮助到大家。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开开心累兮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值