顺序表的实现(迈入数据结构的大门)(完整代码)

seqlist.h

复制代码
#pragma once
typedef int SLDataType;

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

typedef struct SeqList
{
	SLDataType* a;
	int size; // 有效数据个数
	int capacity; // 空间容量
}SL;

//初始化和销毁
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);
//扩容
void SLCheckCapacity(SL* ps);
//头部插?删除 / 尾部插?删除
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
//指定位置之前插?/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLDataType x);

试着自己根据上方头文件,写一篇属于自己的顺序表吧!!!


复制代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"seqlist.h"

//typedef int SLdataTapy;
//#define N  10
//
//typedef struct seqlist {
//	SLdataTapy arr[N];//定长数组
//	int size;//有效数组个数
//}SL;


//typedef int SLdataTapy;
//
//typedef struct seqlist {
//	SLdataTapy* a;//用来开辟动态内存
//	int size;//有效数组个数
//	int capacity;//剩余容量;判断是否需要新添加内存
//}SL;

//初始化和销毁
void SLInit(SL* ps) {
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

void SLDestroy(SL* ps) {
	if (ps->a) {//判断数组中是否为空
		free(ps->a);//因为需要使用malloc,所以需要注意释放内存
	}
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

//扩容
void SLCheckCapacity(SL* ps) {
	//先要判断内存够不够
	if (ps->size == ps->capacity) {
		//使用malloc relloc celloc
		int newcappacity = ps->capacity == 0 ? 4 :ps->capacity*2;//一般增容原来内存的二到三倍;
		SLDataType*tmp = (SLDataType*)relloc(ps->a,newcappacity * sizeof(SLDataType));
		//注:这里没有直接使用ps->a直接申请,是为了防止内存申请失败;防止数据丢失
		if (tmp == NULL) {//也可以使用assert直接终止程序;需要使用aseert.h的头文件
			perror("relloc fail");
			exit(1);//直接退出程序;也可使用return;
		}
		//空间增容成功
		ps->a = tmp;
		ps->capacity = newcappacity;
	}
}
//头插
void SLPushFront(SL* ps, SLDataType x) {
	//记住SLDataType,这里为我们为了方便(typedef int SLDataType)
	assert(ps);//断言一下,防止指针为空
	SLCheckCapacity(&ps);//开辟空间
	int i = ps->size;
	for (; i > 0; i--);//从后往前移位
	{
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[0] = x;//此时a[0]就空出来存放x;
	ps->size++;//不要忘记size需要++
}
//头删
void SLPopFront(SL* ps) {
	assert(ps);
	assert(ps->size);//存放的值不能为NULL;
	for (int i = 0; i < ps->size-1; i++) {
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}
//尾插
void SLPushBack(SL* ps, SLDataType x) {
	assert(ps);
	void SLCheckCapacity(SL * ps);
	ps->a[ps->size++] = x;
	//相当于ps->a[ps->size] = x;
	//ps->size++;
}
//尾删
void SLPopBack(SL* ps) {
	assert(ps);
	assert(ps->size);//进行尾删,必须存在尾删的值
	ps->size--;
}

//查找
int SLFind(SL* ps, SLDataType x) {
	assert(ps);
	for (int i = 0; i < ps->size; i++) {
		if (ps->a[i] == x) {
			return i;
		}
	}
	return -1;
}
//指定位置插入
void SLInsert(SL* ps, int pos, SLDataType x) {
	assert(ps);
	assert(pos >= 0 && ps->size > pos);//pos必须在含有值之间插入
	//插入数据:空间够不够
	SLCheckCapacity(ps);
	//让pos及之后的数据整体往后挪动一位
	for (int i = ps->size; i > pos; i--)
	{
		ps->a[i] = ps->a[i - 1];//a[pos+1] = a[pos]与头插具有相似之处,导致值的覆盖
	}
	ps->a[pos] = x;//这里的pos对应,数组下标,如果不对应,则按情况+-;
	ps->size++;
}
//删除指定位置的数据
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	//与头删类似
	for (int i = pos; i < ps->size - 1; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}
void SLPrint(SL s)//对于打印数组,这里不再需要传地址,而是传值
{
	for (int i = 0; i < s.size; i++)
	{//对于结构体的使用  (.)与(->)的不同
		printf("%d ", s.a[i]);
	}
	printf("\n");
}

下一节我们将实现(通讯录)顺序表

相关推荐
weixin_307779132 小时前
C++代码实现MATLAB中的dlarray函数功能
开发语言·c++·算法·matlab
Frank_refuel5 小时前
C++11之一场名为“搬家”的 C++ 之旅
开发语言·c++
海绵宝宝转agent6 小时前
learn-claude-code第1-5章开源学习笔记分享
人工智能·笔记·python·学习
hetao17338377 小时前
2026-10-03~04 hetao1733837 的刷题记录
c++·算法
Zootopia6268 小时前
飞行力学知识梳理1|飞行性能与稳定性
人工智能·python·算法·机器学习·无人机·学习方法·信息与通信
longlongzihan8 小时前
从LeetCode 70. 爬楼梯看动态规划:如何精准推导状态转移方程?
c++·算法·leetcode·动态规划
91刘仁德9 小时前
HTTP协议详解:从URL到HTTP服务器的完整实战
服务器·网络·笔记·网络协议·http
2601_960356389 小时前
2027校招采购岗解析:数学基础如何迁移到需求预测、成本与供应商分析
人工智能·算法
h_a_o777oah10 小时前
【树论】树链剖分:将树形结构转化为线性结构以处理树上路径问题(洛谷 P3384 附C++代码模板)
数据结构·算法·线段树·acm·树链剖分·树论·重链剖分
HEJOO910 小时前
指针的算术运算详解
java·数据结构·算法