线性结构是简单且常用的数据结构,而线性表是一种典型的数据结构。
一般情况下,如果需要在程序中存储数据,最简单、最有效的方法是把它们存放在线性表中。只有当需要组织和搜索大量数据时,才会考虑使用更复杂的数据结构。
在所有的数据结构中,最简单的是线性表。通常,定义线性表为n(n>=0)个数据元素的一个有限的序列。记为:
L = (a(1),···,a(i),a(i+1),···,a(n))
其中,L是表名,a(i)是数据元素,是不可再分割的原子数据,亦成为结点或表项。
线性表是一个有限序列,意味着表中的各个结点是相继排列的,且每两个相邻结点之间有直接前驱和直接后继的关系;线性表中存在惟一的第一个结点和最后一个结点,第一个结点没有前驱,最后一个结点没有后继,每个结点至多只有一个直接前驱并且至多只有一个直接后继。
线性表的存储表示有两种:顺序存储方式和链表存储方式。用顺序存储方式实现的线性表称为顺序表,是用数组作为表的存储结构的。这里我们讲顺序表。
顺序表的定义:把线性表中的所有结点按照其逻辑顺序依次存储到从计算机存储中指定存储位置开始的一块连续存储空间中。
特点:(1)在 顺序表中各个结点的逻辑顺序与其存放的物理顺序一致,即第i个结点存储于第i个物理位置(1<=i<=n)。
(2)对顺序表中所有结点,既可以进行顺序访问,也可以进行随机访问。也就是时候,既可以从表的第一个结点开始 逐个访问,也可以按照结点序号直接访问。
下面给出顺序表ADT的C++实现:
一、顺序表的基本操作
1.构造函数
通过指定sz,定义数组的长度。
LinearList::LinearList(int sz){
//构造函数,通过指定size,定义数组长度
if(sz>0){
data = new T[sz];//分配连续空间
if(data!=NULL){//分配成功
MaxSize = sz;
last = -1;
}
else{
cerr<<"存储分配错误!"<<endl;
exit(0);
}
}
}
2.查找指定元素
这里在表中从前向后顺序查找。
int LinearList::Search(T &x) const{
//搜索函数:在表中从前向后顺序查找x
int i = 0;//起始位置
while(i<=last&&data[i]!=x){
i++;
}
if(i>last){
return -1;//没找到
}
else{
return i+1;//找到
}
}
3.插入操作
顺序表的插入操作比较简单,假设顺序表最后一个元素的下标是last,被插入的元素是x,要插入到下标为i的位置,只需要将原顺序表中下标为i到last的结点往后顺移一位,然后再将x插入下标为i的位置即可。
void LinearList::Insert(int i,T &x){
//i为下标,不是序号
if(last==MaxSize-1){
cerr<<"顺序表已满无法插入!"<<endl;
exit(1);
}
if(i<0||i>last+1){
cerr<<"参数i越界出错!"<<endl;
exit(1);
}
last++;
for(int j=last;j>i;j--){//移动元素
data[j] = data[j-1];
}
data[i] = x;//在第i项处插入x
cout<<"插入成功!"<<endl;
}
4.删除操作
删除操作的思想和插入操作相似,假设线性表最后一个元素的下标为last,要删除下标为i的元素,只需要将下标为i+1到last的结点往前顺移一位即可。
//删除下标为i的元素
int LinearList::Delete(int i){
if(i<0||i>last){
cerr<<"参数i越界出错!"<<endl;
exit(1);
}
if(i>=0){
last--;//表长度-1
for(int j=i;j<=last;j++){//向前移动元素
data[j] = data[j+1];
}
cout<<"删除成功!"<<endl;
return 1;//删除成功
}
}
5.获取元素x之前的元素
//获取x元素之前的元素
T LinearList::GetPrior(T &x){
if(Length()==0){
cout<<"表已空!"<<endl;
return 404;
}
else if(data[0]==x){
cout<<"该元素是线性表第一个元素,没有前驱元素!"<<endl;
return 404;
}
else if(Search(x)!=-1){
return data[Search(x)-2];
}
}
6.获得元素x的下标
T LinearList::GetNext(T &x){
if(Length()==0){
cout<<"表已空!"<<endl;
return 404;
}
else if(data[last]==x){
cout<<"该元素是顺序表的最后一个元素,没有后继元素!"<<endl;
return 404;
}
else if(Search(x)!=-1){
return Search(x);
}
}
7.打印顺序表
void LinearList::PrintList(){
for(int i=0;i<=last;i++){
cout<<data[i]<<" "<<endl;
}
cout<<endl;
}
8.清空顺序表(利用析构函数)
~LinearList(){delete[] data;}
9.求顺序表长度操作
//返回线性表中元素的个数
int Length() const {return last+1;}
二、完整的ADT和函数操作
1.数据结构的定义和基本操作函数的声明
/*
顺序表ADT
*/
#include <iostream>
#include <cstdlib>
using namespace std;
typedef double T;
class LinearList{
public:
int last;
int LinearListLength;//线性表长度
int MaxSize;//允许线性表最大的元素个数
int LinearListLast;//线性表最后一个元素的下标
T *data;//动态存储的数组存储顺序表
public:
LinearList(int sz);
~LinearList(){delete[] data;}
//返回线性表中元素的个数
int Length() const {return last+1;}
//返回元素x在表中的位置
int Search(T &x) const;
//在位置i插入元素x
void Insert(int i,T &x);
//删除值为x的元素
int Delete(int i);
//表空否
int IsEmpty(){return last==-1;}
//判断是否满
int IsFull(){return last==MaxSize-1;}
//获得第i个元素
T GetData(int i){return data[i-1];};
//取值为x的前驱元素
T GetPrior(T &x);
//取值为x的后继元素
T GetNext(T &x);
//输出线性表
void PrintList();
};
2.操作函数的具体实现
LinearList::LinearList(int sz){
//构造函数,通过指定size,定义数组长度
if(sz>0){
data = new T[sz];//分配连续空间
if(data!=NULL){//分配成功
MaxSize = sz;
last = -1;
}
else{
cerr<<"存储分配错误!"<<endl;
exit(0);
}
}
}
int LinearList::Search(T &x) const{
//搜索函数:在表中从前向后顺序查找x
int i = 0;//起始位置
while(i<=last&&data[i]!=x){
i++;
}
if(i>last){
return -1;//没找到
}
else{
return i+1;//找到
}
}
void LinearList::Insert(int i,T &x){
//i为下标,不是序号
if(last==MaxSize-1){
cerr<<"顺序表已满无法插入!"<<endl;
exit(1);
}
if(i<0||i>last+1){
cerr<<"参数i越界出错!"<<endl;
exit(1);
}
last++;
for(int j=last;j>i;j--){//移动元素
data[j] = data[j-1];
}
data[i] = x;//在第i项处插入x
cout<<"插入成功!"<<endl;
}
//删除下标为i的元素
int LinearList::Delete(int i){
if(i<0||i>last){
cerr<<"参数i越界出错!"<<endl;
exit(1);
}
if(i>=0){
last--;//表长度-1
for(int j=i;j<=last;j++){//向前移动元素
data[j] = data[j+1];
}
cout<<"删除成功!"<<endl;
return 1;//删除成功
}
}
//获取x元素之前的元素
T LinearList::GetPrior(T &x){
if(Length()==0){
cout<<"表已空!"<<endl;
return 404;
}
else if(data[0]==x){
cout<<"该元素是线性表第一个元素,没有前驱元素!"<<endl;
return 404;
}
else if(Search(x)!=-1){
return data[Search(x)-2];
}
}
T LinearList::GetNext(T &x){
if(Length()==0){
cout<<"表已空!"<<endl;
return 404;
}
else if(data[last]==x){
cout<<"该元素是顺序表的最后一个元素,没有后继元素!"<<endl;
return 404;
}
else if(Search(x)!=-1){
return Search(x);
}
}
void LinearList::PrintList(){
for(int i=0;i<=last;i++){
cout<<data[i]<<" "<<endl;
}
cout<<endl;
}
本文深入探讨了线性表这一基本数据结构的概念及其在程序设计中的应用,重点讲解了顺序表的存储方式、基本操作及其实现细节,包括构造函数、查找、插入、删除等操作。
653

被折叠的 条评论
为什么被折叠?



