基于C语言的嵌入式适用的数据结构---顺序表

为什么要写这篇博客?

嵌入式开发中,在很多的环境下无法使用官方库,可以自己写数据结构,进行使用。

顺序表:在连续的内存中,存入一系列结点的存储单元。示意图如下所示。

上图可以看到:存储地址是连续的,表示可以通过(某一结点的地址+偏移量)直接访问其他结点。

顺序表的特点:随机访问(通过表头元素地址和元素的标号,在O(1)的时间复杂度找到指定元素)
顺序表的不足:删除和插入都需要移动大量的元素

顺序表基本操作:构造、插入、扩容、查找、删除、遍历。以下是目录:

  • 顺序表的构造
    • 顺序表的创建
    • 表的初始化
  • 结点插入
  • 表的扩容
  • 结点查找
  • 结点删除
  • 表的遍历
  • 释放内存

顺序表的构造

  • 顺序表的创建
  1. 正如上图中看到的,需要变量记录,表的最大长度size和当前状态下表内数据个数。
  2. 其次,需要一个指针变量指向内存地址data。
typedef struct Vector {
	// 最大容量和当前顺序表个数
    int size,length;
	// 用来指向存储元素的数据
    int *data;
    
} Vector;
  • 表的初始化
  1. 分别为表中的变量赋值
  2. 为顺序表的数据存储分配内存
void init(Vector *vector, int size) {
    vector->size = size;
    vector->length = 0;
	// 这里分配的内存是存放数据数组的内存
    vector->data = (int*)malloc(sizeof(int)*size);
}

结点插入

  • 判断插入位置是否合法
  • 判断顺序表是否已满,是否需要扩容(主要是因为size一开始就固定了)。
  • 将目标位置及之后的元素后移一位
  • 将待插入的元素插入到目标位置
int insert(Vector *vector, int loc, int value) {
	// 判断形参位置信息是否符合
    if(loc < 0 || loc > vector->length){
        return ERROR;
    }
	// 判断是否需要扩容
    if(vector->length >= vector->size){
//        return ERROR;
        expand(vector);
    }
	// 从表尾逐步向后移动
    for(int i = vector->length; i > loc; i--){
        vector->data[i] = vector->data[i-1];
    }
	// 添加新元素
    vector->data[loc] = value;
	// 长度加一
    vector->length++;
    return OK;
}

插入元素(复杂度分析):

表的扩容

  • 将原来的元素存储到临时存储空间
  • 扩大原来的存储空间
  • 将存储空间里的数据元素复制到新的存储空间里
  • 释放临时存储空间
void expand(Vector *vector){
    int  *old_data = vector->data;
    vector->size = vector->size * 2;
    vector->data = (int *)malloc(sizeof(int) * vector->size);
    for(int i = 0; i < vector->length; i++){
        vector->data[i] = old_data[i];
    }
    free(old_data);

}

结点查找

  • 从下标为0的元素开始依次枚举所有元素
  • 发现和value相同的值,则返回他的index
  • 枚举没找到目标元素则返回-1
int search(Vector *vector, int value) {
	for (int i = 0; i < vector->length; i++) {
		if (vector->data[i] == value) {
			return i;
		}
	}
	return -1;
}

查找方法的时间复杂度:

 

结点删除

  • 判断线标是否合法(if)
  • 将目标下标之后的元素前移一位(for)
  • 更新顺序表的长度(length--)
int delete_node(Vector *vector, int index) {
	if (index < 0 || index >= vector->length) {
		return ERROR;
	}
	for (int i = index + 1; i < vector->length; ++i) {
		vector->data[i - 1] = vector->data[i];
	}
	vector->length = vector->length - 1;
	return OK;
}

删除方法时间复杂度:

 

表的遍历

  • 从下标为0的元素开始遍历
  • 输出所有的元素值
void print(Vector *vector) {
	for (int i = 0; i < vector->length; i++) {
		if (i > 0) {
			printf(" ");

		}
		printf("%d", vector->data[i]);
	}
	printf("\n");
}

 

释放内存

  • 在创建链表指针的时候申请一部分需要释放
  • 在创建数据存储单元的时候需要释放一部分
void clear(Vector *vector) {
    free(vector->data);
    free(vector);
}

 

用顺序表完成以下题目:

代码如下:


int main() {
    Vector *a = (Vector *)malloc(sizeof(Vector));
    init(a, 5);
    int n, col, data;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {

		scanf("%d%d", &col, &data);
		insert(a,col,data);

	}
	clear(a);

    return 0;
}

 

 

第二道题

int main() {
    Vector *a = (Vector *)malloc(sizeof(Vector));
    init(a, 20);
    int m, t,index,value,feiwu;
	scanf("%d", &m);
    for(int i = 0; i < m; i++){
        scanf("%d", &t);
        switch(t){
            case 1 :
                scanf("%d%d", &index, &value);
                feiwu = insert(a,index,value);
                break;
            case 2 :
                scanf("%d", &index);
                feiwu = delete_node(a,index);
                break;
            case 3 :
                scanf("%d", &value);
                feiwu = search(a,value);
                break;
            case 4 :
                print(a);
                break;
   }
    }
    free(a);

    return 0;
}

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值