C++数据结构之线性表——顺序表
一、线性表
概念
1.线性表是最简单的一类线性数据结构
2.线性表是由n个数据元素组成的有限序列,相邻数据元素之间存在着序偶关系,可以写成:
(a1, a2,…ai-1, ai, ai+1,…an-1, an)
其中,ai是表中元素,i表示元素ai的位置,n是表的长度
特性
线性表中的元素具有相同的特性,属于同一数据对象,如:
1.26个字母的字母表: (A,B,C,D,…,Z)
2.近期每天的平均温度:(30℃, 28℃, 29℃,…)
ADT定义
ADT List
{
数据对象:数据元素同属一个集合
数据关系:序偶关系
基本操作:
Init创建、Destroy销毁、
Clear清空、Empty是否为空、
Length取表长度、Get取表元素、Locate查找元素
Prior取元素前驱、Next取元素后继
Insert插入元素、Delete删除元素
Traverse遍历表
}
二、顺序表
概念
i.顺序表的构成
1.顺序表是线性表的顺序存储表示
2.顺序表采用一组地址连续的存储单元依次存储线性表的数据元素
ii.顺序表的元素位置
顺序表数据元素的位置:
location(a_i) = location( a_(i-1) ) + l
location(a_i) = location(a_1)+(i-1)*l ( l表示元素占用的内存单元数 )
举例:
一个线性表第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是( )
(A)110 (B)108(C)100 (D)120
根据上面的元素位置公式我们可以知道第五个元素的位置location(a_5)=100+(5-1)*2=108,故选B
实现
顺序表类
#define initsize 100//初始化表的存储容量
#define sizeincrease 10//单次增加容量的大小
class sqlist
{
public:
int length;//顺序表的当前长度
int listsize;//为顺序表分配的储存空间大小
int *element;//指向顺序表的第一个元素(即存储空间基址)
int initelement[initsize];//顺序用于表初始化后的各个存储单元的初始值
void init();//创建顺序表
void destroy();//销毁顺序表
void clear();//清空顺序表
bool empty();//检测是否为空
int getlength();//获取顺序表的长度
int get(int index);//获取下标为index的元素
int locate(int ele);//查找元素ele所在位置的下标
int prior(int index);//取下标为index的元素的前驱元素
int next(int index);//取下标为index的元素的后继元素
void insert(int ele,int index);//在下标为index的元素位置插入元素ele,原位置的元素依次后移一位
void remove(int index);//删除下标为index的元素,下标index后的元素依次向前移动一位
void traverse();//遍历表
void print();//打印表
void push(int ele);//从表尾插入元素
void batchpush();//批量压入数据
};
初始化顺序表
void sqlist::init()
{
element=(int*)malloc(initsize*sizeof(int));//分配内存大小为initsize的空间
for (int i = 0; i < initsize; i++)//将各存储单元的初始值赋值给initelement[]
{
initelement[i]=element[i];
}
if (!element)
{
cout<<"内存空间分配失败!"<<endl;
}
else
{
length=0;//初始化后顺序表是空的,故当前长度为0
listsize=initsize;//初始化的存储容量就等于initsize
cout<<"存储空间分配成功!"<<endl;
}
}
销毁顺序表
void sqlist::destroy()
{
if (!element)//如果分配内存空间失败则无需销毁
{
cout<<"无需销毁顺序表!"<<endl;
}
else//分配成功就销毁顺序表
{
delete element;
cout<<"顺序表销毁成功!"<<endl;
}
}
清空顺序表
void sqlist::clear()
{
for (int i = 0; i < length; i++)//将各个元素值赋值为初始化时的值即为清空
{
element[i]=initelement[i];
}
length=0;//此时顺序表的长度为0
}
判断顺序表是否为空
bool sqlist::empty()
{
return length==0?true:false;
}
得到顺序表长度
int sqlist::getlength()
{
return length;
}
获取下标为index的元素
int sqlist::get(int index)
{
return element[index];
}
定位到第一个数据为ele的元素下标
int sqlist::locate(int ele)
{
int i;
for (; i < length; i++)
{
if (ele==element[i])
{
break;
}
}
return i;
}
取下标为index的元素的前驱元素
int sqlist::prior(int index)
{
if (index==0)
{
cout<<"第一个元素没有前驱元素!"<<endl;
return 0;
}
else
{
return element[index-1];
}
}
取下标为index的元素的后继元素
int sqlist::next(int index)
{
if (index==length-1)
{
cout<<"最后一个元素没有后继元素!"<<endl;
return length-1;
}
else
{
return element[index+1];
}
}
在下标为Index的位置插入元素ele
注意,在插入的时候我们要注意的是是否超出了顺序表的容量,如果超过容量就需要进行扩容,因此我们在头文件需要导入<malloc.h>,并使用里面的realloc函数来进行扩容
void sqlist::insert(int ele,int index)
{
if (length==listsize)
{
cout<<"顺序表空间已满,自动扩容!"<<endl;
listsize+=sizeincrease;
element=(int*)realloc(element,sizeof(listsize));
}
for (int i = length; i > index; i--)
{
element[i]=element[i-1];
}
element[index]=ele;
length+=1;
}
删除下标为index的元素
void sqlist::remove(int index)
{
if (length==0)
{
cout<<"顺序表为空无法移除元素!"<<endl;
}
else
{
for (int i = index; i < length-index; i++)
{
element[i]=element[i+1];
}
element[length-1]=initelement[length-1];//将顺序表最后一个元素赋值为该位置初始值
length-=1;
}
}
遍历顺序表
void sqlist::traverse()
{
if (length==0)
{
cout<<"顺序表为空无法遍历!"<<endl;
}
else
{
for (int i = 0; i < length; i++)
{
//遍历要做的操作
}
}
}
打印顺序表
void sqlist::print()
{
cout<<"============sqlist==========="<<endl;
for (int i = 0; i < length; i++)
{
cout<<"element["<<i<<"]:"<<element[i]<<endl;
}
cout<<"============================="<<endl;
}
从表尾插入元素ele
void sqlist::push(int ele)
{
if (length==0)
{
element[0]=ele;
}
else
{
element[length]=ele;
}
length++;
}
批量压入数据
void sqlist::batchpush()
{
int symbol=0;
int tempele;
while (symbol==0)
{
cin>>tempele;
if (tempele!=-1)
{
push(tempele);
}
else
{
symbol=1;
}
}
cout<<"批量数据压入完毕!"<<endl;
}
全部代码
#include<stdio.h>
#include<iostream>
#include<malloc.h>
#define initsize 10
#define sizeincrease 10
using namespace std;
class sqlist
{
public:
int length;//顺序表的当前长度
int listsize;//为顺序表分配的储存空间大小
int *element;//指向顺序表的第一个元素(即存储空间基址)
int initelement[initsize];//顺序用于表初始化后的各个存储单元的初始值
void init();//创建顺序表
void destroy();//销毁顺序表
void clear();//清空顺序表
bool empty();//检测是否为空
int getlength();//获取顺序表的长度
int get(int index);//获取下标为index的元素
int locate(int ele);//查找元素ele所在位置的下标
int prior(int index);//取下标为index的元素的前驱元素
int next(int index);//取下标为index的元素的后继元素
void insert(int ele,int index);//在下标为index的元素位置插入元素ele,原位置的元素依次后移一位
void remove(int index);//删除下标为index的元素,下标index后的元素依次向前移动一位
void traverse();//遍历表
void print();//打印表
void push(int ele);//从表尾插入元素
};
void sqlist::init()
{
element=(int*)malloc(initsize*sizeof(int));//分配内存大小为initsize的空间
for (int i = 0; i < initsize; i++)//将各存储单元的初始值赋值给initelement[]
{
initelement[i]=element[i];
}
if (!element)
{
cout<<"内存空间分配失败!"<<endl;
}
else
{
length=0;//初始化后顺序表是空的,故当前长度为0
listsize=initsize;//初始化的存储容量就等于initsize
cout<<"存储空间分配成功!"<<endl;
}
}
void sqlist::destroy()
{
if (!element)//如果分配内存空间失败则无需销毁
{
cout<<"无需销毁顺序表!"<<endl;
}
else//分配成功就销毁顺序表
{
delete element;
cout<<"顺序表销毁成功!"<<endl;
}
}
void sqlist::clear()
{
for (int i = 0; i < length; i++)//将各个元素值赋值为初始化时的值即为清空
{
element[i]=initelement[i];
}
length=0;//此时顺序表的长度为0
}
bool sqlist::empty()
{
return length==0?true:false;
}
int sqlist::getlength()
{
return length;
}
int sqlist::get(int index)
{
return element[index];
}
int sqlist::locate(int ele)
{
int i;
for (; i < length; i++)
{
if (ele==element[i])
{
break;
}
}
return i;
}
int sqlist::prior(int index)
{
if (index==0)
{
cout<<"第一个元素没有前驱元素!"<<endl;
return 0;
}
else
{
return element[index-1];
}
}
int sqlist::next(int index)
{
if (index==length-1)
{
cout<<"最后一个元素没有后继元素!"<<endl;
return length-1;
}
else
{
return element[index+1];
}
}
void sqlist::insert(int ele,int index)
{
if (length==listsize)
{
cout<<"顺序表空间已满,自动扩容!"<<endl;
listsize+=sizeincrease;
element=(int*)realloc(element,sizeof(listsize));
}
for (int i = length; i > index; i--)
{
element[i]=element[i-1];
}
element[index]=ele;
length+=1;
}
void sqlist::remove(int index)
{
if (length==0)
{
cout<<"顺序表为空无法移除元素!"<<endl;
}
else
{
for (int i = index; i < length-index; i++)
{
element[i]=element[i+1];
}
element[length-1]=initelement[length-1];//将顺序表最后一个元素赋值为该位置初始值
length-=1;
}
}
void sqlist::traverse()
{
if (length==0)
{
cout<<"顺序表为空无法遍历!"<<endl;
}
else
{
for (int i = 0; i < length; i++)
{
//遍历要做的操作
}
}
}
void sqlist::print()
{
cout<<"============sqlist==========="<<endl;
for (int i = 0; i < length; i++)
{
cout<<"element["<<i<<"]:"<<element[i]<<endl;
}
cout<<"============================="<<endl;
}
void sqlist::push(int ele)
{
if (length==0)
{
element[0]=ele;
}
else
{
element[length]=ele;
}
length++;
}
void sqlist::batchpush()
{
int symbol=0;
int tempele;
while (symbol==0)
{
cin>>tempele;
if (tempele!=-1)
{
push(tempele);
}
else
{
symbol=1;
}
}
cout<<"批量数据压入完毕!"<<endl;
}
int main()
{
sqlist sl;
sl.init();
sl.destroy();
return 0;
}
三、总结
本文先对线性表进行了介绍,并且对本文的关键顺序表进行了介绍以及实现,在后面的文章还会对更多的线性表进行介绍和实现,如果喜欢本文的话麻烦动动你的小手点点赞哈!