【数据结构】线性结构 之 顺序表

news2024/10/7 6:42:58

🌱博客主页:大寄一场.

🌱系列专栏:数据结构与算法

😘博客制作不易欢迎各位👍点赞+⭐收藏+➕关注
75486fdc2eee4efba3dfc46f574e64ef.gif#pic_center

目录

前言

顺序表概念及结构

静态代码实现:

动态代码实现:

SeqList.h文件

SeqList.c文件

test.c文件


前言

本章节博主将会带领大家了解数据结构的线性结构的顺序表

提到线性结构那么不得不先说说说线性表:

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

线性表:逻辑结构, 就是对外暴露数据之间的关系,不关心底层如何实现,数据结构的逻辑结构大分类就是线性结构和非线性结构而顺序表、链表都是一种线性表。

顺序表、链表:物理结构,他是实现一个结构实际物理地址上的结构。比如顺序表就是用数组实现。而链表用指针完成主要工作。不同的结构在不同的场景有不同的区别。


 

顺序表概念及结构

顺序表是用一段 物理地址连续 的存储单元依次存储数据元素的线性结构,一般情况下采用 。在数组上完成数据的增删查改。
顺序表一般可以分为:
1. 静态顺序表:使用定长数组存储元素

 

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

 

静态代码实现:


/*第一部分内容:头文件包含和常量定义*/
#include <stdio.h>
#include <stdlib.h> 
#define OK 1
#define ERROR 0
#define MAXSIZE 100
/*第二部分内容:先用typedef确定元素类型,*/
typedef int ElemType;
typedef struct
{
	ElemType elem[MAXSIZE];
	int last;
}SeqList;
/*第三部分,自定义函数*/
int  Locate(SeqList L, ElemType e)
{
	int i = 0;
	/*i为扫描计数器,初值为0,即从第一个元素开始比较*/
	while ((i <= L.last) && (L.elem[i] != e))		/*顺序扫描表,直到找到值为key的元素, 或扫描到表尾而没找到*/
		i++;
	if (i <= L.last)
		return(i + 1);  /*若找到值为e的元素,则返回其序号*/
	else
		return(-1);  /*若没找到,则返回空序号*/
}
int ListInsert(SeqList* L, int i, ElemType e)
{
	int k;
	if ((i < 1) || (i > L->last + 2)) /*首先判断插入位置是否合法*/
	{
		printf("插入位置i值不合法");
		return(ERROR);
	}
	if (L->last >= MAXSIZE - 1)
	{
		printf("表已满无法插入");
		return(ERROR);
	}
	for (k = L->last; k >= i - 1; k--)   /*为插入元素而移动位置*/
		L->elem[k + 1] = L->elem[k];
	L->elem[i - 1] = e;   /*在C语言数组中,第i个元素的下标为i-1*/
	L->last++;
	return(OK);
}
int  DelList(SeqList* L, int i, ElemType* e)
/*在顺序表L中删除第i个数据元素,并用指针参数e返回其值。i的合法取值为1≤i≤L.last+1 */
{
	int k;
	if ((i < 1) || (i > L->last + 1))
	{
		printf("删除位置不合法!");
		return(ERROR);
	}
	*e = L->elem[i - 1];  /* 将删除的元素存放到e所指向的变量中*/
	for (k = i; k <= L->last; k++)
		L->elem[k - 1] = L->elem[k];  /*将后面的元素依次前移*/
	L->last--;
	return(OK);
}
void Print(SeqList* L)
{
	printf("表中的元素为:\n");
	for (int i = 0; i < L->last; i++)
		printf("%4d", L->elem[i]);
	printf("\n");
}
void InitList(SeqList* L)
{

	for (int i = 0; i < MAXSIZE; i++)
		L->elem[i] = 0;
	L->last = 0;           //空表
}

