当前位置: 首页 > news >正文

【数据结构】知识点一:线性表之顺序表

内容导航

  • 一、什么是线性表?
  • 二、什么是顺序表?
    • 1、顺序表的概念
    • 2、顺序表的结构
      • a. 静态顺序表:使用定长数组存储元素。
      • b. 动态顺序表:使用动态开辟的数组存储。
  • 三、顺序表的接口实现精讲
    • 1.接口一:打印数据
    • 2.接口二:表初始化
    • 3.接口三:数据销毁
    • 4.接口四:尾插数据
    • 5.接口五:尾删数据
    • 6.接口六:头插数据
    • 7.接口七:头删数据
    • 8.接口八:容量检查
    • 9.接口九:任意位置的插入
    • 9.接口九:任意位置的删除
    • 10.接口十:任意数据的查找
  • 四、源代码分享
    • 1.SeqList.h
    • 2.SeqList.c
    • 3.test.c

一、什么是线性表?

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
在这里插入图片描述

二、什么是顺序表?

1、顺序表的概念

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,在数组上完成数据的增删查改。

2、顺序表的结构

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

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

三、顺序表的接口实现精讲

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用,所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

1.接口一:打印数据

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLPrint(SL* ps1)								//打印数据
{assert(ps1);for (int i = 0; i < ps1->size; i++){printf("%d ", ps1->a[i]);}printf("\n");
}

2.接口二:表初始化

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLInit(SL* ps1)							//初始化顺序表,全部为0
{assert(ps1);ps1->a = NULL;ps1->size = 0;ps1->capacity = 0;
}

3.接口三:数据销毁

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLDestroy(SL* ps1)							//销毁顺序表
{assert(ps1);if (ps1->a != NULL)							{free(ps1->a);ps1->a = NULL;ps1->size = 0;ps1->capacity = 0;}
}

4.接口四:尾插数据

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLPushBack(SL* ps1, SLDataType x)			//尾插入
{assert(ps1);SLCheckCapacity(ps1);						//检查容量ps1->a[ps1->size] = x;ps1->size++;
}

5.接口五:尾删数据

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLPopBack(SL* ps1)							//尾删除
{assert(ps1);assert(ps1->size > 0);						//有效数据为0则不需要删ps1->size--;
}

6.接口六:头插数据

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLPushFront(SL* ps1, SLDataType x)		//头插入
{assert(ps1);SLCheckCapacity(ps1);						//检查容量//往后挪动数据int end = ps1->size - 1;while (end >= 0){ps1->a[end + 1] = ps1->a[end];end--;}ps1->a[0] = x;ps1->size++;
}

7.接口七:头删数据

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLPopFront(SL* ps1)						//头删除
{assert(ps1);assert(ps1->size > 0);						//有效数据为0则不需要删//往前挪动数据int begin = 1;while (begin < ps1->size){ps1->a[begin - 1] = ps1->a[begin];begin++;}ps1->size--;
}

8.接口八:容量检查

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLCheckCapacity(SL* ps1)					//检查空间是否充足,若否,使空间充足,头插尾插都要用到
{assert(ps1);if (ps1->size == ps1->capacity){int NewCapacity = ps1->capacity == 0 ? 4 : ps1->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps1->a, sizeof(SLDataType) * NewCapacity);if (tmp == NULL){perror("realloc fail");return;}ps1->a = tmp;ps1->capacity = NewCapacity;}
}

9.接口九:任意位置的插入

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLInsert(SL* ps1, int pos, SLDataType x)	//任意位置的插入
{assert(ps1);assert(pos >= 0 && pos <= ps1->size);		//确保pos大小的有效性SLCheckCapacity(ps1);						//检查容量//往后挪动数据int end = ps1->size - 1;while (end > pos){ps1->a[end + 1] = ps1->a[end];end--;}ps1->a[pos] = x;ps1->size++;
}

9.接口九:任意位置的删除

<font color=black size=4 font face=黑体" >代码之函数的定义:

void SLErase(SL* ps1, int pos)					//任意位置的删除
{assert(ps1);assert(pos >= 0 && pos <= ps1->size);		//确保pos大小的有效性//往前挪动数据int begin = pos+1;while (begin < ps1->size){ps1->a[begin - 1] = ps1->a[begin];begin++;}ps1->size--;
}

