创建线性表顺序存储类MyArrayList

  1. 创建线性表顺序存储类MyArrayList

    目的:通过对线性表顺序存储类的创建和应用,增强面向对象程序设计和顺序表的理解与应用实践。

内容:

(1)MyArrayList存储空间的大小以及存储数据类型根据用户需求自行确定。

(2) 提供初始化数据功能(即创建该对象时可以通过指定数组将初始参数传入该对象)

(3)提供插入一个元素功能;

(4)提供删除一个元素功能;

(5)提供根据指定关键字排序功能;(默认升序,也能降序,提供用户自己选择方式。)

(6)提供根据指定关键字查找功能,查找结果返回该元素位置,-1表示查找失败。

(7)提供两个有序顺序表合并功能;

(8)提供根据指定关键字,返回指定第K大的元素位置;

(9)提供显示顺序表中各元素功能;

(提示:顺序表中元素可能是简单数据类型,也可能是复合数据类型:比如自定义结构体类型,所以有指定关键字一说。)

(9)给出各个功能的测试样例。

报告要求:

  (1)仔细观察设计中的各种现象及出现的问题。分析产生各种现象的原因。寻找解决问题的办法。

  (2)报告应至少包括带注释的程序清单、输出的结果及对各种现象的分析意见。

下面附上

SqList.h文件代码与cpp文件代码:

注意:为了避免link2019等错误的出现,我们将类的头文件与实现文件全部写在了头文件。

以下代码在VS2019上完美运行!

运行截图:

                                #pragma once
#include <iostream>
using namespace std;
constexpr auto MAXSIZE = 500;	   //最大存储容量,便于批量操作
typedef int ElemType;			   //定义数据类型,便于批量操作
template <class T>
class SqList
{
public:
	SqList();					   //无参构造函数
	SqList(T elems[], int n);	   //有参构造器,便于快速创建指定元素数量的线性表
	~SqList();	//C					   //析构函数
	void CreatList();			   //新建一个顺序表
	void UnionList1(SqList L1, SqList L2);//合并顺序表,不去重
	void UnionList2(SqList L1, SqList L2);//合并顺序表,去重
	void LocateElem(ElemType e);//L1   //按元素查找:成功则返回元素的序号(从1开始),失败则返回-1
	int ListLength();//C			   //顺序表的长度
	int GetElem(int i, T& e);//L1	   //查找第i个位置的元素//按位置查找
	void ListInsert(int i,T e);//L	   //在第i个位置插入元素
	void ListDelete(int i, T& e);//L 1 //删除第i个位置的元素
	void ListEmpty();//L1			   //判空
	void clearList();//C			   //清空顺序表
	void display();	//C	1		   //显示当前的顺序表
	void Sort_Lead();			   //排序选择引导函数
	void QS( T E[],int m, int n);  //快速排序(升序)
	void R_Kth(int k);//C		   //返回第K大元素的值
	void QST(T  s[], int l, int r);//快速排序(降序)
	T data[MAXSIZE];//由于在使用插入删除等功能时,需时时用到此数据域,故定为public
	//下标从0开始,但是自然计数就是1,第1个元素其实就是下标为0的元素
private:
	int length;
	//所有的查找、删除、添加等功能全部基于length的大小,如果length不适当则操作无法进行
};
template<class T>
SqList<T>::SqList()//初始化
{
	length = 0;
}
template<class T>
SqList<T>::SqList(T elems[], int n)//有参构造器,功能同CreateList
{
	
	if (n > MAXSIZE)
	{
		cout << "传入的顺序表长度超出最大范围,只接收了前" << MAXSIZE << "个元素" << endl;
		length = MAXSIZE;
	}
	else
		length = n;
	for (int i = 0; i < length; i++)
		data[i] = elems[i];//将传入的T类型数组在有效长度范围内逐个赋值给data域
}
template<class T>
SqList<T>::~SqList()
{
	clearList();
}
template<class T>
void SqList<T>::CreatList()
{
	p3:
	cout << "插入多少个元素(0-"<<MAXSIZE<<")?" << endl;
	cin >> length;
	cout << "进行初始化..." << endl;
	if (length<0 || length>MAXSIZE)
	{
		length = 0;
		cout << "创建失败,重新输入!" << endl;
		goto p3;
	}
	int w;
	p4:
	cout << "请选择你想要创建的方式:1.数组自动赋值(升序赋值) 2.手动逐个输入" << endl;
	cin >> w;
	switch (w) {
	case 1:
		for (int i = 1; i <= length; i++)
		{
			data[i - 1] = i;
		}
		cout << "创建完成!" << endl;
		break;
	case 2:
		for (int i = 1; i <= length; i++)
		{
			        cout<<"请输入顺序线性表的第"<<i<<"个元素:";
					cin >> data[i - 1];
		}
		cout << "创建完成!" << endl;
		break;
	default:
		cout << "输入有误,请重新输入!" << endl;
		goto p4;
		break;
	}
	
}
template<class T>
void  SqList<T>::LocateElem(ElemType e)//成功则返回元素的序号(从1开始),失败则返回-1
{
	int n = 0;
	ElemType INST[MAXSIZE];
	for (int i = 0; i < length; i++) {
		if (data[i] == e)
		{
			INST[n] = i;
			n++;
		}
	}
	if (!n > 0)
		cout << "查找失败!" << endl;
	else 
	{
		cout << "所查找元素元素共在线性表中发现" << n << "个" << endl
			<< "在位置 ";
		for (int j = 0; j < n; j++) {
			cout << INST[j] +1<< " 、";//因为自然计数从1开始,而数组下标从0开始
		}
		cout << "找到" << e << endl;
	}
}

