如有问题欢迎指正
文章目录
前言
一、头文件SeqTable.h
#pragma once //防止头文件被重复引用
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SeqTableDataType;
typedef struct SeqTable
{
SeqTableDataType* array;
int size;
int capacity;
}ST;
//声明函数
//初始化
void INITSeqTable(ST* parr);
// 检查空间,如果满了,进行增容
void CheckCapacity(ST* parr);
//尾插
void PushBackSeqTabke(ST* parr, SeqTableDataType x);
// 顺序表打印
void SeqTablePrint(ST* parr);
// 顺序表尾删
void SeqListPopBack(ST* parr);
// 顺序表头插
void SeqListPushFront(ST* parr, SeqTableDataType x);
// 顺序表头删
void SeqListPopFront(ST* parr);
// 顺序表查找
int SeqListFind(ST* parr, SeqTableDataType x);
// 顺序表在pos位置插入x
void SeqListInsert(ST* parr, size_t pos, SeqTableDataType x);
// 顺序表删除pos位置的值
void SeqListErase(ST* parr, size_t pos);
// 顺序表销毁
void SeqListDestory(ST* parr);
这里作者是按照自己习惯将代码分为头文件,接口实现,测试三个。也可以将三个合在一起写,声明函数就不用写了,写的时候要注意函数顺序。
二、SeqTable.c
1.初始化
代码如下(示例):
#include"SeqTable.h" // 引用自己定义的头文件,注意用“”
#define INIT_CAPACITY 4 // 容量初始值
//初始化顺序表
void INITSeqTable(ST* parr)
{
assert(parr);//检查parr是否为空指针
SeqTableDataType* tmp = (SeqTableDataType*)malloc(sizeof(SeqTableDataType)* INIT_CAPACITY);//malloc函数开辟一段空间
if (tmp == NULL)//检查malloc是否成功
{
perror("malloc faild");
exit(-1);
}
parr->array = tmp;//开辟空间成功后将指针指向开头
parr->capacity = INIT_CAPACITY;
parr->size = 0;
}
2.扩容
代码如下(示例):
void CheckCapacity(ST* parr)
{
assert(parr);
if (parr->capacity == parr->size)//如果容量和数量相同则说明空间满了需要扩容,用realloc函数
{
SeqTableDataType* tmp = (SeqTableDataType*)realloc(parr->array, sizeof(SeqTableDataType) *parr->capacity* 2);
if (tmp == NULL)
{
perror("realloc faild");
exit(-1);
}
parr->array = tmp;
parr->capacity *= 2;
}
}
3.尾插
void PushBackSeqTabke(ST* parr, SeqTableDataType x)
{
assert(parr);
CheckCapacity(parr);
parr->array[parr->size] = x;
parr->size += 1;
}
4.打印
void SeqTablePrint(ST* parr)
{
assert(parr);
int i = 0;
for (i = 0; i < parr->size; i++)
{
printf("%d ", parr->array[i]);
}
printf("\n");
}
5.尾删,只需要将个数减一即可
void SeqListPopBack(ST* parr)
{
assert(parr);
parr->size -= 1;
}
6.头插
void SeqListPushFront(ST* parr, SeqTableDataType x)
{
assert(parr);
CheckCapacity(parr);
int i = 0;
//将数据全部后移一位
for (i = parr->size; i > 0; i--)
{
parr->array[i] = parr->array[i-1];
}
parr->array[0] = x;
parr->size += 1;
}
7.头删
void SeqListPopFront(ST* parr)
{
assert(parr);
int i = 0;
for (i = 0; i < parr->size-1; i++)
{
parr->array[i] = parr->array[i + 1];
}
parr->size -= 1;
}
8.查找
int SeqListFind(ST* parr, SeqTableDataType x)
{
assert(parr);
int i = 0;
for (i = 0; i < parr->size; i++)
{
if (parr->array[i] == x)
return i;
}
return -1;
}
9.在pos位置插入
void SeqListInsert(ST* parr, size_t pos, SeqTableDataType x)
{
assert(parr);
int i = 0;
for (i = parr->size; i > pos-1; i--)
{
parr->array[i] = parr->array[i - 1];
}
parr->array[pos] = x;
parr->size++;
}
之前的头插头删,尾插尾删都可以用9,10替代
10.在pos位置删除
void SeqListErase(ST* parr, size_t pos)
{
assert(parr);
int i = 0;
for (i = pos; i < parr->size; i++)
{
parr->array[i] = parr->array[i + 1];
}
parr->size--;
}
11.销毁顺序表
void SeqListDestory(ST* parr)
{
assert(parr);
free(parr->array);//free函数
parr->array = NULL;
parr->capacity = parr->size = 0;
}
三.函数
1.free:
void free (void* ptr);//调用malloc、calloc或realloc之前分配的内存块将被释放,使其再次可用于进一步的分配。如果ptr没有指向用上述函数分配的内存块,则会导致未定义的行为。如果ptr是一个空指针,那么函数将不执行任何操作。请注意,此函数不会更改ptr本身的值,因此它仍然指向相同的(现在无效的)位置。
2.malloc:
void* malloc (size_t size);//分配一个大小为字节的内存块,返回一个指向该块开头的指针。
3.realloc:
void* realloc (void* ptr, size_t size);//重新分配内存块,更改ptr指向的内存块的大小。.指向重新分配的内存块的指针,该内存块可能与ptr相同,也可能是新位置。如果原内存块后有足够的大小则直接在 原内存块后直接添加。如果空间不足则重新找一块足够的内存块,然后将已有数据拷贝过来。
参考:
free - C++ Reference (cplusplus.com)
malloc - C++ Reference (cplusplus.com)
crealloc - C++ Reference (cplusplus.com)
总结
下标的随机访问,二分查找,排序等都可以用顺序表,其中malloc,realloc,free函数比较重要。