#来源:@英雄从哪里出来#
4-1 顺序表的概念
基本概念
顺序表是一种线性的数据结构,其中数据元素按照特定的顺序依次存储在连续的内存空间中。它由一系列元素组成,每个元素都与唯一的索引(下标)相关联,索引从0开始递增。顺序表中的元素可以是任意类型的数据,包括int\float\double\char等,也可以是结构体或者对象。
顺序表的插入
顺序表的元素插入需要指定一个索引和一个元素,将目标索引之后的元素依次往后挪,然后再将这个元素插入对应的索引序列上。
具体步骤如下:
①判断插入位置是否合法,如果不合法则抛出异常(比如:原本只有5个元素,给定的索引是100,那显然这个位置是不合法的);
②如果顺序表已满,则需要扩容顺序表,一般是把原有顺序表的容量进行倍增;
③将插入位置之后的元素向后移动,为新元素腾出空间;
④将新元素插入到指定位置;
⑤更新顺序表的大小。
顺序表的删除
顺序表的元素删除,就是指给定一个索引,将这个索引上的元素删除,并且把这个索引位置以后的所有元素都往前移动一个位置。
具体步骤如下:
①判断删除位置是否合法,如果不合法则抛出异常;
②如果删除位置为最后一个元素,直接将顺序表的大小减1;
③如果删除位置不是最后一个元素,将删除位置之后的元素向前移动,覆盖要删除的元素;
④更新顺序表的大小。
顺序表的元素查找
顺序表的元素查找,是指在顺序表中查找指定元素是否存在,如果存在则返回该元素的索引,否则返回-1。由于需要遍历整个顺序表进行元素对比,所以查找的时间复杂度为 O(n)。
具体步骤如下:
①遍历整个顺序表,对顺序表中的每个元素,和指定元素进行比较,如果相等则返回当前的索引;
②如果遍历完所有的顺序表元素,都没有找到相等的元素,则返回-1;
顺序表的元素索引
顺序表的元素索引,是指给定一个索引值,通过下标访问,直接在顺序表中获取元素的值,时间复杂度 O(1)。
具体步骤如下:
直接通过索引访问即可获得对应的元素。
顺序表的元素修改
将顺序表中指定位置的元素更新为新的值。
具体步骤如下:
通过索引直接访问即可获得对应的元素,修改成指定的值。
4-2-1 手写顺序表模板
代码示例:
#include <stdio.h>
#include <stdlib.h>
#define SequentialList seList
typedef struct {
int *elements; //存储顺序表元素的动态数组
size_t size; //顺序表中元素的个数
size_t capacity;//顺序表中最多能存储的元素个数
}seList;
void seListInit(seList *list,int capacity)
{
list->elements = (int*)malloc(sizeof(int)*capacity);
list->size = 0;
list->capacity = capacity;
}
void seListDestory(seList *list)
{
if ((list->elements) != NULL) {
free(list->elements);
list->elements = 0;
}else {};
}
int seListSize(seList* list)
{
return list->size;
}
void seListInsert(seList *list,int index,int element)
{
if (index<0 || index>list->size) { //检查索引是否合法
printf("index invalid\n");
return;
}else{}
if (list->size == list->capacity) { //顺序表的扩容
int* newElements = (int*)realloc(list->elements,sizeof(int)*(list->capacity*2));
if (NULL == newElements) {
printf("failed to allocate memory\n");
return;
}
else {
list->elements = newElements;
list->capacity *= 2;
}
}else{}
for (size_t i = list->size; i > index; --i) //把索引之后的元素依次往后挪动
{
list->elements[i] = list->elements[i - 1];
}
list->elements[index] = element;
++list->size;
}
void seListDelete(seList* list,int index)
{
if (index < 0 || index >= list->size)
{
printf("index invalid\n");
return;
}
else {
for (size_t i=index;i<list->size;++i)
{
list->elements[i] = list->elements[i + 1];
}
--list->size;
}
}
size_t seListFind(const seList *list, int element)
{
for (size_t i=0;i<list->size;i++)
{
if (list->elements[i] == element)
{
return i;
}else{}
}
return -1;
}
int seListIndex(const seList* list, int index)
{
if (index < 0 || index >= list->size) {
printf("invalid index\n");
return -1;
}else {
return list->elements[index];
}
}
void seListSet(seList* list, int index, int element)
{
if (index < 0 || index >= list->size) {
printf("invalid index\n");
return -1;
}
else {
list->elements[index] = element;
}
}
int main(void)
{
seList list0;
seListInit(&list0, 1);
for (int i=0;i<10;i++)
{
seListInsert(&list0, i, i * 10);
}
printf("Size:%d\n", seListSize(&list0));
int elem = seListIndex(&list0,2);
printf("elements[2]=%d\n",elem);
int index = seListFind(&list0,15);
if (-1 == index) {
printf("15 doesn't belong to list0\n");
}
else {
printf("15 is elements %d\n",index);
}
seListSet(&list0,3,60);
for (int i=0;i<seListSize(&list0);i++)
{
printf("%d %d\n",i, seListIndex(&list0,i));
}
seListDestory(&list0);
return 0;
}
4-2-2 C语言中的顺序表
题目:提供一个长度为n的整数数组arrA,构建一个长度为2n的整数数组arrB,数组索引从0开始计算,要求对于任意0<=i<n的i,满足下述所有要求:
①arrB[i]==arrA[i];
②arrB[i]==arrA[i];
总之就是arrB由两个arrA串联而成,返回arrB。