void menu()
{
	printf("=============================================================== \n");
	printf("			           顺序表基本操作                           \n");
	printf("--------------------------------------------------------------- \n");
	printf("                       1.输出顺序表\n");
	printf("                       2.查找数据元素\n");
	printf("                       3.插入数据元素\n");
	printf("                       4.删除第i个元素\n");
	printf("                       0.退出\n");
	printf("================================================================= \n");

}
/*第四部分,main函数*/
void main()
{
	SeqList H;
	int a;
	int m, i, e, select;
	InitList(&H);            // 初始化表格 
	ListInsert(&H, 1, 5);      //将 5,3,4,6,6,6,9依次插入表格 
	ListInsert(&H, 2, 3);
	ListInsert(&H, 3, 4);
	ListInsert(&H, 4, 6);
	ListInsert(&H, 5, 6);
	ListInsert(&H, 6, 6);
	ListInsert(&H, 7, 9);
	menu();
	while (1)
	{
		SeqList L;
		printf("\n请输入选项:");
		scanf("%d", &select);
		switch (select)
		{
		case 0:
			exit(0);
			break;
		case 1:
			Print(&H);
			break;
		case 2:
		{
			printf("请输入你要查找的某个元素");
			scanf("%d", &m);

			a = Locate(H, m);
			if (a == -1)
				printf("没找到!");
			else
				printf("找到了,它的元素下标为%d", a);
			break;
		}
		case 3:
			printf("请输入插入位置i和插入的数据元素e: ");
			scanf("%d %d", &i, &e);
			ListInsert(&H, i, e);
			Print(&H);
			break;
		case 4:
			printf("请输入删除位置i: ");
			scanf("%d", &i);
			DelList(&H, i, &e);
			Print(&H);
			break;
		}
	}
}

动态代码实现:

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

SeqList.h文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#define INIT_CAPACITY 4
typedef int SLDataType;
#define N 10

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

void SLInit(SL* ps);//创建
void SLDestory(SL* s);//销毁
void SLExpend(SL* s);//增容
void Push_Back(SL* ps, SLDataType x);//尾插
void Pop_Back(SL* ps);//尾删
void SLPrint(SL* ps);//打印
void Push_Front(SL* ps, SLDataType x);//头插
void Pop_Front(SL* ps);//头删

SeqList.c文件

#include"SeqList.h"

void SeqInit(SL* ps)
{
	ps->a= (SLDataType*)malloc(sizeof(SLDataType) * INIT_CAPACITY);
	if (ps->a == NULL)
	{
		perror("malloc fail");
	}
	ps->size = 0;
	ps->capacity= INIT_CAPACITY;
}

void SLDestroy(SL* ps)
{
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->size = 0;
}

void SLExpend(SL* s)
{
	SLDataType* tmp = (SLDataType*)realloc(s->a, sizeof(SLDataType)*s->capacity * 2);
	if (tmp == NULL)
	{
		perror("realloc fail");
		return;
	}
	s->a = tmp;
	s->capacity *= 2;
	printf("扩容成功\n");
}

void Push_Back(SL* ps, SLDataType x)
{
	if (ps->capacity == ps->size)
	{
		SLExpend(ps);
	}
	ps->a[ps->size++] = x;
}

void SLPrint(SL* ps)
{
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	puts("");
}

void Pop_Back(SL* ps)
{
	if (ps->size == 0)
	{
		return;
	}
	ps->size--;
}

void Push_Front(SL* ps, SLDataType x)
{
	if (ps->capacity == ps->size)
	{
		SLExpend(ps);
	}
	int end = ps->size;
	while (end)
	{
		ps->a[end] = ps->a[end - 1];
		end--;
	}
	ps->a[0] = x;
	ps->size++;
}

void Pop_Front(SL* ps)
{
	int pos = 1;
	while (pos < ps->size)
	{
		ps->a[pos - 1] = ps->a[pos];
		pos++;
	}
	ps->size--;
}

test.c文件

#include"SeqList.h"

int main(void)
{
	SL s;
	SeqInit(&s);
	Push_Back(&s, 1);
	Push_Back(&s, 2);
	Push_Back(&s, 8);
	Push_Back(&s, 8);
	Push_Front(&s, 100);
	Push_Front(&s, 99);
	Push_Front(&s, 98);
	SLPrint(&s);
	Pop_Front(&s);
	Pop_Front(&s);
	SLPrint(&s);
	printf("%d %d", s.capacity, s.size);
	return 0;
}

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/552257.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用VitePress和Github搭建个人博客网站,可以自动构建和发布

