数据结构——顺序表(定义、实现)
一、顺序表的定义
顺序表:用顺序存储的方式实现线性表的顺序存储。把逻辑上相邻的元素存储在物理位置上也相邻的存储单位中,元素之间的关系由存储单元的邻接关系来体现。
二、顺序表的实现————静态分配
(1)基础代码:
#define MaxSize 10 //定义最大长度
typedef struct{
Elem Type data[MaxSize]; //用静态的“数组”存放数据元素
int length; //顺序表的当前长度
}SqList; //顺序表的类型定义(静态分配方式) Sq:squence————顺序,序列
(2)具体代码显示:
#include <stdio.h>
#definr MaxSize 10 //定义最大长度
typedef struct{
int data[MaxSize]; //用静态的“数组”存放数据元素
int length; //顺序表的当前长度
}SqList; //顺序表的类型定义
// 基本操作——初始化——顺序表
void InitList(SqList & L){
for (int i=0; i<MaxSize;i++)
{
L.data[i] = 0; //将所有数据元素设为默认初始值
}
L.length = 0; //顺序表的初始长度为0 ,这一步是必须的操作
}
int main(){
SqList L; //声明一个顺序表
InitList(L); //初始化顺序表
//尝试“违规”打印整个data数组
for(int i=0;i<MaxSize;i++) //这种方式很容易出现脏数据,需要把MaxSize换成L.length
{
printf("data[%d]=%d\n",i,L.data[i]);
}
//这种访问方式也不够好,更好的做法是使用基本操作来访问各个数据元素 GetElem(L,i)
return 0;
}
注意:若不进行初始化设置,即没有设置数据元素的默认值,内存会有遗留的“脏数据”
(3)如果“数组”存满了怎么办?
可以放弃治疗,顺序表的表长刚开始确定后就无法更改(存储空间是静态的)
三、顺序表的实现————动态分配
(1)基础代码:
#define InitSize 10 //顺序表的初始长度
typedef struct{
ElemType *data; //指示动态分配数组的指针
int MaxSize; //顺序表的最大容量
int length; //顺序表的当前长度
}SqList; //顺序表的类型定义(动态分配方式)
key:动态申请和释放空间
C语言————malloc、free函数
L.data = (Elem Type *)malloc(sizeof(Elem Type)* InitSize);
malloc函数返回一个指针,需要强制转换为你定义的数据元素类型指针
malloc 函数的参数,指明要分配多大的连续内存空间
(2)具体代码显示:
#include <stdlib.h>
#include <stdio.h>
#define InitSize 10 //默认最大的长度
typedef struct{
int *data; //指示动态分配数组的指针
int MaxSize; //初始化顺序表
int length; //顺序表的当前长度
}SqListp;
void InitList(SqList & L)
{
//用malloc函数申请一片连续的空间
L.data = (int *)malloc (InitSize*sizeof(int));
L.length = 0;
L.MaxSize = InitSize;
}
//增加动态数组的长度
void IncreaseSize(SqList & L,int len)
{
int *p =L.data; //p与data指向同一片空间
L.data = (int*)malloc((L.MaxSize+len)*szieof(int)); //开辟了一片新的空间,data指向新的空间的首地址
for(int i=0;i<length;i++)
{
L.data[i]= p[i]; //将数据复制到新区域 时间开销大
}
L.MaxSize = L.MaxSize + len; //顺序表的最大长度增加len
free (p); //释放原来的内存空间
}
int main()
{
SqList L; //声明一个顺序表
InitList(L); //初始化顺序表
//...往顺序表中随便插入几个元素...
IncreaseSzie(L,5);
return 0;
}
四、顺序表的实现
顺序表的特点:
(1)随机访问,即可以在0(1)时间内找到i个元素
代码实现:data[i-1];
静态分配、动态分配都一样
(2)存储密度高,每个节点只存储数据元素
(3)拓展容量不方便(即便采取动态分配的方法实现,拓展长度的时间复杂度也比较高)
(4)插入、删除不方便,需要移除大量元素