10.接口十:任意数据的查找

<font color=black size=4 font face=黑体" >代码之函数的定义:

int SLFind(SL* ps1, SLDataType x)				//查找某个数据,找到返回下标,未找到返回-1
{assert(ps1);for (int i = 0; i < ps1->size; i++)			//直接遍历查找{if (ps1->a[i] == x){return i;}}return -1;
}

四、源代码分享

1.SeqList.h

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
typedef int SLDataType;typedef struct SeqList
{SLDataType* a;							//开辟的数组地址int size;								//有效数据个数int capacity;							//容量空间的大小
}SL;void SLPrint(SL* ps1);						//打印数据
void SLInit(SL* ps1);						//初始化顺序表,全部为0
void SLDestroy(SL* ps1);					//销毁顺序表void SLPushBack(SL* ps1, SLDataType x);		//尾插入
void SLPushFront(SL* ps1, SLDataType x);	//头插入
void SLPopBack(SL* ps1);					//尾删除
void SLPopFront(SL* ps1);					//头删除void SLInsert(SL* ps1, int pos, SLDataType x);	//任意位置的插入
void SLErase(SL* ps1, int pos);					//任意位置的删除int SLFind(SL* psl, SLDataType x);				//查找某个数据,找到返回下标,未找到返回-1

2.SeqList.c

#include"SeqList.h"void SLPrint(SL* ps1)								//打印数据
{assert(ps1);for (int i = 0; i < ps1->size; i++){printf("%d ", ps1->a[i]);}printf("\n");
}void SLInit(SL* ps1)							//初始化顺序表,全部为0
{assert(ps1);ps1->a = NULL;ps1->size = 0;ps1->capacity = 0;
}void SLDestroy(SL* ps1)							//销毁顺序表
{assert(ps1);if (ps1->a != NULL)							{free(ps1->a);ps1->a = NULL;ps1->size = 0;ps1->capacity = 0;}
}void SLCheckCapacity(SL* ps1)					//检查空间是否充足,若否,使空间充足,头插尾插都要用到
{assert(ps1);if (ps1->size == ps1->capacity){int NewCapacity = ps1->capacity == 0 ? 4 : ps1->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps1->a, sizeof(SLDataType) * NewCapacity);if (tmp == NULL){perror("realloc fail");return;}ps1->a = tmp;ps1->capacity = NewCapacity;}
}
void SLPushBack(SL* ps1, SLDataType x)			//尾插入
{assert(ps1);SLCheckCapacity(ps1);						//检查容量ps1->a[ps1->size] = x;ps1->size++;
}void SLPushFront(SL* ps1, SLDataType x)		//头插入
{assert(ps1);SLCheckCapacity(ps1);						//检查容量//往后挪动数据int end = ps1->size - 1;while (end >= 0){ps1->a[end + 1] = ps1->a[end];end--;}ps1->a[0] = x;ps1->size++;
}void SLPopBack(SL* ps1)							//尾删除
{assert(ps1);assert(ps1->size > 0);						//有效数据为0则不需要删ps1->size--;
}void SLPopFront(SL* ps1)						//头删除
{assert(ps1);assert(ps1->size > 0);						//有效数据为0则不需要删//往前挪动数据int begin = 1;while (begin < ps1->size){ps1->a[begin - 1] = ps1->a[begin];begin++;}ps1->size--;
}void SLInsert(SL* ps1, int pos, SLDataType x)	//任意位置的插入
{assert(ps1);assert(pos >= 0 && pos <= ps1->size);		//确保pos大小的有效性SLCheckCapacity(ps1);						//检查容量//往后挪动数据int end = ps1->size - 1;while (end > pos){ps1->a[end + 1] = ps1->a[end];end--;}ps1->a[pos] = x;ps1->size++;
}void SLErase(SL* ps1, int pos)					//任意位置的删除
{assert(ps1);assert(pos >= 0 && pos <= ps1->size);		//确保pos大小的有效性//往前挪动数据int begin = pos+1;while (begin < ps1->size){ps1->a[begin - 1] = ps1->a[begin];begin++;}ps1->size--;
}int SLFind(SL* ps1, SLDataType x)				//查找某个数据,找到返回下标,未找到返回-1
{assert(ps1);for (int i = 0; i < ps1->size; i++)			//直接遍历查找{if (ps1->a[i] == x){return i;}}return -1;
}