之前我们写过一篇关于如何自动构建和发布个人博客的文章&#xff0c;当时是使用VuePress和GitLab。GitLab持续集成部署CI/CD初探&#xff1a;如何自动构建和发布个人前端博客 现在换了Vue3和Vite&#xff0c;使用VitePress在Github上又搭建了一个博客。博客地址&#xff1a; …

博弈Ai官网ChatGPT能力真实测评

链接&#xff1a;https://chat.bo-e.com/&#xff08;基于ChatGPT4和3.5研发的智能聊天机器人国产镜像&#xff09; 一&#xff0c;博弈Ai的UI设计样式 1、博弈Ai&#xff08;ChatGPT&#xff09;白天模式 2、博弈Ai&#xff08;ChatGPT&#xff09;黑天模式 3、博弈Ai&#x…

五、c++学习(加餐1:汇编基础学习)

经过前面几节课的学习&#xff0c;我们在一些地方都会使用汇编来分析&#xff0c;我们学习汇编&#xff0c;只是学习一些基础&#xff0c;主要是在我们需要深入分析语法的时候&#xff0c;使用汇编分析&#xff0c;这样会让我们更熟悉c编译器和语法。 从这节课开始&#xff0c…

【003hive基础】hive的数据类型

文章目录 一.数据类型1. 基础数据类型2. 复杂数据类型 二. 显式转换与隐式转换三. hive的读时模式 一.数据类型 1. 基础数据类型 2. 复杂数据类型 array: 有序相同数据类型的集合。 arrays(1, 2)map : key必须是基本数据类型&#xff0c;value不限。 map(‘a’, 1, ‘b’, 2)s…

线性回归、正规方程和梯度下降法

一、线性回归简介 1.定义与公式 线性回归是利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。 特点&#xff1a;只有一个自变量的情况称为单变量回归&#xff0c;多余一个自变量情况的叫做多元回归 通用公式&#xff1a; y …

javascript基础三:谈谈 JavaScript 中的类型转换机制

一、概述 JS中有六种简单数据类型&#xff1a;undefined、null、boolean、string、number、symbol&#xff0c;以及引用类型&#xff1a;object 但是我们在声明的时候只有一种数据类型&#xff0c;只有到运行期间才会确定当前类型 let name y?allen:1上面代码中&#xff0c…

2023年NOC大赛创客智慧编程赛项Python 复赛模拟题(二)

题目来自:NOC 大赛创客智慧编程赛项Python 复赛模拟题(二) NOC大赛创客智慧编程赛项Python 复赛模拟题(二) 第一题: 编写一个成绩评价系统,当输入语文、数学和英语三门课程成绩时,输出三门课程总成绩及其等级。 (1)程序提示用户输入三个数字,数字分别表示语文、数学、…

ChatGPT-4 镜像网站推荐

文章目录 1. TomChat2. Ai Doge3. 二狗问答4. 小莓用AI5. Ora6. 未知名字7. VIVI-AI8. ATALK9. ChatGPT Web10 AIchatOS 什么是ChatGPT? ChatGPT&#xff0c;全称&#xff1a;聊天生成预训练转换器&#xff08;英语&#xff1a;Chat Generative Pre-trained Transformer&#…

抓取领域相关论文及摘要

抓取规划问题是指确定物体与手指间的一系列接触位置&#xff0c;使得手指能抵抗任意外力且灵活操作物体的能力。传统的基于分析的抓取规划需要根据已知的被抓物体模型根据力闭合的条件判断抓取的好&#xff0c;这种方法只适合对已知的物体进行抓取。 然而日常生活中有很多相似…

MyBatis 中的动态 SQL 是什么?它的作用是什么?

MyBatis 中的动态 SQL 是一种允许在 SQL 语句中根据不同的条件动态生成 SQL 语句的技术。它可以根据不同的条件生成不同的 SQL 语句&#xff0c;从而达到灵活构建 SQL 语句的目的。动态 SQL 可以减少代码的重复度&#xff0c;提高代码的可维护性和可读性。 动态 SQL 使用 OGNL…

