学海之路无止境,长夜漫漫,我爱编程。
这次实现的是线性表中的顺序表。
线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结
构,常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物
理上存储时,通常以数组和链式结构的形式存储。
顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组
上完成数据的增删查改。
顺序表一般可以分为:
- 静态顺序表:使用定长数组存储。
- 动态顺序表:使用动态开辟的数组存储。
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多
了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下
面我们实现动态顺序表。
#pragma once
#include<stddef.h>
typedef int SLDateType;
typedef struct SeqList{
SLDateType *arrary; //指针,指向堆上的存放数据的空间
int size; // 顺序表中的有效数据个数
int capacity; //顺序表的容量
} SeqList;
//接口
//初始化
void SeqListInit(SeqList *sl, size_t capacity);
//销毁
void SeqListDestroy(SeqList *sl);
//尾插,插入顺序表的尾部
void SeqListPushBack(SeqList *sl, SLDateType date);
//尾删,删除顺序表尾部
void SeqListPopBack(SeqList *sl);
//头插,将数据插入顺序表头部
void SeqListPushFront(SeqList *sl, SLDateType date);
//头删,删除顺序表头部
void SeqListPopFront(SeqList *sl);
//在 pos 所在的下标做数据输入
void SeqListInsert(SeqList *sl, size_t pos, SLDateType date);
//删除 pos 所在的下标数据
void SeqListErase(SeqList *sl, size_t pos);
//查找,从零开始第一次出现的位置,返回数据所在的下标,如果没有找到返回一个无效值-1
int SeqListFind(SeqList *sl, SLDateType date);
//删除第一个遇到的date
void SeqListRemove(SeqList *sl, SLDateType date);
//删除所有遇到的date
void SeqListRemoveAll(SeqList *sl, SLDateType date);
//修改 pos 所在的下标的数据
void SeqListModify(SeqList *sl, size_t pos, SLDateType date);
//打印
void SeqListPrint(SeqList *sl);
//扩容
void CheckCapacity(SeqList *sl);
#include"SeqList.h"
#include<assert.h>
//初始化函数
void SeqListInit(SeqList *sl, size_t capacity)
{
//合法判断
assert(sl != NULL);
sl->size = 0;
sl->capacity = capacity;
//为线性表创建空间
sl->arrary = (SeqList*)malloc(sizeof(SLDateType)* sl->capacity);
//错误监察
assert(sl->arrary != NULL);
}
//销毁函数
void SeqListDestroy(SeqList *sl)
{
assert(sl != NULL);
//清空线性表有效个数和容量
free(sl->arrary);
sl->size = sl->capacity = 0;
//防御型代码
sl->arrary = NULL;
}
//尾插
void SeqListPushBack(SeqList *sl, SLDateType date)
{
assert(sl != NULL);
CheckCapacity(sl);
sl->arrary[sl->size] = date;
sl->size++;
//SeqListInsert(sl,sl->size,date)
}
//尾删
void SeqListPopBack(SeqList *sl)
{
assert(sl != NULL);
if (sl->size > 0){
sl->size--;
}
else{
printf("你的线性表当前没有数据!\n");
}
}
//头插
void SeqListPushFront(SeqList *sl, SLDateType date)
{
assert(sl != NULL);
CheckCapacity(sl);
for (int i = sl->size; i > 0; i--)
{
sl->arrary[i] = sl->arrary[i - 1];
}
sl->arrary[0] = date;
sl->size++;
//SeqListInsert(sl, 0,date);
}
//头删
void SeqListPopFront(SeqList *sl)
{
assert(sl != NULL);
if (sl->size > 0){
for (int i = 0; i < sl->size - 1; i++)
{
sl->arrary[i] = sl->arrary[i + 1];
}
sl->size--;
}
else{
printf("你的线性表当前没有数据!\n");
}
}
//在 pos 所在的下标做数据输入
void SeqListInsert(SeqList *sl, size_t pos, SLDateType date)
{
assert(sl != NULL);
assert(pos >= 0 && (int)pos <= sl->size);
CheckCapacity(sl);
for (int i = sl->size; i >= (int)pos; i--)
{
sl->arrary[i] = sl->arrary[i - 1];
}
sl->arrary[pos] = date;
sl->size++;
}
//删除 pos 所在的下标数据
void SeqListErase(SeqList *sl, size_t pos)
{
assert(sl != NULL);
assert(sl->size > 0);
assert(pos >= 0 && (int)pos < sl->size);
for (int i = pos + 1; i < sl->size; i++)
{
sl->arrary[i - 1] = sl->arrary[i];
}
sl->size--;
}
//查找,从零开始第一次出现的位置,返回数据所在的下标,如果没有找到返回一个无效值-1
int SeqListFind(SeqList *sl, SLDateType date)
{
assert(sl != NULL);
for (int i = 0; i < sl->size; i++)
{
if (sl->arrary[i] = date)
{
return i;
}
}
//没有找到
return -1;
}
//删除第一个遇到的date
void SeqListRemove(SeqList *sl, SLDateType date)
{
assert(sl != NULL);
//for (int i = 0; i < sl->size; i++)
//{
// if (sl->arrary[i] = date)
// {
// SeqListErase(sl, i);
// }
// return;
//}
int pos = SeqListFind(sl, date);
if (pos != -1)
{
SeqListErase(sl, pos);
}
}
//删除所有遇到的date
void SeqListRemoveAll(SeqList *sl, SLDateType date)
{
#if 0
for (int i = 0; i < sl->size; i++)
{
if (sl->arrary[i] = date)
{
SeqListErase(sl, i);
}
}
#endif
#if 0
int pos;
while ((pos = SeqListFind(sl, date)) != -1)
{
SeqListErase(sl, pos);
}
#endif
#if 0
SLDateType* temp = (SLDateType*)malloc(sizeof(SLDateType)* sl->size);
assert(temp != NULL);
int j = 0;
for (int i = 0; i < sl->size; i++)
{
if (sl->arrary[i] != date)
{
temp[j++] = sl->arrary[i];
}
}
for (int k = 0; k < j; k++)
{
sl->arrary[k] = temp[k];
}
sl->size = j;
#endif
int j = 0;
for (int i = 0; i < sl->size; i++)
{
if (sl->arrary[i] != date)
{
sl->arrary[j++] = sl->arrary[i];
}
}
sl->size = j;
}
//修改 pos 所在的下标的数据
void SeqListModify(SeqList *sl, size_t pos, SLDateType date)
{
assert(sl != NULL);
assert(pos >= 0 && (int)pos < sl->size);
sl->arrary[pos] = date;
}
//打印
void SeqListPrint(SeqList *sl)
{
assert(sl != NULL);
for (int i = 0; i < sl->size; i++)
{
printf("%d ", sl->arrary[i]);
}
printf("\n");
}
//扩容
void CheckCapacity(SeqList *sl)
{
assert(sl != NULL);
if (sl->size < sl->capacity)
return;
int NewCapacity = sl->capacity * 2;
SLDateType* Newarrary = (SLDateType*)malloc(sizeof(SLDateType)* NewCapacity);
for (int i = 0; i < sl->size; i++)
{
Newarrary[i] = sl->arrary[i];
}
//切记一定要先释放老的内存
free(sl->arrary);
sl->arrary = Newarrary;
sl->capacity = NewCapacity;
}
#include"SeqList.h"
void TestSeqList()
{
SeqList seqlist;
SeqListInit(&seqlist, 10);
SeqListDestroy(&seqlist);
SeqListPushBack(&seqlist, 5);
SeqListPopBack(&seqlist);
SeqListPushFront(&seqlist, 5);
SeqListPopFront(&seqlist);
SeqListInsert(&seqlist, 3, 5);
SeqListErase(&seqlist, 3);
SeqListFind(&seqlist, 5);
SeqListRemove(&seqlist, 5);
SeqListRemoveAll(&seqlist, 5);
SeqListModify(&seqlist 3, 5);
SeqListPrint(&seqlist);
CheckCapacity(&seqlist);
}
int main()
{
TestSeqList();
system("pause");
return 0;
}