1 前言
上一篇文章主要描述线性表的概念、特点、组成和适用场景。本文描述顺序表的插入、删除、查找操作以及C语言的实现。
2 顺序表插入
顺序表插入时间复杂度为O(n),顺序表插入类型有三种,不同的插入类型主要是元素集合移动操作不同,即是效率不同。
- 表头插入,将已有的元素集合全部右移,插入效率最低
- 表尾插入,将已有的元素集合一部分右移,插入效率次之
- 表中间插入,不需移动已存在元素集合,插入效率最高
顺序表插入步骤:
【1】遍历到目标位置
【2】将目标位置开始的集合元素右移
【3】元素插入目标位置
C语言实现:
int insert_sequence_list_node(sequence_list_t *list, list_node_type_t *value, int pos)
{
int i = 0;
if ((list==NULL) || (value==NULL))
{
return -1;
}
if (pos > list->capacity) /* 插入位置大于表长度 */
{
return -1;
}
if (list->occupy == list->capacity) /* 表已满 */
{
return -1;
}
pos = pos > list->occupy ? list->occupy : pos; /* 插入位置大于当前表占用长度 */
for (i=list->occupy; i>pos; i--)
{
list->data[i] = list->data[i-1];
}
memcpy(&list->data[pos], value, sizeof(list_node_type_t));
list->occupy++;
return 0;
}
3 顺序表删除
顺序表删除与插入是一个相反的的过程,删除类型有三种,与插入类型对应。
- 表头删除,将已有的元素集合全部左移,删除效率最低
- 表尾删除,将已有的元素集合一部分左移,删除效率次之
- 表中间删除,不需移动已存在元素集合,删除效率最高
顺序表删除步骤:
【1】遍历到目标位置
【2】删除目标位置元素
【3】将目标位置开始的集合元素左移
C语言实现:
int delete_sequence_list_node(sequence_list_t *list, int pos)
{
list_node_type_t *node = NULL;
int i = 0;
if (list == NULL)
{
return -1;
}
if (pos > list->occupy)
{
return -1;
}
node = get_sequence_list_node(list, pos);
if (node != NULL)
{
for(i=pos; i<(list->occupy-1); i++)
{
list->data[i] = list->data[i+1];
}
list->occupy--;
return 0;
}
return -1;
}
4 顺序表查找
顺序表查找时间复杂度是O(1),只需根据索引(下标)值查找即可,查找效率极高。
C语言实现:
list_node_type_t *get_sequence_list_node(sequence_list_t *list, int pos)
{
if (list == NULL)
{
return NULL;
}
if (0 == list->occupy)
{
return NULL;
}
if((pos>=0) && (pos<list->occupy))
{
return (list_node_type_t*)&list->data[pos];
}
}
5 实例
- 实现一个顺序表
- 提供顺序表创建、插入、删除、查找、销毁操作接口
#include <stdio.h>
#include <string.h>
#include <malloc.h>
typedef int list_node_type_t;
typedef struct _sequence_list
{
int capacity;
int occupy;
list_node_type_t *data;
}sequence_list_t;
sequence_list_t* create_sequence_list(int capacity, list_node_type_t node)
{
sequence_list_t* list = NULL;
if (capacity >= 0)
{
list = (sequence_list_t*)malloc(sizeof(sequence_list_t) + sizeof(list_node_type_t) * capacity);
}
if (list != NULL)
{
list->capacity = capacity;
list->occupy = 0;
list->data= (int*)(list + 1);
}
return list;
}
int destory_sequence_list(sequence_list_t *list)
{
if (list == NULL)
{
return -1;
}
free(list);
list = NULL;
return 0;
}
int get_sequence_list_capacity(sequence_list_t *list)
{
if (list == NULL)
{
return 0;
}
return list->capacity;
}
int get_sequence_list_occupy(sequence_list_t *list)
{
if (list == NULL)
{
return 0;
}
return list->occupy;
}
int clear_sequence_list(sequence_list_t *list)
{
if (list == NULL)
{
return -1;
}
list->occupy = 0;
return 0;
}
int insert_sequence_list_node(sequence_list_t *list, list_node_type_t *value, int pos)
{
int i = 0;
if ((list==NULL) || (value==NULL))
{
return -1;
}
if (pos > list->capacity) /* 插入位置大于表长度 */
{
return -1;
}
if (list->occupy == list->capacity) /* 表已满 */
{
return -1;
}
pos = pos > list->occupy ? list->occupy : pos; /* 插入位置大于当前表占用长度 */
for (i=list->occupy; i>pos; i--)
{
list->data[i] = list->data[i-1];
}
memcpy(&list->data[pos], value, sizeof(list_node_type_t));
list->occupy++;
return 0;
}
list_node_type_t *get_sequence_list_node(sequence_list_t *list, int pos)
{
if (list == NULL)
{
return NULL;
}
if (0 == list->occupy)
{
return NULL;
}
if((pos>=0) && (pos<list->occupy))
{
return (list_node_type_t*)&list->data[pos];
}
}
int delete_sequence_list_node(sequence_list_t *list, int pos)
{
list_node_type_t *node = NULL;
int i = 0;
if (list == NULL)
{
return -1;
}
if (pos > list->occupy)
{
return -1;
}
node = get_sequence_list_node(list, pos);
if (node != NULL)
{
for(i=pos; i<(list->occupy-1); i++)
{
list->data[i] = list->data[i+1];
}
list->occupy--;
return 0;
}
return -1;
}
int main(int argc, char *argv[])
{
sequence_list_t *seqlist = NULL;
list_node_type_t node;
list_node_type_t *ptemp;
int i;
/* 创建顺序表 */
seqlist = create_sequence_list(10, node);
/* 插入操作 */
node = 0;
insert_sequence_list_node(seqlist, &node, 0);
node = 1;
insert_sequence_list_node(seqlist, &node, 1);
node = 3;
insert_sequence_list_node(seqlist, &node, 2);
node = 5;
insert_sequence_list_node(seqlist, &node, 1);
printf("sequence list capacity:[%d]\n", seqlist->capacity);
printf("sequence list occupy:[%d]\n", seqlist->occupy);
for(i=0; i<get_sequence_list_occupy(seqlist); i++)
{
ptemp = get_sequence_list_node(seqlist, i);
printf("sequence list node[%d]=%d\n", i, *ptemp);
}
destory_sequence_list(seqlist); /* 销毁线性表 */
}
编译执行
- 在Ubuntu16.04下执行结果
acuity@ubuntu:/mnt/hgfs/LSW/STHB/temp$ gcc list.c -o list
acuity@ubuntu:/mnt/hgfs/LSW/STHB/temp$ ./list
sequence list capacity:[10]
sequence list occupy:[4]
sequence list node[0]=0
sequence list node[1]=5
sequence list node[2]=1
sequence list node[3]=3