C语言实现数据结构——顺序表

在数据结构的开端,存在一个最简单但是局限性很大的一个数据结构,叫做顺序表
顺序表的书写还是分为SeqList.c,SeqList.h,test.c文件进行书写
先表明顺序表作为数据结构的一种缺陷:由于顺序表的实现大多都用的是数组进行实现,所以他的数据只能进行连续存放在一片内存中

SeqList.h文件

先书写我们所需要的接口函数

#pragma once 
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef struct SeqList
{
	int* a;//数组
	int size;//顺序表中存储了多少个元素
	int capacity;//顺序表中的最大容量
}SL;

void SeqListPrint(SL* ps);//打印整个顺序表
void SeqListInit(SL* ps);//顺序表的初始化
void SeqListDestroy(SL* ps);//顺序表的销毁
void SeqListCheck(SL* ps);//检查顺序表的存储是否足够
void SeqListPushBack(SL* ps,int x);//尾插顺序表
void SeqListPopBack(SL* ps);//尾删顺序表
void SeqListPushFront(SL* ps, int x);//头插顺序表
void SeqListPopFront(SL* ps);//头删顺序表
int SeqListFind(SL* ps, int x);//查找顺序表中的元素,并且返回其下标
void SeqListInsert(SL* ps, int pos, int x);//将元素x插入到pos位置
void SeqListErase(SL* ps, int x);//消除为x的元素

这里看起来顺序表的函数接口十分多,但是由于顺序表的一个结构特征是一个数组,所以大部分的接口采用一个遍历的思想

SeqList.c文件

下面来实现这些接口函数

SeqListInit函数

void SeqListInit(SL* ps)
{
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

由于这里只是对一个顺序表进行初始化,还没有对顺序表进行创造存储空间,所以只需要把size和capacity全部赋值为0即可

SeqListCheck函数

void SeqListCheck(SL* ps)
{
	if (ps->capacity == ps->size)
	{
		int new = 0;
		if (ps->capacity == 0)
		{
			new = 4;
		}
		else
		{
			new = ps->capacity * 2;
		}
		int* tmp = (int*)realloc(ps->a, new * sizeof(int));
		if (tmp == NULL)
		{
			printf("malloc fail\n");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = new;
	}

}

注意这个地方判断顺序表是否被装满的条件:顺序表中的容量和已经存放的元素的数量是否相等
同时需要注意realloc的用法

SeqListPushBack函数

这个函数是在顺序表的尾部插入元素

void SeqListPushBack(SL* ps, int x)
{
	SeqListCheck(ps);
	ps->a[ps->size] = x;
	ps->size++;
}

这个尾插函数只需要注意在插入之前先判断顺序表是否需要扩容

SeqListPopBack函数

这个函数是在顺序表的尾部删除元素

void SeqListPopBack(SL* ps)
{
	ps->size--;
}

这个接口函数看起来很简单,但是需要对结构体和数组的关系需要有一定的认识
我们只需要将结构体中的size(顺序表存储元素个数)进行减少一个,那么就相当于无法再访问到顺序表的最后一个元素,也就等同于是删除了顺序表的最后一个元素

SeqListPushFront函数

这个函数是在顺序表的头部插入一个元素

void SeqListPushFront(SL* ps, int x)
{
	SeqListCheck(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{
		end--;
		ps->a[end + 1] = ps->a[end];
	}
	ps->a[0] = x;
	ps->size++;
}

这个顺序表的头插需要对顺序表中的数据进行一个移位的处理,先标记最后一个元素的下标end,再将顺序表中的所有元素往后面挪一位

SeqListPopFront函数

void SeqListPopFront(SL* ps)
{
	int begin = 1;
	while (begin < ps->size)
	{
		begin++;
		ps->a[begin - 1] = ps->a[begin];
	}
	ps->size--;
}

还是利用一个移位的原理,将第一个元素进行覆盖

SeqListErase函数

void SeqListErase(SL* ps, int x)
{
	int i = 0;
	int j = 0;
	for (i = 0;i < ps->size;i++)
	{
		if (ps->a[i] == x)
		{
			for (j = i;j < ps->size;i++)
			{
				ps->a[j] = ps->a[j + 1];
			}
			ps->size--;
		}
	}
}

先对链表中的每个元素做一个遍历,当找到元素的值和我们需要寻找的x的值相同时,记录他的下标为i
然后将下标为i后面的元素全部往前挪一个,这样就可以达到一个消除一个元素的结果

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值