【数据结构】 模拟实现顺序表(C语言)
- 引言:顺序表是数据结构的一种简单线性结构,在学习过程中,刚从C语言过渡到数据结构,承前启后,既考验C语言语法功底,又考验了对数据结构入门知识的了解。
- 定义:顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。 顺序表一般可以分为:
- 静态顺序表:使用定长数组存储。
#define N 100
typedef int SLDataType;
typedef struct SeqList
{
SLDataType array[N]; // 定长数组
size_t size; // 有效数据的个数
}SeqList;
- 动态顺序表:使用动态开辟的数组存储。
typedef struct SeqList
{
SLDataType* array; // 指向动态开辟的数组
size_t size ; // 有效数据个数
size_t capicity ; // 容量空间的大小
}SeqList;
如图所示:
- 注:静态顺序表已经确切的知道了需要开多少数据,所以为定长数组,虽然很方便,但是却不实用,现实中不可能先计算好字节大小再去开辟空间,如果不够了就作废了,开大了也就浪费了,所以我们一般选择动态开辟空间大小。那么我们主要用到对数据的增删查改操作,一起来实现一下这些功能吧。
代码如下:
SeqList.c
//顺序表的初始化
void SeqListInit(SeqList *ps, int capacity)
{
assert(ps != NULL);
if (ps != NULL)
{
return;
}
ps->array = malloc(sizeof(int)*capacity);
assert(ps->array != NULL);
ps->size = 0;
ps->capacity = capacity;
}
//顺序表的销毁
void SeqListDestroy(SeqList *ps)
{
assert(ps != NULL);
assert(ps->array != NULL);
//释放空间
free(ps->array);
ps->array = NULL;
ps->capacity = 0;
ps->size = 0;
}
//检查是否需要扩容
static void CheckCapacity(SeqList *ps)
{
if (ps->size < ps->capacity)
{
return;
}
//扩容
int newCapacity = ps->capacity * 2;
int *newArray = (int *)malloc(sizeof(int)*newCapacity);
assert(newArray != NULL);
for (int i = 0; i < ps->size; i++)
{
newArray[i] = ps->array[i];
}
//释放老空间,绑定新空间
free(ps->array);
ps->array = newArray;
ps->capacity = newCapacity;
}
//顺序表的尾插
void SeqListPushBack(SeqList *ps, int v)
{
CheckCapacity(ps);
ps->array[ps->size] = v;
ps->size++;
}
//顺序表的头插
void SeqListPushFront(SeqList *ps, int v)
{
CheckCapacity(ps);
for (int i = ps->size; i >= 1; i--)
{
ps->array[i] = ps->array[i - 1];
}
ps->array[0] = v;
ps->size++;
}
//在顺序表的特定位置插入值
void SeqListInsert(SeqList *ps, int pos, int v)
{
CheckCapacity(ps);
assert(pos >= 0 && pos <= ps->size);
for (int i = ps->size; i >= pos; i--)
{
ps->array[i] = ps->array[i-1];
}
ps->array[pos] = v;
ps->size++;
}
//顺序表的尾删
void SeqListPopBack(SeqList *ps)
{
assert(ps->size > 0);
ps->size--;
}
//顺序表的头删
void SeqListPopFront(SeqList *ps)
{
assert(ps->size > 0);
for (int i = 0; i < ps->size - 2; i++)
{
ps->array[i] = ps->array[i+1];
}
ps->size--;
}
//删除特定位置的值
void SeqListErase(SeqList *ps, int pos)
{
assert(pos >= 0 && pos <= ps->size);
for (int i = pos + 1; i < ps->size; i++)
{
ps->array[i - 1] = ps->array[i];
}
ps->size--;
}
//顺序表的查找
void SeqListFind(SeqList *ps, int v)
{
for (int i = 0; i < ps->size; i++)
{
if (ps->array[i] == v)
{
return 1;
}
}
return -1;
}
//顺序表的修改
void SeqListModify(SeqList *ps, int pos, int v)
{
assert(pos >= 0 && pos <= ps->size);
ps->array[pos] = v;
}
//顺序表找到指定位置并进行删除
void SeqListRemove(SeqList *ps, int pos, int v)
{
SeqListFind(ps, v);
if (pos == -1)
{
return;
}
SeqListErase(ps, v);
}
//顺序表找到指定的值,并将找到的特定值的所有元素都删除掉
void SeqListRemoveAll(SeqList *ps, int v)
{
int i, j;
for (i = 0, j = 0; i < ps->size; i++)
{
if (ps->array[i] != v)
{
ps->array[j] = ps->array[i];
}
j++;
}
ps->size = j;
}
SeqList.h
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int SqListType;
typedef struct SeqList
{
SqListType* arry;
size_t size;
size_t capicity;
}SeqList;
void SeqListInit(SeqList* ps, size_t capacity);
void SeqListDestory(SeqList* ps);
void CheckCapacity(SeqList* ps);
void SeqListPushBack(SeqList* ps, SqListType x);
void SeqListPopBack(SeqList* ps);
void SeqListprintf(SeqList* ps);
void SeqListPushFront(SeqList* ps, SqListType x);
void SeqListPopFront(SeqList* ps);
int SeqListFind(SeqList* ps, SqListType x);
void SeqListInsert(SeqList* ps, size_t pos, SqListType x);
void SeqListErase(SeqList* ps, size_t pos);
void SeqListModify(SeqList* ps, size_t pos, SqListType x);
void SeqListBubbleSort(SeqList* ps);
int SeqListBinaryFind(SeqList* ps, SqListType x);
void SeqListRemoveAll(SeqList* ps, SqListType x);
Test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"test.h"
int main()
{
SeqList s;
SeqListInit(&s, 2);
SeqListPushBack(&s, 1);//尾插
SeqListPushBack(&s, 1);
SeqListPushBack(&s, 9);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 4);
SeqListPushBack(&s, 6);
SeqListPushBack(&s, 5);
SeqListprintf(&s);
SeqListPopBack(&s);//尾删
SeqListprintf(&s);
SeqListPushFront(&s, 2);//头插
SeqListprintf(&s);
SeqListPopFront(&s);
SeqListprintf(&s);
SeqListInsert(&s, 0, 6);//插入
SeqListprintf(&s);
SeqListErase(&s, 0);
SeqListprintf(&s);
SeqListFind(&s, 1);//查找
printf("%d\n", SeqListFind(&s, 1));
SeqListModify(&s, 0, 66);//修改顺序表
SeqListprintf(&s);
SeqListBubbleSort(&s);//冒泡排序
SeqListprintf(&s);
SeqListBinaryFind(&s, 9);//二分查找
printf("%d\n", SeqListBinaryFind(&s, 9));
SeqListRemoveAll(&s, 1);
SeqListprintf(&s);
SeqListDestory(&s);
system("pause");
return 0;
}