数据结构:顺序表(动态顺序表)

专栏说明:本专栏用于数据结构复习,文章中出现的代码由C语言实现,在专栏中会涉及到部分OJ题目,如对你学习有所帮助,可以点赞鼓励一下博主喔💓


  • 博客主页:Duck Bro 博客主页
  • 系列专栏:数据结构专栏
  • 关注博主,后期持续更新系列文章
  • 如果有错误感谢请大家批评指出,及时修改
  • 感谢大家点赞👍收藏⭐评论✍

数据结构:顺序表(动态顺序表)

目录

  • 数据结构:顺序表(动态顺序表)
    • [1. 概念与结构](#1. 概念与结构)
      • [1.1 概念](#1.1 概念)
      • [1.2 结构](#1.2 结构)
    • [2. 接口实现](#2. 接口实现)
      • [2.1 动态顺序表结构](#2.1 动态顺序表结构)
      • [2.2 顺序表初始化](#2.2 顺序表初始化)
      • [2.3 顺序表销毁](#2.3 顺序表销毁)
      • [2.4 检查空间、扩容](#2.4 检查空间、扩容)
      • [2.5 顺序表尾插](#2.5 顺序表尾插)
      • [2.6 顺序表尾删](#2.6 顺序表尾删)
      • [2.7 顺序表头插](#2.7 顺序表头插)
      • [2.8 顺序表头删](#2.8 顺序表头删)
      • [2.9 顺序表查找](#2.9 顺序表查找)
      • [2.10 在pos位置插入x](#2.10 在pos位置插入x)
      • [2.11 删除pos位置值](#2.11 删除pos位置值)
      • [2.12 修改pos位置值](#2.12 修改pos位置值)
      • [2.13 打印顺序表](#2.13 打印顺序表)
    • [3. 详细代码页](#3. 详细代码页)
      • [3.1 SeqList.h](#3.1 SeqList.h)
      • [3.2 SeqList.c](#3.2 SeqList.c)
      • [3.3 main.c](#3.3 main.c)

1. 概念与结构

1.1 概念

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存

储。在数组上完成数据的增删查改。

1.2 结构

静态顺序表:使用定长数组存储元素。

c 复制代码
#define N 7
typedef int DataType;
typedef struct SeqList
{
	DataType a[N];
	int size;
	int capacity;
}SL;

动态顺序表:使用动态开辟的数组存储。

c 复制代码
typedef int DataType;
typedef struct SeqList
{
	DataType* a;
	int size;
	int capacity;
}SL;

2. 接口实现

2.1 动态顺序表结构

c 复制代码
//顺序表动态存储
typedef int DataType;
typedef struct SeqList
{
	DataType* a;	//指点动态开辟数组
	int size;		//有效数据个数
	int capacity;	//容量空间大小
}SL;

2.2 顺序表初始化

c 复制代码
void SLInit(SL* pc)
{
	//断言
	assert(pc);
	//pc->a = NULL;
	pc->a = (DataType*)malloc(sizeof(DataType) * 4);
	//判断是否为空
	if (pc->a == NULL)
	{
		//报错提示
		perror("SLInit faild");
		//退出程序
		exit(-1);
	}
	//顺序表内的数据个数
	pc->size = 0;
	//顺序表内的容量
	pc->capacity = 4;
}

2.3 顺序表销毁

c 复制代码
void SLDestroy(SL* pc)
{
	//断言
	assert(pc);
	//释放内存
	free(pc->a);
	//将指针置为空
	pc->a = NULL;
	//设置数据个数和容量为0个
	pc->size = 0;
	pc->capacity = 0;
}

2.4 检查空间、扩容

c 复制代码
void SLCheckCapacity(SL* pc)
{
	//断言
	assert(pc);
	//如果size==capacity,则进行二倍扩容
	if (pc->size == pc->capacity)
	{
		DataType* temp = (DataType*)realloc(pc->a, pc->capacity * sizeof(DataType) * 2);
		//进行判断是否开辟成功
		if (temp == NULL)
		{
			perror("SLCheckCapacity faild");
			exit(-1);
		}
		pc->a = temp;
		pc->capacity *= 2;
	}
}

2.5 顺序表尾插

c 复制代码
void SLPushBack(SL* pc, DataType x)
{
	assert(pc);

	/*assert(pc);
	SLCheckCapacity(pc);
	pc->a[pc->size] = x;
	pc->size++;*/
	SLInsert(pc, pc->size, x);
}

2.6 顺序表尾删

c 复制代码
void SLPopBack(SL* pc)
{
	assert(pc);
	/*assert(pc);
	assert(pc->size);
	pc->size--;*/
	SLErase(pc, pc->size - 1);
}

2.7 顺序表头插

c 复制代码
void SLPushFront(SL* pc, DataType x)
{
	assert(pc);

	断言
	//assert(pc);
	检查空间是否足够
	//SLCheckCapacity(pc);
	end为顺序表中最后一个数据的下标
	//int end = pc->size - 1;
	将所有数据进行后移
	//while (end >= 0)
	//{
	//	pc->a[end + 1] = pc->a[end];
	//	--end;

	//}
	//pc->a[0] = x;
	//pc->size++;
	SLInsert(pc, 0, x);

}

2.8 顺序表头删

c 复制代码
void SLPopFront(SL* pc)
{
	assert(pc);

	/*assert(pc->size > 0);
	int begin = 1;
	while (begin < pc->size)
	{
		pc->a[begin - 1] = pc->a[begin];
		begin++;

	}
	pc->size--;*/
	SLErase(pc, 0);
}

2.9 顺序表查找

c 复制代码
int SLFind(SL* pc, DataType x)
{

	assert(pc);
	for (int i = 0; i < pc->size; i++)
	{
		if (x == pc->a[i])
		{
			return i;
		}
	}
	return -1;
}

2.10 在pos位置插入x

c 复制代码
void SLInsert(SL* pc, int pos, DataType x)
{
	assert(pos >= 0 && pos <= pc->size);
	SLCheckCapacity(pc);
	int end = pc->size - 1;
	while (end >= pos)
	{
		pc->a[end + 1] = pc->a[end];
		end--;
	}
	pc->a[pos] = x;
	pc->size++;
}

2.11 删除pos位置值

c 复制代码
void SLErase(SL* pc, int pos)
{
	assert(pc);
	assert(pos>=0&&pos<pc->size);

	int begin = pos + 1;
	while (begin < pc->size)
	{
		pc->a[begin-1] = pc->a[begin];
		begin++;
	}
	pc->size--;
}

2.12 修改pos位置值

c 复制代码
void SLModify(SL* pc, int pos, DataType x)
{
	assert(pc);

	assert(pos <= 0 && pos < pc->size);
	pc->a[pos] = x;

}

2.13 打印顺序表

c 复制代码
void SLPrintf(SL* pc)
{
	//断言
	assert(pc);
	//遍历
	int i = 0;
	for (i = 0; i < pc->size; i++)
	{
		printf("%d ", pc->a[i]);
	}
	printf("\n");
}

3. 详细代码页

3.1 SeqList.h

c 复制代码
#define  _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int DataType;
typedef struct SeqList
{
	DataType* a;
	int size;
	int capacity;
}SL;

//顺序表初始化
void SLInit(SL* pc);
//顺序表销毁
void SLDestroy(SL* pc);
//容量检查,并进行扩容
void SLCheckCapacity(SL* pc);
//打印顺序表中的数据 遍历顺序表
void SLPrintf(SL* pc);

//顺序表头插
void SLPushFront(SL* pc, DataType x);
//顺序表尾删
void SLPopBack(SL* pc);
//顺序表尾插
void SLPushBack(SL* pc, DataType x);
//顺序表头删
void SLPopFront(SL* pc);

//查找位置
int SLFind(SL* pc ,DataType x);
//顺序表pos位置前插入X
void SLInsert(SL* pc, int pos,DataType x);
//顺序表删除pos位置值
void SLErase(SL* pc,int pos);
//修改pos位置值
void SLModify(SL* pc, int pos,DataType x);

3.2 SeqList.c

c 复制代码
#define  _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"


void SLInit(SL* pc)
{
	//断言
	assert(pc);
	//pc->a = NULL;
	pc->a = (DataType*)malloc(sizeof(DataType) * 4);
	//判断是否为空
	if (pc->a == NULL)
	{
		//报错提示
		perror("SLInit faild");
		//退出程序
		exit(-1);
	}
	//顺序表内的数据个数
	pc->size = 0;
	//顺序表内的容量
	pc->capacity = 4;
}

void SLDestroy(SL* pc)
{
	//断言
	assert(pc);
	//释放内存
	free(pc->a);
	//将指针置为空
	pc->a = NULL;
	//设置数据个数和容量为0个
	pc->size = 0;
	pc->capacity = 0;

}

void SLCheckCapacity(SL* pc)
{
	//断言
	assert(pc);
	//如果size==capacity,则进行二倍扩容
	if (pc->size == pc->capacity)
	{
		DataType* temp = (DataType*)realloc(pc->a, pc->capacity * sizeof(DataType) * 2);
		//进行判断是否开辟成功
		if (temp == NULL)
		{
			perror("SLCheckCapacity faild");
			exit(-1);
		}
		pc->a = temp;
		pc->capacity *= 2;

	}
}

void SLPrintf(SL* pc)
{
	//断言
	assert(pc);
	//遍历
	int i = 0;
	for (i = 0; i < pc->size; i++)
	{
		printf("%d ", pc->a[i]);
	}
	printf("\n");
}

void SLPushFront(SL* pc, DataType x)
{
	assert(pc);

	断言
	//assert(pc);
	检查空间是否足够
	//SLCheckCapacity(pc);
	end为顺序表中最后一个数据的下标
	//int end = pc->size - 1;
	将所有数据进行后移
	//while (end >= 0)
	//{
	//	pc->a[end + 1] = pc->a[end];
	//	--end;

	//}
	//pc->a[0] = x;
	//pc->size++;
	SLInsert(pc, 0, x);

}

void SLPopBack(SL* pc)
{
	assert(pc);
	/*assert(pc);
	assert(pc->size);
	pc->size--;*/
	SLErase(pc, pc->size - 1);
}

void SLPushBack(SL* pc, DataType x)
{
	assert(pc);

	/*assert(pc);
	SLCheckCapacity(pc);
	pc->a[pc->size] = x;
	pc->size++;*/
	SLInsert(pc, pc->size, x);
}

void SLPopFront(SL* pc)
{
	assert(pc);

	/*assert(pc->size > 0);
	int begin = 1;
	while (begin < pc->size)
	{
		pc->a[begin - 1] = pc->a[begin];
		begin++;

	}
	pc->size--;*/
	SLErase(pc, 0);
}

void SLInsert(SL* pc, int pos, DataType x)
{
	assert(pos >= 0 && pos <= pc->size);
	SLCheckCapacity(pc);
	int end = pc->size - 1;
	while (end >= pos)
	{
		pc->a[end + 1] = pc->a[end];
		end--;
	}
	pc->a[pos] = x;
	pc->size++;
}

void SLErase(SL* pc, int pos)
{
	assert(pc);
	assert(pos>=0&&pos<pc->size);

	int begin = pos + 1;
	while (begin < pc->size)
	{
		pc->a[begin-1] = pc->a[begin];
		begin++;
	}
	pc->size--;
}

int SLFind(SL* pc, DataType x)
{

	assert(pc);
	for (int i = 0; i < pc->size; i++)
	{
		if (x == pc->a[i])
		{
			return i;
		}
	}
	return -1;
}

void SLModify(SL* pc, int pos, DataType x)
{
	assert(pc);

	assert(pos <= 0 && pos < pc->size);
	pc->a[pos] = x;

}

3.3 main.c

c 复制代码
#include "SeqList.h"
void test1()
{
	//测试创建顺序表初始化 销毁
	SL s;
	SLInit(&s);
	SLDestroy(&s);
}

void test2()
{
	//测试顺序表尾插插
	SL s1;
	SLInit(&s1);
	
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	//SLPushFront(&s1, 4);
	//SLPushFront(&s1, 4);

	//SLPopBack(&s1);
	//SLPopBack(&s1);
	SLPopBack(&s1);
	SLPopBack(&s1);


	SLPushBack(&s1, 67);
	SLPushBack(&s1, 67);
	SLPushBack(&s1, 67);

	SLPrintf(&s1);
	SLDestroy(&s1);
}

void test3()
{
	//测试顺序表尾插插
	SL s1;
	SLInit(&s1);

	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPrintf(&s1);

	//SLPushFront(&s1, 4);
	SLPushFront(&s1, 66);



	SLPrintf(&s1);
	SLDestroy(&s1);
}

void test4()
{
	//测试顺序表尾插插
	SL s1;
	SLInit(&s1);

	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	SLPushBack(&s1, 5);
	//SLInsert(&s1, 2, 7);
	int x = 0;
	scanf("%d", &x);
	int pos = SLFind(&s1, x);
	if (pos != -1)
	{
		SLInsert(&s1, pos, 50);
	}


	SLPrintf(&s1);
	SLDestroy(&s1);
}
void test5()
{
	//测试顺序表尾插插
	SL s1;
	SLInit(&s1);

	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLPushBack(&s1, 5);
	//SLInsert(&s1, 2, 7);
	SLPopBack(&s1);
	SLPopFront(&s1);


	SLPrintf(&s1);
	SLDestroy(&s1);
}
int main()
{
	//test1();
	//test2();
	//test3();
	//test4();
	test5();

	return 0;
}

相关推荐
VertexGeek13 分钟前
Rust学习(三):rust基础Ⅱ
开发语言·学习·rust
九年义务漏网鲨鱼18 分钟前
【人脸伪造检测后门攻击】 Exploring Frequency Adversarial Attacks for Face Forgery Detection
论文阅读·python·算法·aigc
_OLi_24 分钟前
力扣 LeetCode 977. 有序数组的平方(Day1:数组)
数据结构·算法·leetcode
励志成为嵌入式工程师39 分钟前
c语言选择排序
c语言·算法·排序算法
三小尛41 分钟前
希尔排序(C语言)
c语言·数据结构·排序算法
風清掦43 分钟前
C/C++每日一练:编写一个查找子串的位置函数
c语言·c++·算法
三小尛1 小时前
插入排序(C语言)
c语言·开发语言
南宫理的日知录1 小时前
106、Python并发编程:深入浅出理解线程池的内部实现原理
开发语言·python·学习·编程学习
WolvenSec1 小时前
C/C++逆向:结构体逆向分析
c语言·开发语言·c++·网络安全
A charmer1 小时前
算法每日双题精讲——滑动窗口(最大连续1的个数 III,将 x 减到 0 的最小操作数)
c++·算法·leetcode