顺序表
总结
物理储存:用一段地址连续的存储单元依次存储线性表的数据元素。
注意:
线性表元素的序号和存放它的数组下标之间存在对应关系:线性表下标起始为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;
}