template<class T>
void SqList<T>::UnionList1(SqList L1, SqList L2)
{
	int i, j;
	if ((L1.ListLength() == 0 && L2.ListLength() == 0))
	{
		cout << "双表为空!合并操作无效!" << endl;
		return;
	}
	else if (L1.ListLength() + L2.ListLength() > MAXSIZE)
	{
			cout << "数据过大,合并后,顺序表的长度超过最大范围" << endl;
			return;
	}
	for (i = 0; i < L1.length; i++)
	{
		data[i] = L1.data[i];
	}

	for (j = 0; j < L2.length; j++)
		{
			data[i] = L2.data[j];
			i++;
		}
	length = i;
	cout << "合并完成!" << endl;
}

template<class T>
inline void SqList<T>::UnionList2(SqList L1, SqList L2)
{
	UnionList1(L1, L2);
	ElemType elem;
	cout << "开始去重" << endl;
	QS(data, 0, length-1);
	for (int i = 0; i < length-1; i++) {
		if (data[i] == data[i + 1]) {
			ListDelete(i + 1, elem);
		}
	}
}
template<class T>
int  SqList<T>::ListLength()
{
	return length;
}
template<class T>
int SqList<T>::GetElem(int i, T& e)
{
	if (length == 0 || i<1 || i>length)
		return -1;
	e = data[i - 1];
	cout << "已找到!位置" << i << "是" << e << endl;
	return 0;
}
template<class T>
void SqList<T>::ListInsert(int i, T e)
{
	if (length == MAXSIZE || i<1 || i>length + 1) {
									 //线性表满,或者i的范围不在合理范围内时返回错误
		cout << "线性表满,或者i的范围不在合理范围内!" << endl;
		return;//理论上我们认可空表的插入,所以不设置专门提示
	}
	if (i <= length)				 //不在表尾
	{
									 //插入位置的后续元素后移一位
		for (int k = length - 1; k >= i - 1; k--)
			data[k + 1] = data[k];	 // 倒序挪动位置,避免覆盖问题
	}
	data[i - 1] = e;				 //插入元素
	length++;
	cout << "插入成功!" << endl;
}
template<class T>
void SqList<T>::ListDelete(int i, T& e)
{
	if (length == 0 || i<1 || i>length) {//线性表空,或者i的范围不在合理范围内时返回错误
		cout << "线性表空,或者i的范围不在合理范围内!" << endl;
		return;
	}
	e = data[i - 1];				//取出元素
	if (i <= length)				//不在表尾
	{								//插入位置的后续元素前移一位
		for (int k = i - 1; k < length - 1; k++)
			data[k] = data[k + 1];	// 倒序挪动位置,避免覆盖问题
	}
	length--;
	cout << e<<"删除成功!" << endl;
}
template<class T>
void SqList<T>::ListEmpty()
{
	if (length == 0)
		cout << "线性表为空!" << endl;
	cout << "线性表不为空!" << endl;
}
template<class T>
void SqList<T>::clearList()
{
	length = 0;

}
template<class T>
void SqList<T>::display()
{
	for (int i = 0; i < length; i++)
		cout << data[i] << "  ";
	cout << endl;
}

template<class T>
inline void SqList<T>::Sort_Lead()
{
	p5:
	cout << "请输入你的选择:1.升序2.降序";
	int k;
	cin >> k;
	switch (k) {
	case 1:QS(data, 0, length - 1);
		cout << "排序完成,新顺序是:";
		display();
		break;
	case 2:
		QST(data, 0, length - 1);
		cout << "排序完成,新顺序是:";
		display();
		break;
	default:
		cout << "输入有误,请重新选择!";
		goto p5;
		break;
	}
}