3.test.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"void menu()
{printf("********************************\n");printf("****1、尾插数据  2、尾删数据****\n");printf("****3、头插数据  4、头删数据****\n");printf("****5、打印数据  0、退出    ****\n");printf("********************************\n");
}int main()
{SL s;SLInit(&s);int option = 0;do{menu();printf("请输入你的选择:>");scanf("%d", &option);if (option == 1){printf("请依次输入你的要尾插数据个数和数据:>");int n = 0;scanf("%d", &n);for (int i = 0; i < n; i++){int x = 0;scanf("%d", &x);SLPushBack(&s, x);}}else if (option == 2){printf("请依次输入你的要尾删数据的个数:>");int n = 0;scanf("%d", &n);for (int i = 0; i < n; i++){SLPopBack(&s);}}else if (option == 3){printf("请依次输入你的要头插数据个数和数据:>");int n = 0;scanf("%d", &n);for (int i = 0; i < n; i++){int x = 0;scanf("%d", &x);SLPushFront(&s, x);}}else if (option == 4){printf("请依次输入你的要头删数据的个数:>");int n = 0;scanf("%d", &n);for (int i = 0; i < n; i++){SLPopFront(&s);}}else if (option == 5){SLPrint(&s);}else if (option == 0){break;}else{printf("无此选项,请重新输入\n");}} while (option != 0);SLDestroy(&s);return 0;
}

相关文章:

  • 多线程系列(十五) -常用并发工具类详解
  • 封装方法2
  • 计算机网络-网络安全(二)
  • 基于Spring Boot+ Vue的房屋租赁系统
  • LVS集群(Linux Virtual server)相关介绍及LVS的NAT模式部署
  • GPT的历史
  • 【设计模式】(二)设计模式六大设计原则
  • LeetCode 热题 100 | 图论(二)
  • 【粉丝福利】一本书讲透ChatGPT,实现从理论到实践的跨越!大模型技术工程师必读
  • 线性代数笔记11--矩阵空间、秩1矩阵
  • 数据库-第四/五章 数据库安全性和完整性【期末复习|考研复习】
  • [Vulnhub]靶场 Web Machine(N7)
  • 【CSP试题回顾】202209-2-何以包邮?
  • 各中间件性能、优缺点对比
  • Android使用OpenGL和FreeType绘制文字
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • Angular2开发踩坑系列-生产环境编译
  • Date型的使用
  • Electron入门介绍
  • Java到底能干嘛?
  • Java应用性能调优
  • Linux链接文件
  • MySQL用户中的%到底包不包括localhost?
  • ReactNative开发常用的三方模块
  • Spring框架之我见(三)——IOC、AOP
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 浮现式设计
  • 浅谈Golang中select的用法
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • 湖北分布式智能数据采集方法有哪些?
  • ​io --- 处理流的核心工具​
  • ​queue --- 一个同步的队列类​
  • ​卜东波研究员:高观点下的少儿计算思维
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • (10)STL算法之搜索(二) 二分查找
  • (arch)linux 转换文件编码格式
  • (windows2012共享文件夹和防火墙设置
  • (八)Flask之app.route装饰器函数的参数
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (接口自动化)Python3操作MySQL数据库
  • (利用IDEA+Maven)定制属于自己的jar包
  • (南京观海微电子)——I3C协议介绍
  • (七)c52学习之旅-中断
  • (一)Thymeleaf用法——Thymeleaf简介
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (转)C#调用WebService 基础
  • ***详解账号泄露:全球约1亿用户已泄露
  • . Flume面试题
  • .net mvc 获取url中controller和action
  • .net 重复调用webservice_Java RMI 远程调用详解,优劣势说明
  • .Net面试题4
  • :如何用SQL脚本保存存储过程返回的结果集
  • @Resource和@Autowired的区别