顺序表

线性表的理解

当线性表使用连续的内存空间来存储时,就是顺序表。

顺序表使用物理内存地址表示线性表中元素的前驱和后继关系。

优点

访问时可以根据内存物理地址访问,时间复杂度为O(1)

可以随机存取表中任一元素

缺点

在插入、删除某一元素时,需要移动大量元素

空间需要预申请,浪费存储空间

属于静态存储形式,数据元素的个数不能自由扩充

实现(C语言)

声明配置

定义程序执行的常量、变量依赖环境。使程序调整更灵活,修改时不用一处处的修改

#include <stdio.h>
#include <stdlib.h>

// 函数结果状态代码 
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;		// Status是函数的类型,也就是函数的返回值 
typedef char ElemType; 
#define MAXSIZE 5		// 定义宏表示线性表的长度 

定义结构体表示顺序表

实现的思路是,结构体的实例表示一个线性表(这与链表不同),由一个指针指向存储线性表元素存储的内存空间。

后续的操作都是作用在这个结构体实例上

/* 
	定义结构,表示顺序表类型
*/
typedef struct {
	ElemType *elem;
	int length;
}SqList;	

线性表初始化 

对已有的一个线性表实例进行初始化。申请一块连续的空间,使线性表实例的指针成员指向这块空间,

并记录线性表的成员数量为0

// 构造一个空的顺序表L   
Status InitList_Sq(SqList *L) {	
	L->elem = (ElemType *)malloc(MAXSIZE * sizeof(ElemType));
	if(!L->elem){	// 分配空间失败
		exit(OVERFLOW);		// 退出程序
	}		
	L->length = 0;	// 空表长度为0 
	return OK; 
} 

销毁线性表

将主动申请的、用来存储线性表成员的内存空间主动回收,之后

// 销毁线性表L
void DestroyList(SqList *L) {
	if (L->elem) {
		free(L->elem);
	}
	L->length = 0;
} 

清空线性表

在逻辑上将线性表实例已有的元素视作无效,则只需将线性表实例的表示长度的成员的值设置为0即可

// 清空线性表
void ClearList(SqList *L) {
	L->length = 0;
} 

线性表长度

// 求线性表长度
int GetLength(SqList L) {
	return L.length;
}

线性表判空

// 判断线性表是否为空
int IsEmpty(SqList L) {
	if (L.length == 0) {
		return 1;
	} else {
		return 0;
	}
} 

线性表插入

将某值插入到线性表某个位置上,需要先将该位置以及后面的所有值依次往后移一位,操作的时间复杂度为O(n)。

当线性表保存大量数据,而插入位置比较靠前时,则比较耗费时间,这也是线性表的痛点之一

Status ListInsert_Sq(SqList *L, int i, ElemType e) {
	int j;
	if (i < 1 || i > L->length + 1) {	// 值不合法 
		exit(ERROR); 
	}
	if (L->length == MAXSIZE) {	// 当前储存空间已满 
		exit(ERROR);
	} 
	for (j = L->length - 1; j >= i - 1; j--) {
		L->elem[j + 1] = L->elem[j];	// 插入位置及之后的元素后移 
	} 
	L->elem[i - 1] = e;
	L->length++;
	return OK; 
} 

线性表删除元素

删除某位置上的元素,将该位置之后的所有元素依次向前移一位,所以时间复杂度为O(n)

Status ListDelete_Sq(SqList *L, int i) {
	int j;
	if (i < 1 || i > L->length) {	// i值不合法 
		exit(ERROR);
	} 
//	printf("线性表的长度为:%d", L->length);
	for ( j = i; j < L->length; j++) {
		L->elem[j - 1] = L->elem[j];	// 被删除元素之后的元素前移
	} 
	L->length--; 
	return OK;
}

线性表取值

int GetElem(SqList *L, int i, ElemType *e) {
	if (i < 1 || i > L->length) {
		exit(ERROR);
	}
	*e = *(L->elem + i - 1);
	return OK;
} 

线性表查值

查询线性表内某值第一次出现的位置

int LocateElem(SqList L, ElemType e) {
	// 在线性表L中查找值为e的数据元素,返回其序号
	int i; 
	for(i = 0; i < L.length; i++) {
		if (L.elem[i] == e) {
			return i + 1;	// 查找成功,返回符号 
		}
	} 
	return 0;	// 查找失败,返回0 
} 

测试功能 

int main(int argc, char *argv[]) {
	int i;
	ElemType e;
	SqList list;
	InitList_Sq(&list);
	ListInsert_Sq(&list, 1, 'A');
	ListInsert_Sq(&list, 2, 'B');
	ListInsert_Sq(&list, 3, 'D');
	ListInsert_Sq(&list, 2, 'c');
	printf("长度为: %d\n", GetLength(list)); 
	GetElem(&list, 2, &e);
	printf("第%d位上的值为:%c\n", 2, e);
	if (IsEmpty(list)) { 
		printf("线性表为空!\n");
	} else {
		printf("线性表不为空!\n");
	} 
	ListDelete_Sq(&list, 3); 
	i = LocateElem(list, 'B');
	printf("元素B的位置为: %d\n", i);
	for (i = 0; i < list.length; i++) {
		printf("%c", list.elem[i]);		// []运算符返回的是元素值而不是地址 
	}
	ClearList(&list);
	DestroyList(&list);
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值