线性表--顺序表的实现及其相关操作

顺序表


总结

物理储存:用一段地址连续的存储单元依次存储线性表的数据元素。

注意:
  线性表元素的序号和存放它的数组下标之间存在对应关系:线性表下标起始为1,而数组下标起始位0,于是线性表的第i个元素是要存储在数组下标为i-1的位置。

特点:(顺序存储结构适合元素个数稳定的操作)
1.逻辑上相邻的数据元素,物理存储位置也相邻,且存储空间需要预先分配;
2.存储空间连续,即允许元素的随机访问;
3.存储密度大,内存中存储的全部是数据元素;
4.要访问特定元素,可以使用索引访问,时间复杂度为 O(1);
5.要想在顺序表中插入或删除一个元素,都涉及到之后所有元素的移动,因此时间复杂度为 O(n)。(除非操作在表尾进行)

优点:
1.存取速度高效,通过下标来直接存储,允许随机访问;
2.方法简单,使用数组容易实现;
3.不用为了表示节点间的逻辑关系而增加额外的存储开销。

缺点:
1.在顺序表中做插入、删除操作时,平均移动表中的一半元素,因此对n较大的顺序表来说,这些操作效率低;
2.需要预先分配足够的存储空间,若过大可能会导致顺序表后部大量闲置;而过小,又会造成溢出。

顺序表相关操作的源码:

//线性表下标从1开始,区别数组从0开始

#include "stdafx.h"
#include<iostream>
using namespace std;

