顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
- 静态顺序表:使用定长数组存储。
- 动态顺序表:使用动态开辟的数组存储。
定义
typedef int DataType;
typedef struct SeqList
{
DataType* _arr; //动态数组存储
size_t _size; //有效元素的个数
size_t _capacity; //容量
}SeqList;
初始化
void Init(SeqList* s)
{
s->_arr = NULL;
s->_size = s->_capacity = 0;
}
销毁
void Destroy(SeqList* s)
{
if (s->_arr)
{
free(s->_arr);
s->_arr = NULL;
s->_size = s->_capacity = 0;
}
}
扩容
void Reserve(SeqList* s, size_t new_capacity)
{
DataType* tmp = (DataType*)malloc(sizeof(DataType) * new_capacity);
if (s->_arr)
{
memcpy(tmp, s->_arr, sizeof(DataType) * s->_size);
}
free(s->_arr);
s->_arr = tmp;
s->_capacity = new_capacity;
}
尾插
void PushBack(SeqList* s, DataType val)
{
if (s->_size == s->_capacity)
{
size_t new_capacity = s->_capacity == 0 ? 2 : s->_capacity * 2;
Reserve(s, new_capacity);
}
s->_arr[s->_size++] = val;
}
尾删
void PopBack(SeqList* s)
{
assert(s->_arr != NULL);
--s->_size;
}
头插
void PushFront(SeqList* s, DataType val)
{
if (s->_size == s->_capacity)
{
size_t new_capacity = s->_capacity == 0 ? 2 : s->_capacity * 2;
Reserve(s, new_capacity);
}
size_t end = s->_size;
while (end > 0)
{
s->_arr[end] = s->_arr[end - 1];
--end;
}
s->_arr[0] = val;
++s->_size;
}
头删
void PopFront(SeqList* s)
{
assert(s->_arr != NULL);
size_t begin = 1;
while (begin < s->_size)
{
s->_arr[begin - 1] = s->_arr[begin];
++begin;
}
--s->_size;
}
在pos位置插入
void Insert(SeqList* s, size_t pos, DataType val)
{
assert(pos <= s->_size);
if (s->_size == s->_capacity)
{
size_t new_capacity = s->_capacity == 0 ? 2 : s->_capacity * 2;
Reserve(s, new_capacity);
}
size_t end = s->_size;
while (end > pos)
{
s->_arr[end] = s->_arr[end - 1];
--end;
}
s->_arr[pos] = val;
++s->_size;
}
在pos位置删除
void Erase(SeqList* s, size_t pos)
{
assert(pos < s->_size);
size_t begin = pos + 1;
while (begin < s->_size)
{
s->_arr[begin - 1] = s->_arr[begin];
++begin;
}
--s->_size;
}
查找
int Find(SeqList* s, DataType val)
{
for (size_t i = 0; i < s->_size; ++i)
{
if (s->_arr[i] == val)
{
return i;
}
}
return -1;
}
完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
typedef int DataType;
typedef struct SeqList
{
DataType* _arr;
size_t _size;
size_t _capacity;
}SeqList;
void Init(SeqList* s)
{
s->_arr = NULL;
s->_size = s->_capacity = 0;
}
void Reserve(SeqList* s, size_t new_capacity)
{
DataType* tmp = (DataType*)malloc(sizeof(DataType) * new_capacity);
if (s->_arr)
{
memcpy(tmp, s->_arr, sizeof(DataType) * s->_size);
}
free(s->_arr);
s->_arr = tmp;
s->_capacity = new_capacity;
}
void PushBack(SeqList* s, DataType val)
{
if (s->_size == s->_capacity)
{
size_t new_capacity = s->_capacity == 0 ? 2 : s->_capacity * 2;
Reserve(s, new_capacity);
}
s->_arr[s->_size++] = val;
}
void PopBack(SeqList* s)
{
assert(s->_arr != NULL);
--s->_size;
}
void PushFront(SeqList* s, DataType val)
{
if (s->_size == s->_capacity)
{
size_t new_capacity = s->_capacity == 0 ? 2 : s->_capacity * 2;
Reserve(s, new_capacity);
}
size_t end = s->_size;
while (end > 0)
{
s->_arr[end] = s->_arr[end - 1];
--end;
}
s->_arr[0] = val;
++s->_size;
}
void PopFront(SeqList* s)
{
assert(s->_arr != NULL);
size_t begin = 1;
while (begin < s->_size)
{
s->_arr[begin - 1] = s->_arr[begin];
++begin;
}
--s->_size;
}
void Insert(SeqList* s, size_t pos, DataType val)
{
assert(pos <= s->_size);
if (s->_size == s->_capacity)
{
size_t new_capacity = s->_capacity == 0 ? 2 : s->_capacity * 2;
Reserve(s, new_capacity);
}
size_t end = s->_size;
while (end > pos)
{
s->_arr[end] = s->_arr[end - 1];
--end;
}
s->_arr[pos] = val;
++s->_size;
}
void Erase(SeqList* s, size_t pos)
{
assert(pos < s->_size);
size_t begin = pos + 1;
while (begin < s->_size)
{
s->_arr[begin - 1] = s->_arr[begin];
++begin;
}
--s->_size;
}
int Find(SeqList* s, DataType val)
{
for (size_t i = 0; i < s->_size; ++i)
{
if (s->_arr[i] == val)
{
return i;
}
}
return -1;
}
void Destroy(SeqList* s)
{
if (s->_arr)
{
free(s->_arr);
s->_arr = NULL;
s->_size = s->_capacity = 0;
}
}
void Print(SeqList* s)
{
for (size_t i = 0; i < s->_size; ++i)
{
printf("%d ", s->_arr[i]);
}
printf("\n");
}
测试用例
void Test()
{
SeqList sl;
Init(&sl);
PushBack(&sl, 1);
PushBack(&sl, 2);
PushBack(&sl, 3);
Print(&sl);
PopBack(&sl);
Print(&sl);
PopBack(&sl);
Print(&sl);
PopBack(&sl);
Print(&sl);
Destroy(&sl);
}
void Test2()
{
SeqList sl;
Init(&sl);
PushBack(&sl, 3);
PushBack(&sl, 2);
PushBack(&sl, 1);
for (int i = 0; i < 1000; i++)
{
PushFront(&sl, i);
}
Print(&sl);
Destroy(&sl);
}
void Test3()
{
SeqList sl;
Init(&sl);
PushBack(&sl, 3);
PushFront(&sl, 2);
PushFront(&sl, 1);
PushBack(&sl, 4);
PushBack(&sl, 5);
PushBack(&sl, 7);
PushBack(&sl, 9);
PushBack(&sl, 10);
Insert(&sl, 5, 6);
Insert(&sl, 7, 8);
Insert(&sl, 10, 200);
Print(&sl);
PopFront(&sl);
Print(&sl);
PopBack(&sl);
Print(&sl);
Erase(&sl, 3);
Print(&sl);
Erase(&sl, 3);
Print(&sl);
Destroy(&sl);
}
void Test4()
{
SeqList sl;
Init(&sl);
PushBack(&sl, 1);
PushBack(&sl, 2);
PushBack(&sl, 3);
Print(&sl);
int ret = Find(&sl, 2);
printf("数据2的位置是:%d\n", ret);
Destroy(&sl);
}