数据结构-顺序表的定义和基本操作

169 阅读2分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路

定义

用顺序存储的方式实现线性表的顺序存储, 把逻辑上相邻的元素存储在物理位置也相邻的存储单元中, 元素之间的关系由存储单元的邻接关系来体现 在这里插入图片描述

分配方式

静态分配
#define MAX 100
ElemType elem [MAX];//表
int n;				//数据元素个数你<MAX

结构体分配方式

#define MAX 100
typedef struct{
	ElemType elem [MAX];
	int length;	//元素个数,即表长
}Sqlist;

存储空间的大小: MAX×sizeof(ElemType)

动态分配
#define LIST_INIT_SIZE 100//存储空间的初始分配量
#define LISTINCREMENT 10  //分配增量

typedef struct{
	ElemType *elem;//存储区域的基址
	int length;	   //当前表的长度
	int listsize;  //当前已分配的存储容量
}SqList;		   //顺序表类型


C语言申请

L.data=(ElemType *)malloc(sizeof(ElemType)*InitSize)

顺序表的基本操作

初始化一个顺序表Init_Sq(&L)


Status InitList_Sq(SqList &L){//构造一个空的顺序表
	L.elem=(ElemType*)malloc(LIST_INIT_SIZE 100*sizeof(ElemType));
	if(!L.elem) exit(OVERFLOW);//存储空间分配失败
	L.length=0;
	L.listsize=LIST_INIT_SIZE ;
	return OK;
}

本算法的时间复杂度是O(1)

销毁顺序表DestroyLIst_Sq(&L)释放L占用的内存空间


void DestroyList_Sq(SqList &L){
	free(L.elem);
	L.elem=NULL;
	L.length=0;
	L.listsize=0;
}

本算法的时间复杂度是O(1)

判断是否为空表ListEmpty_Sq(L)

int ListEmpty_Sq(SqList L){
	return (L.length==0);
}

若L为空表, 返回1, 否则返回零

输出顺序表 DispList_Sq(L)

int DispList_Sq(SqList L){
	if(ListEmpty_Sq(L)) return -1;
	for(i=0;i<L.length;i++){
		printf(L.elem[i]);
	}
	return 1;
}

插入数据元素ListInsert_Sq(&L,i,e)

在顺序表L的第i个位置前插入新元素e

Status ListInsert_Sq(SqList &L, int i, ElemType e){
	//在顺序表L的第i个位置前插入新元素e
	if(i<1||i>L.length+1){//i的值不合法
		return -1;	
	}
	if(L.length>=L.InitList){//上溢时,增加空间
			newbase=(ElemType*)realloc(L.elem,L.(Listsize+LISTINCREMENT)*sizeof(ElemType));
			if(!newbase){
				exit(OVERFLOW);
			}
			L.elem=newbase;
			L.ListInit+=LISTINCREMENT;
	}
	for(j=L.length;j>=i;j--){
		L.elem[i] = L.elem[j-1];	//元素后移
	}
	L.elem[j-1]=e;				//第i个位置前插入新元素e
	++L.length;					//顺序表增加1
	return OK;
}

在插入数据元素的过程中, 我们涉及到一个时间复杂度的问题

最好的情况: 新的元素插到表尾, 不需要移动元素,循环0次,时间复杂度为O(1)

最坏的情况: 新的元素查到表头, 需要将原有的n个元素全都向后移动i=1, 循环n次,时间复杂度为O(n)

平均情况: 假设新元素插入到任意一个位置相同, 则长度为n的线性表中插入一个节点时, 所需节点的移动次数

在这里插入图片描述 平均时间复杂度为O(n)

删除数据元素ListDelete_Sq(&L,i,&e)

删除顺序表第i个元素

Status ListDelete_Sq(SqList &L,int i,ElemType &e){
	if(i<1||i>L.length){
		return ERROR;
	}
	for(j=i;j<L.length;j++){
		L.elem[j-1]=L.elem[j];
	}
	--L.length;
	return OK;
}

时间复杂度:最好的时间复杂度O(1), 最坏的时间复杂度O(n), 平均移动次数(n-1)/2; 平均时间复杂度O(n)

按位查找操作

获取表L中第i个位置的元素的值

#defined InitSize 10	//顺序表的初始长度
typedef struct{
	ElemType * data;	//指示动态分配数组的指针
	int MaxSize;		//顺序表的最容量
	int length;			//顺序表的当前长度
}SqList;
ElemType GetElem(SqList L, int i){
	return L.data[i-1];
}

时间复杂度时O(1)

按值查找操作LocateElem()

在表L中查找具有给定关键字值的元素

#defined InitSize 10	//顺序表的初始长度
typedef struct{
	ElemType * data;	//指示动态分配数组的指针
	int MaxSize;		//顺序表的最容量
	int length;			//顺序表的当前长度
}SqList;
int LocateElem()(SqList L, ElemType e){
	for(int i=0;i<L.length;i++){
		if(L.data[i]==e){
			return i+1;		//数组下标的i元素值等于e, 其返回i+1;
		}else{
			return 0;	//退出循环, 说明查找失败
		}
	}
}

平均比较次数是 (n+1)/2 平均时间复杂度是O(n)