#define MAXSIZE 20
#define Node ElemType
#define ERROR 0
typedef int DataType;
//创建一个节点类
class Node
{
public:
	DataType data;
};
//创建一个顺序表类
class SqList
{
private:
	int len;//长度
	ElemType * elem;//基地址
public:
	SqList();          //初始化顺序表
	~SqList();         //销毁顺序表
	void Create(int n);       //创建一个顺序表
	void Traverse();          //遍历顺序表
	ElemType GetElemByIndex(int i);    //按下标查找顺序表中的元素
	bool isEmpty();                 //判断顺序表是否为空
	bool isFull();                  //判断顺序表是否满
	int GetLength();                //获取顺序表的长度
	int GetElemByElem(DataType data);    //按值查找顺序表中的元素
	void InsertSqList(int i, DataType data);  //向顺序表中某位置插入新数据
	void InsertSqListAtHead(DataType data);      //在顺序表头部插入数据
	void InsertSqListAtEnd(DataType data);       //向顺序表尾部插入数据
	void DeleteElem(int i);              //删除指定位置的元素值
	void DeleteElemAtElem(DataType data);   //按值删除元素
	void Clear();                    //删除所有元素,清空顺序表
	void DeleteAtHead();                 //在头部删除元素
};
//初始化顺序表
SqList::SqList()
{
	elem=new ElemType[MAXSIZE];
	if (!elem)
	{
		exit(OVERFLOW);//溢出
	}
	len=0;
}
//析构函数销毁顺序表
SqList::~SqList()
{
	delete[] elem;
}
//创建一个顺序表
void SqList::Create(int n)
{
	if (n<0)//输入数值有误
	{
		cout<<"输入节点个数不合法!"<<endl;
		exit(EXIT_FAILURE);
	}
	else
	{
		for (int i = 0; i < n; i++)
		{
			cout<<"请输入第"<<i+1<<"个节点元素:";
			cin>>elem[i].data;
		}
		len=n;
	}
}
//遍历顺序表
void SqList::Traverse()
{
	for (int i = 0; i < len; i++)
	{
		cout<<"第"<<i+1<<"个元素的值是 "<<elem[i].data<<endl;
	}
}
//根据下标查找顺序表中的元素
ElemType SqList::GetElemByIndex(int i)
{
	if (i<1||i>len)
	{
		cout<<"不在查询范围内!"<<endl;
	}
	else
	{
		return elem[i-1];
	}
}
//判空
bool SqList::isEmpty()
{
	if (len==0)
	{
		return true;
	}
	return false;
}
//判满
bool SqList::isFull()
{
	if (len==MAXSIZE)
	{
		return true;
	}
	return false;
}
//获取顺序表长度
int SqList::GetLength()
{
	return len;
}
//给定元素值,在顺序表中查找匹配该值
int SqList::GetElemByElem(DataType data)
{
	for (int i = 0; i < len; i++)
	{
		if (elem&&elem[i].data==data)
		{
			return i+1;
		}
		if (i==len-1)//无匹配
		{
			return -1;
		}
	}
}
//向顺序表中某位置插入新数据
void SqList::InsertSqList(int i, DataType data)
{
	if (i<1||i>len+1)
	{
		cout<<"插入的下标位置不合法!"<<endl;
	}
	else if (len>MAXSIZE)
	{
		cout<<"已经达到最大长度!"<<endl;
	}
	else
	{
		for (int j = len-1; j >= i-1; j --)
		{
			elem[j+1]=elem[j];
		}
		elem[i-1].data=data;
		len++;
	}
}
//在顺序表头部插入数据
void SqList::InsertSqListAtHead(DataType data)
{
	for (int i = len-1; i >= 0; i --)
	{
		elem[i+1]=elem[i];
	}
	elem[0].data=data;//第一个位置插入
	len++;
}
//向顺序表尾部插入数据
void SqList::InsertSqListAtEnd(DataType data)
{
	if (len>MAXSIZE)
	{
		cout<<"已经达到最大长度!"<<endl;
	}
	else
	{
		elem[len].data=data;//最后一个位置插入
		len++;
	}
}
//删除指定位置的元素值
void SqList::DeleteElem(int i)
{
	if (i<1||i>len)
	{
		cout<<"输入的下标不合法!"<<endl;
	}
	else
	{
		for (int j = i; j < len-1; j++)
		{
			elem[j-1]=elem[j];
		}
		len--;
	}
}
//按值删除元素值
void SqList::DeleteElemAtElem(DataType data)
{
	int i=0;
	while (elem[i].data!=data && i<len)
	{
		i++;
	}
	for (int index = i; index < len-1; index++)
	{
		elem[index]=elem[index+1];
	}
	len++;
}
//删除所有元素,清空顺序表
void SqList::Clear()
{
	for (int i = len; i > 0; i--)
	{
		elem[i]=elem[i-1];
		len--;
	}
}
//在头部删除元素
void SqList::DeleteAtHead()
{
	for (int i = 1; i <= len-1; i++)
	{
		elem[i-1]=elem[i];
	}
	len--;
}
int _tmain(int argc, _TCHAR* argv[])
{
	SqList list;
	int i;
	cout<<"创建一个顺序表"<<endl;
	int n;
	cout << "请输入顺序表的元素个数: ";
	cin >> n;
	list.Create(n);
	cout<<"---------------------------------------"<<endl;
	cout << "1.遍历顺序表\n2.通过下标获取元素\n3.查找要查询的元素的下标\n4.通过下标插入元素\n5.通过下标删除一个元素\n6.获取顺序表的长度\n7.删除所有元素\n8.判断顺序表是否为空\n9.判断顺序表是否满\n10.根据数据删除节点\n11.在头部插入数据\n12.在头部删除数据\n13.从顺序表尾部插入数据\n0.退出" << endl;
	do
	{
		cout << "请选择一个操作: " ;
		cin >> i;
		switch (i)
		{
		case 1:
			{
				list.Traverse();
				break;
			}
		case 2:
			{
				int n;
				cout << "请输入将要获取元素的下标: ";
				cin >> n;
				ElemType getElemByIndex = list.GetElemByIndex(n);
				cout << getElemByIndex.data << endl;
				break;
			}
		case 3:
			{
				DataType data;
				cout << "请输入将要查找元素的值: ";
				cin >> data;
				cout<<"该元素的下标为:"<<list.GetElemByElem(data)<<endl;
				break;
			}
		case 4:
			{
				int index;
				DataType insertData;
				cout << "请输入要插入的数据的位置: ";
				cin >> index;
				cout << "请输入要插入的数据: ";
				cin >> insertData;
				list.InsertSqList(index, insertData);
				break;
			}
		case 5:
			{
				int deleteIndex;
				cout << "请输入要删除的数据的下标: ";
				cin >> deleteIndex;
				list.DeleteElem(deleteIndex);
				break;
			}
		case 6:
			{
				cout<<list.GetLength()<<endl;
				break;
			}
		case 7:
			{
				list.Clear();
				break;
			}
		case 8:
			{
				if (list.isEmpty() == 1) {
					cout << "顺序表为空!" << endl;
				}
				else
				{
					cout << "顺序表不为空!" << endl;
				}
				break;
			}
		case 9:
			{
				if (list.isFull() == 1) {
					cout << "顺序表已满!" << endl;
				}
				else
				{
					cout << "顺序表未满!" << endl;
				}
				break;
			}
		case 10:
			{
				DataType data1;
				cout << "请输入要删除的数据: ";
				cin >> data1;
				list.DeleteElemAtElem(data1);
				break;
			}
		case 11:
			{
				DataType data2;
				cout << "请输入要在头部插入的数据: ";
				cin >> data2;
				list.InsertSqListAtHead(data2);
				break;
			}
		case 12:
			{
				list.DeleteAtHead();
				break;
			}
		case 13:
			{
				DataType data3;
				cout << "请输入要在末尾插入的数据: ";
				cin >> data3;
				list.InsertSqListAtEnd(data3);
				break;
			}
		default:break;
		}
	}while (i!=0);
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值