顺序表
概念及结构
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删改查。 顺序表一般可以分为:
- 静态顺序表:使用定长数组存储
- 动态顺序表:使用动态开辟的数组存储
接口实现
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组会导致空间开多了浪费,开少了不够用。 所以动态顺序表会用的比较多,根据需要动态的分配空间大小。
相关操作代码示例
seqList.h
#pragma once
#define N 100
typedef int SLDataType;
struct seqList
{
SLDataType _data[N];
int _size;
};
typedef struct seqList1
{
SLDataType* _data;
int _size;
int _capacity;
}seqList1;
void initseqList(seqList1* s1);
void seqListCheckCapacity(seqList1* s1);
void seqList_pushBack(seqList1* s1, SLDataType val);
void seqList_popBack(seqList1* s1);
void seqList_print(seqList1* s1);
SLDataType seqList(seqList1* s1, int pos);
int seqList_isEmpty(seqList1* s1);
void seqList_pushFront(seqList1* s1, SLDataType val);
void seqList_popFront(seqList1* s1);
void seqList_insPos(seqList1* s1, int pos, SLDataType val);
void seqList_delPos(seqList1* s1, int pos);
void seqList_Destroy(seqList1* s1);
Tes1204.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"seqList.h"
void initseqList(seqList1* s1)
{
if (s1 == NULL)
{
return;
}
s1->_data = NULL;
s1->_size = 0;
s1->_capacity = 0;
}
int seqList_isEmpty(seqList1* s1)
{
if (s1 == NULL)
{
return;
}
if (s1->_size == 0)
return 1;
else
return 0;
}
void seqListCheckCapacity(seqList1* s1)
{
if (s1->_size == s1->_capacity)
{
int newCapacity = s1->_capacity == 0 ? 1 : 2 * s1->_capacity;
SLDataType* tmp = (SLDataType*)malloc(newCapacity * sizeof(SLDataType));
if (tmp == NULL)
{
return;
}
memcpy(tmp, s1->_data, sizeof(SLDataType) * s1->_size);
free(s1->_data);
s1->_data = tmp;
s1->_capacity = newCapacity;
}
}
void seqList_pushBack(seqList1* s1, SLDataType val)
{
if (s1 == NULL)
{
return;
}
seqListCheckCapacity(s1);
s1->_data[s1->_size] = val;
s1->_size++;
}
void seqList_popBack(seqList1* s1)
{
if (s1 == NULL)
{
return;
}
if (s1->_size > 0)
s1->_size--;
}
void seqList_print(seqList1* s1)
{
if (s1 == NULL)
{
return;
}
for (int i = 0; i < s1->_size; ++i)
{
printf("%d ", s1->_data[i]);
}
printf("\n");
}
SLDataType seqList(seqList1* s1, int pos)
{
if (s1 == NULL)
{
return;
}
if (seqList_isEmpty(s1))
return -1;
if (pos <= s1->_size)
return s1->_data[pos];
else
{
printf("位置错误!\n");
return -1;
}
}
void seqList_pushFront(seqList1* s1, SLDataType val)
{
if (s1 == NULL)
{
return;
}
seqListCheckCapacity(s1);
for (int i = s1->_size; i > 0; --i)
{
s1->_data[i] = s1->_data[i - 1];
}
s1->_data[0] = val;
s1->_size++;
}
void seqList_popFront(seqList1* s1)
{
if (s1 == NULL)
{
return;
}
for (int i = 0; i < s1->_size - 1; ++i)
{
s1->_data[i] = s1->_data[i + 1];
}
s1->_size--;
}
void seqList_insPos(seqList1* s1, int pos, SLDataType val)
{
if (s1 == NULL)
{
return;
}
if (pos <= s1->_size && pos >= 0)
{
seqListCheckCapacity(s1);
for (int i = s1->_size; i > pos; --i)
{
s1->_data[i] = s1->_data[i - 1];
}
s1->_data[pos] = val;
s1->_size++;
}
else
{
printf("位置错误!\n");
return;
}
}
void seqList_delPos(seqList1* s1, int pos)
{
if (s1 == NULL)
{
return;
}
if (seqList_isEmpty(s1))
return;
if (pos < s1->_size && pos >= 0)
{
for (int i = pos; i < s1->_size - 1; ++i)
{
s1->_data[i] = s1->_data[i + 1];
}
s1->_size--;
}
else
{
printf("位置错误!\n");
return;
}
}
void seqList_Destroy(seqList1* s1)
{
if (s1 == NULL || s1->_data == NULL)
{
return;
}
free(s1->_data);
s1->_data == NULL;
}
void test()
{
seqList1 s1;
initseqList(&s1);
seqList_pushBack(&s1, 1);
seqList_pushBack(&s1, 2);
seqList_pushBack(&s1, 3);
seqList_pushBack(&s1, 4);
seqList_pushBack(&s1, 5);
seqList_pushFront(&s1, 0);
seqList_print(&s1);
seqList_popFront(&s1);
seqList_print(&s1);
seqList_pushFront(&s1, 0);
seqList_print(&s1);
seqList_delPos(&s1, 3);
seqList_print(&s1);
seqList_insPos(&s1, 5, 9);
seqList_print(&s1);
printf("\n=============\n");
seqList1* s2 = (seqList1*)malloc(sizeof(seqList1));
initseqList(s2);
seqList_Destroy(s2);
free(s2);
}
int main()
{
test();
system("pause");
return 0;
}
顺序表特点
- 空间连续
- 支持随机访问
- 尾插、尾删操作:O(1)
- 空间利用率高,不容易造成内存碎片
- 其他位置(除了尾部)插入、删除:O(n)
- 增容的代价较大
|