目录
1、线性表
线性表。全名为线性存储结构,可以理解为即“把所有数据用一根线儿串起来,再存储到物理空间中”。线性表并不是一种具体的存储结构,它包含 顺序存储结构 和 链式存储结构,是顺序表和链表的统称。除了数组,链表、队列、栈等也是线性表结构。
顺序存储结构:将数据依次存储在连续的整块物理空间中
链式存储结构:数据分散的存储在物理空间中,通过一根线保存着它们之间的逻辑关系
非线性表。在非线性表中,数据之间并不是简单的前后关系。比如树、图
2、顺序表
它用一组连续的内存空间,来存储一组具有相同类型的数据。最大的特点就是支持随机访问,但插入、删除操作也因此变得比较低效,平均情况时间复杂度为 O(n)。
数组和链表的区别及优缺点:数组在内存地址上是连续的;链表在内存地址上可以是连续 也可以不是连续的,每个链表的节点包括原来的内存和下一个节点的信息(单向的一个,双向链表的话会有两个)
优点 | 缺点 | |
数组 | 使用方便 ,查询效率 比链表高,内存为一连续的区域 | 大小固定,不方便动态添加 |
链表 | 可动态添加删除 大小可变 | 只能通过顺次指针访问,查询效率低 |
3、顺序表的存储结构
4、顺序表的基本操作
顺序表的基本操作包括表的创建、销毁,数据的插入、删除、修改、清空。数据在插入的时候还支持动态扩容,在插入的数据量超过了表的容量的时候,自动扩展2倍于现有容量的存储空间
#ifndef __ALGO_ARRAY_LIST_H__
#define __ALGO_ARRAY_LIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rtthread.h>
#define ARRAY_LIST_MALLOC(size) rt_malloc(size)
#define ARRAY_LIST_CALLOC(n,size) rt_calloc(n,size)
#define ARRAY_LIST_FREE(p) rt_free(p)
#define ARRAY_LIST_GROW_STEP 50
struct array_list
{
unsigned int cap; /* array total size */
unsigned int used; /* array used size, from 1 to size */
void **array; /* array, dynamically applied by array_init()*/
};
/* 创建并且返回一个空的array_list */
extern struct array_list* array_list_creat(unsigned int cap);
/* 销毁一个线性表array_list */
extern int array_list_destroy(struct array_list *list);
/* 将一个线性表array_list中的所有元素清空 */
extern int array_list_clear(struct array_list *list);
/* 向一个线性表array_list的最后位置处插入新元素,元素指向data */
extern int array_list_insert(struct array_list *list, void *data);
/* 删除一个线性表array_list的pos位置处的元素 */
extern int array_list_delete(struct array_list *list, unsigned int pos);
/* 增加array_list空间大小,返回新空间大小 */
extern int array_list_grow(struct array_list *list, int new_cap);
#endif
/*
* Copyright (c) 20019-2020, dhl
*
* Change Logs:
* Date Author Notes
* 2021-07-29 dhl the first version
*/
#include "algo_array_list.h"
/**
* dynamically create a dynamic array, including the array header and data space.
*
* @param cap: array size
* @return NULL:malloc fail
* !NULL:success
*/
struct array_list* array_list_creat(unsigned int cap)
{
struct array_list *list = NULL;
void **array = NULL;
list = ARRAY_LIST_MALLOC(sizeof(struct array_list));
if(!list)
return NULL;
memset(list, 0, sizeof(struct array_list));
array = ARRAY_LIST_MALLOC(sizeof(void *) * cap);
if(array == NULL)
return NULL;
memset(array, 0, sizeof(void *) * cap);
list->array = array;
list->cap = cap;
list->used = 0;
return list;
}
/**
* 销毁一个线性表array_list
*
* @param list: array_list
* @return -1: fail
* 0: success
*/
int array_list_destroy(struct array_list *list)
{
int i = 0;
if(list == NULL)
return -1;
/* 删除数组元素指向的指针数据 */
for(i=0; i<list->used; i++)
{
if(list->array[i])
ARRAY_LIST_FREE(list->array[i]);
list->array[i] = NULL;
}
/* 删除数组元素 */
if(list->array)
ARRAY_LIST_FREE(list->array);
list->array = NULL;
/* 删除链表 */
ARRAY_LIST_FREE(list);
return 0;
}
/**
* 将一个线性表array_list中的所有元素清空
*
* @param list: array_list
* @return -1: fail
* 0: success
*/
int array_list_clear(struct array_list *list)
{
int i = 0;
if(list == NULL)
return -1;
/* 删除数组元素指向的指针数据 */
for(i=0; i<list->used; i++)
{
if(list->array[i])
ARRAY_LIST_FREE(list->array[i]);
list->array[i] = NULL;
}
return 0;
}
/**
* 向一个线性表array_list的pos位置处插入新元素
*
* @param list: array_list
* @return -1: fail
* 0: success
*/
int array_list_insert(struct array_list *list, void *data)
{
int ret = 0;
if(list == NULL)
return -1;
/* 需要扩容 */
if(list->used == list->cap)
{
ret = array_list_grow(list, list->cap * 2);
if(ret == -1)
return -1;
}
list->array[list->used] = data;
list->used += 1;
return 0;
}
/**
* 删除一个线性表array_list的pos位置处的元素
*
* @param list: array_list
* @return -1: fail
* 0: success
*/
int array_list_delete(struct array_list *list, unsigned int pos)
{
void *del_data = NULL;
int i = 0;
if(list == NULL || pos >= list->used)
return -1;
del_data = list->array[pos];
/* 向前移动 */
for(i=pos+1; i<list->used; i++) {
list->array[i-1] = list->array[i];
}
if(del_data)
ARRAY_LIST_FREE(del_data);
list->used -= 1;
return 0;
}
/**
* 增加array_list空间大小,返回新空间大小
*
* @param list: array_list
* @return -1: fail
* 0: success
*/
int array_list_grow(struct array_list *list, int new_cap)
{
void **new_array = NULL;
if(list == NULL || new_cap < list->cap)
return -1;
/* 申请新的空间 */
new_array = ARRAY_LIST_MALLOC(sizeof(void *) * new_cap);
if(new_array == NULL)
return -1;
memset(new_array, 0, sizeof(void *) * new_cap);
/* 拷贝 */
memcpy(new_array, list->array, sizeof(void *) * list->used);
/* 回收旧的空间 */
ARRAY_LIST_FREE(list->array);
/* 指向新的空间 */
list->array = new_array;
list->cap = new_cap;
return 0;
}