如何在MyBatis中处理复杂结果集映射关系

文章目录 前言一、 准备工作二、resultMap处理字段和属性的映射关系三、多对一映射0、级联方式处理映射关系1、使用association处理映射关系2、分步查询解决多对一关系(1) 查询员工信息(2) 根据员工所对应的部门id查询部门信息延迟加载 三、一对多的关系处理0、使用collection来…

6.1 SpringBoot解决跨域,我推荐这2种超实用方案

文章目录 前言一、验证跨域1. 添加index.html2. 增加/auth/test/cors接口3. IDEA启动多个springboot项目4. 验证POST方法5. 验证OPTIONS方法 二、拦截器方案定义拦截器注册拦截器&#xff0c;并指定拦截规则 三、过滤器方案总结最后 前言 在文章【2-2】中&#xff0c;我和你介…

获取企业服务超市企业信息

地址&#xff1a; 服务机构-苏州工业园区企业服务超市 import os from datetime import datetime from urllib import request import pandas as pd import re import requests from lxml import etree from bs4 import BeautifulSoup import csv import codecs# 20230521 根据…

learn_C_deep_13 (深刻理解宏定义)

目录 宏定义 数值宏常量 字符串宏常量 用定义充当注释符号宏 用 define 宏定义表达式 宏定义中的空格 宏定义 数值宏常量 在C语言中&#xff0c;宏定义可以用于定义数值宏常量。数值宏常量是一个值&#xff0c;在宏定义中用一个常量名称来表示&#xff0c;该值在后续的代…

计算机视觉的应用5-利用PCA降维方法实现简易人脸识别模型

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用5-利用PCA降维方法实现简易人脸识别模型&#xff0c;本文将介绍如何使用主成分分析&#xff08;PCA&#xff09;实现简易的人脸识别模型。首先&#xff0c;我们将简要介绍PCA的原理及其在人脸识别中…

26 KVM热迁移虚拟机

文章目录 26 KVM热迁移虚拟机26.1 总体介绍26.1.1 概述26.1.2 应用场景26.1.3 注意事项和约束限制 26.2 热迁移操作26.2.1 前提条件26.2.2 热迁移脏页率预测&#xff08;可选&#xff09;26.2.3 设置热迁移参数&#xff08;可选&#xff09;26.2.4 热迁移操作&#xff08;共享存…

Linux:文本三剑客之awk

Linux&#xff1a;文本三剑客之awk 一、awk编辑器1.1 awk概述1.2 awk工作原理1.3 awk与sed的区别 二、awk的应用2.1 命令格式2.2 awk常见的内建变量&#xff08;可直接用&#xff09; 三、awk使用3.1 按行输出文本3.2 按字段输出文本3.3 通过管道、双引号调用 Shell 命令 一、a…

【模电实验】日光灯电路及功率因数的提高

实验4 日光灯电路及功率因数的提高 一、实验目的 1&#xff0e;理解提高功率因数的意义并掌握其方法。 2&#xff0e;掌握日光灯电路的联接。 二、原理说明 日光灯电路结构及工作原理 日光灯电路如图4-1所示&#xff0c;日光灯由灯管、镇流器和启辉器三部分组成。 &…

复制带随机指针的链表

&#x1f495;“如果你关注自己已经拥有的&#xff0c;你就会拥有更多。如果你只关注自己没有得到的&#xff0c;你永远不会满足。” - 奥普拉温弗瑞&#x1f495; &#x1f43c;作者&#xff1a;不能再留遗憾了&#x1f43c; &#x1f386;专栏&#xff1a;Java学习&#x1f3…

11. Redis集群(cluster)

11. Redis集群cluster 是什么&#xff1f;能干嘛&#xff1f;集群算法-分片-槽位slot官网出处redis集群的槽位slotredis集群的分片他两的优势slot槽位映射&#xff0c;一般业界有3种解决方案哈希取余分区—致性哈希算法分区3大步骤算法构建一致性哈希环redis服务器IP节点映射k…