前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【初阶数据结构】- 顺序表

【初阶数据结构】- 顺序表

作者头像
_孙同学
发布2024-10-21 20:51:53
860
发布2024-10-21 20:51:53
举报
文章被收录于专栏:技术分享

1. 顺序表的概念及结构

1.1 线性表

顺序表是一种线性表,线性表是n个具有相同特性的数据元素的有限序列,常见的线性表有:顺序表,链表,栈,队列 👉线性表的逻辑结构:在逻辑上是一条连续的直线。 👉线性表的物理结构:线性表在物理结构上并不是连续的,线性表在物理上存储时通常以数组链式的结构存储的。

2. 顺序表的分类

顺序表与数组的关系

◦ 顺序表的底层结构就是数组,通过对数组的封装,实现增删查改等功能。

• 顺序表的分类: ◦静态顺序表

代码语言:javascript
复制
//使用定长数组存储数据
typedef int SLDataType;
#define N 10
typedef struct SeqList
{
	SLDataType a[N];//定长数组
	int size;//有效元素的个数
}SL;

❗️缺点:空间是死的,短了不够用,长了会造成空间的浪费。 ◦动态顺序表

代码语言:javascript
复制
//按需申请
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* arr;//动态数组。动态内存开辟,确定大小之后再去动态申请
	int size;//顺序表当前有效元素的个数
	int capacity; //顺序表的空间大小
}SL;

3. 动态顺序表的实现

3.1 头文件.h

顺序表结构的声明

代码语言:javascript
复制
#include<stdio.h>
#include<stdlib.h>//需要动态申请内存的头文件
#include<assert.h>
typedef int SLDataType;
// 动态顺序表 -- 按需申请 
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);
3.2 .C文件

实现顺序表的方法

代码语言:javascript
复制
//顺序表的初始化
void SLInit(SL* ps)
{
	assert(ps);
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}
//顺序表的销毁
void SLDestroy(SL* ps)
{
	assert(ps);
	if (ps->arr)//如果arr不等于空
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}
//打印顺序表中的数据
void SLPrint(SL* ps)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ",ps->arr[i]);
	}
	
}
//扩容 
void SLCheckCapacity(SL* ps)
{
	assert(ps);
	if (ps->size == ps->capacity)
	{
		//申请空间
		//malloc calloc realloc 因为要涉及增容,所以用realloc
		int newcapacity = ps->capacity == 0 ? 4 : 2* ps->capacity ;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));//realloc申请的是字节大小,*(SLDtaType)整形大小
		if (tmp == NULL)
		{
			perror("realloc fail");//空间申请失败,报错
			exit(1);//直接退出程序,不再继续执行
		}
		//申请空间成功
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}

}
//顺序表的尾部插入
void SLPushBack(SL* ps, SLDataType x)
{
	//温柔的方法
	/*if (ps == NULL)
	{
		return;
	}*/
	assert(ps);//暴力方法
	if(ps->size==ps->capacity)
	SLCheckCapacity(ps);
	//ps->arr[ps->size] = x;
	//ps->size++;
	ps->arr[ps->size++] = x;
}
//顺序表的尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);
	--ps->size;
}
//顺序表的头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i-1];
	}
	ps->arr[0] = x;
	ps->size++;
}
//头删
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);
	for (int i = 0; i<ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i+1];
	}
	ps->size--;
}
//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos>=0 && pos<=ps->size);
	//插入数据之前看数据够不够
	SLCheckCapacity(ps);
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i-1];
	}
	ps->arr[pos] = x;
	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->arr[i] = ps ->arr[i + 1];
	}
	ps->size--;
}
//查找顺序表中的数据
int SLFind(SL* ps, SLDataType x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->arr[i] == x)
		{
			//找到了
			return i;
		}
	}
	return -1;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 顺序表的概念及结构
    • 1.1 线性表
    • 2. 顺序表的分类
    • 3. 动态顺序表的实现
      • 3.1 头文件.h
        • 3.2 .C文件
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档