前言
线性表有两种物理存储结构:顺序存储结构和链式存储结构,现在了解一下顺序存储结构。
一、顺序线性表
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。顺序存储结构封装需要三个属性:
- 存储空间的起始位置,数组data,它的存储位置就是线性表存储空间的存储位置。
- 线性表的最大存储容量:数组的长度MaxSize。
- 线性表的当前长度:length。
二、代码实例
linearlist.h
#ifndef __LINEAR_LIST_
#define __LINEAR_LIST_
#define MAX_SIZE 100
typedef int ElemType;
typedef struct _sqList {
ElemType data[MAX_SIZE];
int length;
}sqList_s, *sqList_p;
int initList(sqList_s **list);
int isFullList(sqList_p list);
int isEmptyList(sqList_p list);
int lengthList(sqList_p list);
int addListOfTail(sqList_p list, ElemType value);
int addList(sqList_p list, ElemType value, int i);
int getElemList(sqList_p list, int i, ElemType *e);
int deleteList(sqList_p list, int i, ElemType *e);
int clearList(sqList_p list);
#endif
linearlist.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linearlist.h"
int initList(sqList_s **list)
{
*list = (sqList_s *)malloc(sizeof(sqList_s));
if (NULL == *list) {
perror("malloc error");
return -1;
}
memset((*list)->data, 0, MAX_SIZE);
(*list)->length = 0;
return 0;
}
int isFullList(sqList_p list)
{
return list->length == (MAX_SIZE - 1);
}
int isEmptyList(sqList_p list)
{
return list->length == 0;
}
int lengthList(sqList_p list)
{
return list->length;
}
int addListOfTail(sqList_p list, ElemType value)
{
if (list == NULL)
return -1;
if (isFullList(list))
return -1;
list->data[list->length ++] = value;
return 0;
}
int addList(sqList_p list, ElemType value, int i)
{
int k;
if (list == NULL)
return -1;
if (isFullList(list))
return -1;
for(k = list->length - 1 ; k >= i; k --)
list->data[k + 1] = list->data[k];
list->data[i] = value;
list->length ++;
return 0;
}
int getElemList(sqList_p list, int i, ElemType *e)
{
if (NULL == list || i < 0 || i > list->length)
return -1;
*e = list->data[i];
return 0;
}
int printfList(sqList_p list)
{
int i;
for (i = 0; i < list->length; i++)
printf("%d\t", list->data[i]);
printf("\n");
return 0;
}
#if 1
/*测试*/
int main()
{
int i;
ElemType e ;
sqList_p l = NULL ;
initList(&l);
printf("It is empty? %s\n", (isEmptyList(l) ? "yes" : "no"));
for(i = 0; i < MAX_SIZE - 5; i++)
addListOfTail(l, i);
printf("It is full? %s\n", isFullList(l)==1 ? "yes" : "no");
getElemList(l, 18, &e);
printf("list[18] is %d\n", e);
printf("length: %d\n", lengthList(l));
printfList(l);
addListOfTail(l, 100);
printf("length: %d\n", lengthList(l));
printfList(l);
addList(l, 99, 4);
printf("length: %d\n", lengthList(l));
printfList(l);
deleteList(l, 5, &e);
printf("value: %d length: %d\n", e, lengthList(l));
printfList(l);
freeList(l);
return 0;
}
#endif
三、分析
现在我们分析一下,插入和删除的时间复杂度:
- 最好的情况:插入和删除操作刚好要求在最后一个位置操作,因为不需要移动任何元素,所以此时的时间复杂度为O(1)。
- 最坏的情况:如果要插入和删除的位置是第一个元素,那就意味着要移动所有的元素向后或者向前,所以这个时间复杂度为O(n)。
- 至于平均情况,就取中间值O((n-1)/2)。 按照前边游戏秘籍指导,平均情况复杂度简化后还是O(n)。
线性表顺序存储结构的优缺点:
线性表的顺序存储结构,在存、读数据时,不管是哪个位置,时间复杂度都是O(1)。而在插入或删除时,时间复杂度都是O(n)。这就说明,它比较适合元素个数比较稳定,不经常插入和删除元素,而更多的操作是存取数据的应用。
四、总结
那我们接下来给大家简单总结下线性表的顺序存储结构的优缺点:
优点:
- 无须为表示表中元素之间的逻辑关系而增加额外的存储空间。
- 可以快速地存取表中任意位置的元素。
缺点:
- 插入和删除操作需要移动大量元素。
- 当线性表长度变化较大时,难以确定存储空间的容量。
- 容易造成存储空间的“碎片”。
关注公众号"小败日记",搬砖过程遇到的问题,大家一起探讨,资源共享