数据结构(初阶)(二)----顺序表

顺序表

概念与结构

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

顺序表实现

头文件

c 复制代码
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int SLTDataType;
typedef struct SeqList 
{
	SLTDataType* arr;
	int size;
	int capacity;
}SLT;

//初始化
void SLTInit(SLT* slt);

//判断空间大小,如果不够增容
void SLTCheckCapacity(SLT* ps);

//尾插
void SLTPushBack(SLT* ps,SLTDataType x);

//打印顺序表
void SLTPrint(SLT* ps);

//头插
void SLTPushFront(SLT* ps, SLTDataType x);

//尾删
void SLTPopBack(SLT* ps);

//头删
void SLTPopFront(SLT* ps);

//查找元素,返回对应位置下标,没有返回-1
int SLTFind(SLT* ps, SLTDataType x);

//指定位置之前插入数据
void SLTInsert(SLT* ps, int pos, SLTDataType x);

//删除指定位置元素
void SLTErase(SLT* ps, int pos);

//销毁顺序表
void SLTDestory(SLT* ps);

创建与初始化

c 复制代码
#define _CRT_SECURE_NO_WARNINGS

#include"SeqList.h"

//初始化
void SLTInit(SLT* ps)
{
	assert(ps);
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

尾插

在插入之前我们需要先判断顺序表的空间大小是否足够,如果不够就需要对原有空间增容,判断依据是size == capacity,如果等式成立,那么空间就满了,需要增容。

增容,一般是成倍的增加,这里我们使用2倍的增容。

判断空间大小
c 复制代码
//判断空间大小,如果不够增容
void SLTCheckCapacity(SLT* ps)
{
	assert(ps);
	if (ps->size == ps->capacity)
	{
		//注意在初始状态下,空间大小为0,需要判断给定初始空间
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		//扩容有可能失败,需要创建新的指针来接收,成功后再赋给原数组
		SLTDataType* tmp = (SLTDataType*)realloc(ps->arr, newCapacity * sizeof(SLTDataType));
		if (tmp == NULL)
		{
			perrpr("SLTCheckCapacity()::realloc fail");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newCapacity;
	}
}
c 复制代码
//尾插
void SLTPushBack(SLT* ps,SLTDataType x)
{
	assert(ps);
    SLTCheckCapacity(ps);
	ps->arr[ps->size++] = x;
}

头插

c 复制代码
//头插
void SLTPushFront(SLT* ps, SLTDataType x)
{
	assert(ps);
	SLTCheckCapacity(ps);
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	++ps->size;
}

尾删

时间复杂度为O(1)

c 复制代码
//尾删
void SLTPopBack(SLT* ps)
{
	//顺序表不为空,且有效数据个数不为0
	assert(ps && ps->size);
	--ps->size;
}

头删

时间复杂度O(n)

c 复制代码
//头删
void SLTPopFront(SLT* ps)
{
	//顺序表不为空,且有效数据个数不为0
	assert(ps && ps->size);
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	--ps->size;
}

查找

c 复制代码
//查找元素,返回对应位置下标,没有返回-1
int SLTFind(SLT* ps, SLTDataType x)
{
	assert(ps);
	if (ps->size == 0)
	{
		return -1;
	}

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

指定位置之前插入数据

c 复制代码
//指定位置之前插入数据
void SLTInsert(SLT* ps, int pos, SLTDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	++ps->size;
}

指定位置删除数据

c 复制代码
//删除指定位置元素
void SLTErase(SLT* 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;
}

销毁(回收)

c 复制代码
//销毁顺序表
void SLTDestory(SLT* ps)
{
	assert(ps);
	if (ps->arr)
		free(ps->arr);
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

测试文件

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

void test1()
{
	SLT slt;
	SLTInit(&slt);

	//尾插
	SLTPushBack(&slt,1);
	SLTPushBack(&slt,2);
	SLTPushBack(&slt,3);
	SLTPushBack(&slt,4);
	SLTPushBack(&slt,5);

	头插
	//SLTPushFront(&slt, 11);
	//SLTPushFront(&slt, 12);
	//SLTPushFront(&slt, 13);
	//SLTPushFront(&slt, 14);


	///尾删
	//SLTPopBack(&slt);
	//SLTPopBack(&slt);

	//头删
	//SLTPopFront(&slt);
	//SLTPopFront(&slt);

	//打印顺序表
	SLTPrint(&slt);

	//查找元素,返回对应位置下标,没有返回-1
	int ret = SLTFind(&slt, 12);
	printf("%d\n", ret);

	指定位置之前插入数据
	//SLTInsert(&slt, ret, 21);
	//SLTInsert(&slt, ret, 22);

	//删除指定位置元素
	SLTErase(&slt, ret);
	SLTErase(&slt, ret);

	//打印顺序表
	SLTPrint(&slt);

	销毁顺序表
	//SLTDestory(&slt);
}

int main()
{
	test1();
	
	return 0;
}
相关推荐
三品吉他手会点灯27 分钟前
STM32 VSCode 开发-C/C++的环境配置中,找不到C/C++: Edit Configurations选项
c语言·c++·vscode·stm32·单片机·嵌入式硬件·编辑器
逻辑驱动的ken44 分钟前
Java高频面试考点场景题09
java·开发语言·数据库·算法·oracle·哈希算法·散列表
帅小伙―苏1 小时前
力扣42接雨水
前端·算法·leetcode
AI科技星1 小时前
精细结构常数α的几何本源:从第一性原理的求导证明、量纲分析与全域验证
算法·机器学习·数学建模·数据挖掘·量子计算
三品吉他手会点灯1 小时前
C语言学习笔记 - 1.C概述 - 本讲内容概述
c语言·笔记·学习
6Hzlia1 小时前
【Hot 100 刷题计划】 LeetCode 287. 寻找重复数 | C++ 数组判环 (快慢指针终极解法)
c++·算法·leetcode
MegaDataFlowers1 小时前
26.删除有序数组中的重复项
算法
码完就睡3 小时前
数据结构——栈和队列的相互模拟
数据结构
iiiiyu3 小时前
常用API(SimpleDateFormat类 & Calendar类 & JDK8日期 时间 日期时间 & JDK8日期(时区) )
java·大数据·开发语言·数据结构·编程语言
故事和你913 小时前
洛谷-数据结构1-4-图的基本应用2
开发语言·数据结构·算法·深度优先·动态规划·图论