一、动态顺序表简介
具有一对一关系的数据在逻辑上构成线性结构,在逻辑上用线性表表示。
线性表的概念和特点,我就不罗嗦了。
线性表的物理存储可以用顺序表(占用连续空间)和链表实现,
顺序表又可以分为静态顺序表和动态顺序表,
静态顺序表就是数组,一旦定义,大小固定,因为在许多语言中数组名是常数;
动态顺序表就是动态数组,用指针变量存储申请到的空间的首地址,可以改变。
二、用什么方式表示动态顺序表
如果学生学习过C++,则选择C++的模板类表示数据结构上的抽象数据类型最为合适;
如果学生没有学习过C++,有两种选择
一种是大部分课本选择的,用C语言的结构体;
一种是我在这里推荐的,用C++中的结构体模板。
C语言中的结构体中只可以定义成员变量;C++的结构体中可以定义成员变量和成员函数;
C++的结构体也可以采用模板的形式,以处理通用类型。
C++结构体的语法要比类的语法简单。
三、顺序表的简单实现
我们这里用C++的结构体模板作为抽象数据类型,实现动态顺序表的部分操作,
使初学者能够从代码的级别掌握顺序表的思想。
#include<iostream>//C++的输入输出
using namespace std;
template<typename ElemType> struct SqList
{
ElemType *elem;//存储空间首地址
int length;//线性表中元素个数
int listsize;//当前线性表的最大容量
int InitList()
{//对顺序表进行初始化
elem=new ElemType[16];//这个正整数随便设置
if(0==elem)
return 0;
listsize=16;//初始时,有16个空间
length=0; //没有数据元素
}
int enlarge()
{//当L的空间不足时,本函数功能:将L的空间翻倍
//如果成功返回1,失败返回0
ElemType *newbase=new ElemType[listsize*2];
if(0==newbase)
return 0;
for(int i=0;i<length;i++)
newbase[i]=elem[i];
delete []elem;
elem=newbase;
listsize=listsize*2;
return 1;
}
int ListInsert(int i,ElemType x)
{//在顺序表的第i个位置插入元素x
//如果成功,返回1,否则返回0
if(i<0||i>length) return 0;
if(length==listsize)
{
int flag=enlarge();
if(flag==0)return 0;
}
int j;
for(j=length-1;j>=i;j--)
elem[j+1]=elem[j];
elem[i]=x;
length++;
return 1;
}
int pop_i(int i)
{//删除下标为 i 的数据
if(i<0 || i>=length)//如果删除位置不合法
return -1;
else
{
for(int j=i+1;j<=length-1;j++)
elem[j-1]=elem[j];//元素前移 一位
length--;
return 1;
}
}
int find(ElemType e)
{//在顺序表中查找元素e是否存在,
//如果存在返回对应的下标
//否则返回-1
for(int i=0;i<=length-1;i++)
{
if(elem[i]==e)
return i;
}
return -1;
}
void print()
{
for(int i=0;i<length;i++)
cout<<elem[i]<<" ";
cout<<endl;
}
};
int main()
{
SqList<int> LA;
LA.InitList();
for(int i=0;i<20;i++)
{
LA.ListInsert(i,i);
}
LA.print();
LA.pop_i(0);
LA.print();
cout<<LA.find(5)<<endl;
return 0;
}