template<class T>
void SqList<T>::QS(T s[], int l, int r)
{

	if (l < r)
	{
		int i = l, j = r;
		T x = s[l];					   //自定类型参数
		while (i < j)
		{
			while (i < j && s[j] >= x) // 从右向左找第一个小于x的数
				j--;
			if (i < j)
				s[i++] = s[j];

			while (i < j && s[i] < x) // 从左向右找第一个大于等于x的数
				i++;
			if (i < j)
				s[j--] = s[i];
		}
		s[i] = x;
		QS(s, l, i - 1);			  // 递归调用 
		QS(s, i + 1, r);
	}
}
template<class T>
void SqList<T>::R_Kth(int k)
{
	cout << "将会对data域进行排序..." << endl;
	QS(data, 0, length - 1);
	cout << "第"<<k<<"大元素是:" << data[length-k] << endl;
}
template<class T>
inline void SqList<T>::QST(T s[], int l, int r)
{

	if (l < r)
	{
		int i = l, j = r;
		T x = s[l];
		while (i < j)
		{
			while (i < j && s[j] <= x) // 从右向左找第一个大于x的数
				j--;
			if (i < j)
				s[i++] = s[j];

			while (i < j && s[i] > x) // 从左向右找第一个小于等于x的数
				i++;
			if (i < j)
				s[j--] = s[i];
		}
		s[i] = x;
		QST(s, l, i - 1);			  // 递归调用 
		QST(s, i + 1, r);
	}
}

以下为CPP文件代码:

#include <iostream>
#include<string> 
#include<windows.h>
#include "SqList.h"
using namespace std;
int main()
{
	SqList<ElemType> list;//使用自定类型可以实现批量切换
	ElemType elem;
	ElemType elems1[9] = { 5,11,23,32,4,27,6,7,777 };
	ElemType elems2[10] = { 5,61,79,8,9,10,11,1,12,225 };
	SqList<ElemType> list1(elems1, 9);
	SqList<ElemType> list2(elems2, 10);//均是有参构造器的调用
	SqList<ElemType> list3;
	//string elems3[7] = { "while","if","else","do","for","switch","case" };
	//SqList<string> list4(elems3, 7);
	//list4.display();
	//list4.Sort_Lead();
p1:
	cout << "请选择你要操作的选项:" << endl << endl;
	cout << "\t1.初始化线性表" <<"\t2.删除元素" << "\t3.插入元素"<<endl << endl;
	cout << "\t4.按元素查找"<<"\t5.按位置查找" << "\t6.输出线性表"<<endl << endl;
	cout << "\t7.获取当前表长" <<"\t8.清空顺序表"<< "\t9.快速排序线性表(升序/降序)"<<endl << endl;
	cout << "\t9.快速排序线性表(升序/降序)" <<"\t10.返回第K大元素的值"<< endl << endl;
	cout << "\t11.合并顺序表(另起:不去重/去重)" <<"\t12.退出"<< endl << endl;
	int k;
ElemType ins;
	cin >> k;
	system("CLS");
switch (k)
{
case 1:
	list.CreatList();
	break;
case 2:
	cout << "请输入要删除元素的序号:";
	cin >> k;
	list.ListDelete(k, elem);
	break;
case 3:
	cout << "请输入要插入的位置和要插入的元素:";
	cin >> k>>ins;
	list.ListInsert(k, ins);
	break;
case 4:
	cout << "请输入要查找的元素值:";
	cin >> ins;
	list.LocateElem(ins);
	break;

case 5:
	cout << "请输入要查找的位置序号:";
	cin >> k;
	k=list.GetElem(k, elem);
	if(k==-1)
		cout << "查找失败!" << endl;
	break;
case 6:
	list.display();
	break;
case 7:
	cout << "表长为:" << list.ListLength() << endl;
	break;
case 8:
	list.clearList();
	cout << "清空完成!" << endl;
	break;
case 9:
	list.Sort_Lead();
	break;
case 10:
	cout << "请输入k值:";
	cin >> k;
	list.R_Kth(k);
	break;
case 11: 
	system("CLS");
	cout << "此功能不影响之前所创建的线性表!" << endl;
	cout << "稍等,正在对线性表进行有参构造..." << endl;
	Sleep(3000);

	cout << "合并前的两个表为:" << endl;
	list1.display();
	list2.display();
p2:
	cout << "请选择合并方式:1.不去重 2.去重" << endl;
	cin >> k;
	switch (k)
	{
	case 1:
		list3.UnionList1(list1,list2);
		cout << "该顺序表尚未有序化,不能保证数据有序性,是否进行有序化?(键入:Y / N )" << endl;
		char C;
		cin >> C;
		if (C == 'Y' || C == 'y')
			list3.Sort_Lead();
		break;
	case 2:
		cout << "去重后的结果时有序数列!" << endl;
		list3.UnionList2(list1, list2);
		break;
	default:
		cout << "输入有误,请重新输入!" << endl;
		goto p2;
		break;
	}
	cout << "该表的长度为:" << list3.ListLength() << endl;
	list3.display();
	break;
	//除此之外的输入全作无效处理
case 12:
	cout << "执行退出" << endl;
	return 0;
default:
	cout << "输入有误!请重新输入!" << endl;
	goto p1;
	break;
}
goto p1;
return 0;
}

VS2019可用,代码为作者原创,转载请注明出处。

                                      痛击白嫖党!!!!!!

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值