数据结构 day02

3. 线性表

3.1. 顺序表

3.1.3. 顺序表编程实现

 操作:增删改查

.h 文件 

#ifndef __SEQLIST_H__
#define __SEQLIST_H__
#define N 10
typedef struct seqlist
{
    int data[N];
    int last; //代表数组中最后一个有效元素的下标
} seqlist_t;

//1.创建一个空的顺序表
seqlist_t *CreateEpSeqlist();
//2.向顺序表的指定位置插入数据
int InsertIntoSeqlist(seqlist_t *p, int post, int data);
//3.遍历顺序表
void ShowSeqlist(seqlist_t *p);
//4.判断顺序表是否为满,满返回1,未满返回0
int IsFullSeqlist(seqlist_t *p);
//5.判断顺序表是否为空
int IsEpSeqlist(seqlist_t *p);
//6.删除顺序表中指定位置的数据
int DeleteIntoSeqlist(seqlist_t *p, int post);
//7.清空顺序表 (清空:访问不到,但是内存中还有;销毁:内存清空)
void ClearSeqList(seqlist_t *p);
//8.修改指定位置的数据,post为被修改数据位置,data为修改成的数据
int ChangePostSeqList(seqlist_t *p,int post,int data);
//9.查找指定数据出现位置,data为被查找的数据,返回下标,未找到返回-1
int SearchDataSeqList(seqlist_t *p,int data);
#endif

 1.创建一个空的顺序表

#include <stdio.h>
#include "seqlist.h"
#include <stdlib.h>

// 1.创建一个空的顺序表
seqlist_t *CreateEpSeqlist()
{
    // 1. 动态申请一块空间存放顺序表
    seqlist_t *p = NULL;
    p = (seqlist_t *)malloc(sizeof(seqlist_t));
    // 2. 检测空间是否开辟成功
    if (NULL == p)
    {
        perror("malloc last!");
        return NULL;
    }
    else
    {
        // 空间开辟成功,对last初始化
        printf("malloc success!\n");
        p->last = -1;
        return p;
    }
}

2.向顺序表的指定位置插入数据

#include <stdio.h>
#include "seqlist.h"

// 2.向顺序表的指定位置插入数据
int InsertIntoSeqlist(seqlist_t *p, int post, int data)
{
    // post容错,post范围,顺序表满了
    if (post > p->last + 1 || post < 0 || IsFullSeqlist(p))
    {
        perror("Insert Failed");
        return -1;
    }
    // 从post开始,到last,中间的元素向后移动一位
    for (int i = p->last; i >=post; i--)
    {
        p->data[i+1] = p->data[i];
    }
    p->data[post] = data;
    p->last++;
    return 0;
}

3.遍历顺序表

#include <stdio.h>
#include "seqlist.h"

//3.遍历顺序表
void ShowSeqlist(seqlist_t *p)
{
     for (int i = 0; i <= p->last; i++)
        printf("%-4d", p->data[i]);
    printf("\n");
}

4. 判断顺序表是否为满

#include <stdio.h>
#include "seqlist.h"

// 4.判断顺序表是否为满,满返回1,未满返回0
int IsFullSeqlist(seqlist_t *p)
{
    // if (p->last + 1 == N)
    //     return 1;
    // else
    //     return 0;
    return p->last +1 == N;
}

5. 判断顺序表是否为空

#include <stdio.h>
#include "seqlist.h"

// 5.判断顺序表是否为空
int IsEpSeqlist(seqlist_t *p)
{
    return p->last == -1;
}

 6. 删除顺序表中指定位置的数据

#include <stdio.h>
#include "seqlist.h"

// 6.删除顺序表中制定位置的数据
int DeleteIntoSeqlist(seqlist_t *p, int post)
{
    // 容错判断
    if (IsEpSeqlist(p) || post < 0 || post > p->last)
    {
        perror("Delete Failed!");
        return -1;
    }
    // 从下标为post+1 到last的元素向前移动一个单位
    for (int i = post + 1; i <= p->last; i++)
        p->data[i - 1] = p->data[i];
    p->last--;
    return 0;
}

7. 清空顺序表

#include <stdio.h>
#include "seqlist.h"

// 7.清空顺序表 (清空:访问不到,但是内存中还有;销毁:内存清空)
void ClearSeqList(seqlist_t *p)
{
    p->last = -1;
}

8. 修改指定位置的数据

#include <stdio.h>
#include "seqlist.h"

// 8.修改指定位置的数据,post为被修改数据位置,data为修改成的数据
int ChangePostSeqList(seqlist_t *p, int post, int data)
{
    // 容错判断
    if (post < 0 || post > p->last || IsEpSeqlist(p))
    {
        perror("Change Failed!");
        return -1;
    }

    // 修改指定位置的数据
    p->data[post] = data;

    return 0;
}

9. 查找指定数据出现位置

#include <stdio.h>
#include "seqlist.h"

// 9.查找制定数据出现位置,data为被查找的数据,返回下标,未找到返回-1
int SearchDataSeqList(seqlist_t *p, int data)
{
    for (int i = 0; i <= p->last; i++)
        if (p->data[i] == data)
            return i;
    return -1;
}

 main.c

#include <stdio.h>
#include "seqlist.h"
#include <stdlib.h>

int main(int argc, char const *argv[])
{
    // 创建空顺序表
    seqlist_t *p = NULL;
    p = CreateEpSeqlist();

    // 插入数据
    InsertIntoSeqlist(p, 0, 1);
    InsertIntoSeqlist(p, 1, 2);
    InsertIntoSeqlist(p, 2, 3);
    InsertIntoSeqlist(p, 3, 4);
    InsertIntoSeqlist(p, 4, 5);

    // 遍历顺序表
    ShowSeqlist(p);

    // 删除指定位置的数据
    DeleteIntoSeqlist(p, 2);
    ShowSeqlist(p);

    // 修改指定位置的数据
    ChangePostSeqList(p, 1, 999);
    ShowSeqlist(p);

    // 查找指定数据的位置
    printf("post = %d\n", SearchDataSeqList(p, 4));
    // 清空顺序表
    ClearSeqList(p);
    printf("%d\n",IsEpSeqlist(p));

    // 释放空间
    free(p);
    return 0;
}

3.2. 链表 Link

        链表又叫单链表,链式存储结构,用于存储逻辑关系为 “ 一对一 ” 的数据。每个元素配有指针域,存储和访问时通过指针域指向下一个节点的地址。

3.2.1. 链表的特性

逻辑结构:线性结构

存储结构:链式存储

特点:内存可以不连续

解决问题:长度固定,插入和删除操作繁琐

操作:增删改查

struct node_t
{
    int data;    // 数据域
    struct node_t next;    // 指针域,存放下一个节点的地址
};

3.2.2. 单向链表

1)有头单向链表

        第一位数据域无效,无法存储数据

2)无头单向链表

        第一位数据域有效

 单向链表的基本操作

 1. 定义结构体数组,作为链表的一个节点

typedef struct Link_list
{
    int data;
    struct Link_list *next;
}link_node_t, *link_list_t;

2. 定义链表节点

    link_node_t A = {'a', NULL};
    link_node_t B = {'b', NULL};
    link_node_t C = {'c', NULL};
    link_node_t D = {'d', NULL};

3. 定义头指针

        无头

link_list_t h = &A;

        有头            定义头节点,让头指针指向头节点

link_node_t S = {'\0', &A};
link_list_t h = &S;

4. 遍历链表

        无头

    while (h != NULL)
    {
        printf("%-4c", h->data);
        h = h->next;
    }
    printf("\n");

        有头

按照有头节点方式遍历

while (h->next != NULL)
{
    h = h->next;
    printf("%-4c", h->data);
}

按照无头节点方式遍历

h = h->next;
while(h != NULL)
{
    printf("%-4c", h->data);
    h = h->next;
}
 有头单向链表的函数操作

头文件 .h 

#ifndef __LINKLIST_H__
#define __LINKLIST_H__

typedef int datatype;
typedef struct node_t
{
    datatype data;       // 数据域
    struct node_t *next; // 指针域,指向自身结构体的指针
} link_node_t, *link_list_t;

// 1.创建一个空的有头单向链表
link_list_t createEmptyLinkList();
// 2.链表指定位置插入数据
int insertIntoPostLinkList(link_node_t *p, int post, datatype data);
// 3.计算链表的长度。
int lengthLinkList(link_node_t *p);
// 4.遍历链表
void showLinkList(link_node_t *p);
// 5.链表指定位置删除数据
int deletePostLinkList(link_node_t *p, int post);
// 6.判断链表是否为空
int isEmptyLinkList(link_node_t *p);
// 7.清空单向链表
void clearLinkList(link_node_t *p);
// 8.修改指定位置的数据 post 被修改的位置 data修改成的数据
int changePostLinkList(link_node_t *p, int post, datatype data);
// 9.查找指定数据出现的位置 data被查找的数据 //search 查找
int searchDataLinkList(link_node_t *p, datatype data);
// 10.删除单向链表中出现的指定数据,data代表将单向链表中出现的所有data数据删除
int deleteDataLinkList(link_node_t *p, datatype data);
// 11.转置链表
// 解题思想:
//(1) 将头节点与当前链表断开,断开前保存下头节点的下一个节点,
//    保证后面链表能找得到,定义一个q保存头节点的下一个节点,
//    断开后前面相当于一个空的链表,后面是一个无头的单向链表
//(2) 遍历无头链表的所有节点,
//    将每一个节点当做新节点插入空链表头节点的下一个节点
//    (每次插入的头节点的下一个节点位置)
void reverseLinkList(link_node_t *p);
#endif

1. 创建一个空的有头单项链表

link_node_t *createEmptyLinkList()
{
    link_list_t h = (link_list_t)malloc(sizeof(link_node_t));
    
    // 容错判断
    if (h == NULL)
    {
        perror("空间开辟失败\n");
        return NULL;
    }

    // 头节点初始化
    h->next=NULL;
    
    return h;
}

2. 链表指定位置插入节点

int insertIntoPostLinkList(link_node_t *p, int post, datatype data)
{
    link_list_t pnew = NULL; // 指向新节点

    // 容错判断
    if(post > lengthLinkList(p) || post < 0)
    {
        perror("post 范围错误");
        return -1;
    }

    // 创建新节点并初始化
    pnew = (link_list_t)malloc(sizeof(link_node_t));
    pnew->data = data;
    pnew ->next = NULL;

    // 移动头指针,指向插入位置的前一个节点
    for(int i = 0; i < post; i++)
    {
        p = p->next;
    }

    // 链接插入节点
    pnew->next = p->next;
    p ->next = pnew;

    return 0;
}

3. 计算链表长度

int lengthLinkList(link_node_t *p)
{
    int len = 0;
    while (p->next != NULL)
    {
        p = p->next;
        len++;
    }
    return len;
}

4. 遍历链表

void showLinkList(link_node_t *p)
{
    while (p->next != NULL)
    {
        p = p->next;
        printf("%-4d", p->data);
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32的HAL库开发---ADC

一、ADC简介 1、ADC&#xff0c;全称&#xff1a;Analog-to-Digital Converter&#xff0c;指模拟/数字转换器 把一些传感器的物理量转换成电压&#xff0c;使用ADC采集电压&#xff0c;然后转换成数字量&#xff0c;经过单片机处理&#xff0c;进行控制和显示。 2、常见的AD…

25/2/16 <算法笔记> DirectPose

DirectPose 是一种直接从图像中预测物体的 6DoF&#xff08;位姿&#xff1a;6 Degrees of Freedom&#xff09;姿态 的方法&#xff0c;包括平移和平面旋转。它在目标检测、机器人视觉、增强现实&#xff08;AR&#xff09;和自动驾驶等领域中具有广泛应用。相比于传统的位姿估…

企业级API集成方案:基于阿里云函数计算调用DeepSeek全解析

解决方案链接&#xff1a;https://www.aliyun.com/solution/tech-solution/deepseek-r1-for-platforms?utm_contentg_1000401616 何为DeepSeek R1 DeepSeek R1模型有诸多技术优势。高效架构设计使其能更高效提取特征&#xff0c;减少冗余计算&#xff0c;提升数据处理速度、…

137,【4】 buuctf web [SCTF2019]Flag Shop

进入靶场 都点击看看 发现点击work会增加&#xffe5; 但肯定不能一直点下去 抓包看看 这看起来是一个 JWT&#xff08;JSON Web Token&#xff09;字符串。JWT 通常由三部分组成&#xff0c;通过点&#xff08;.&#xff09;分隔&#xff0c;分别是头部&#xff08;Header&…

ThinkPHP8视图赋值与渲染

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 在控制器操作中&#xff0c;使用view函数可以传入视图…

渗透利器:YAKIT 工具-基础实战教程.

YAKIT 工具-基础实战教程. YAKIT&#xff08;Yak Integrated Toolkit&#xff09;是一款基于Yak语言开发的集成化网络安全单兵工具&#xff0c;旨在覆盖渗透测试全流程&#xff0c;提供从信息收集、漏洞扫描到攻击实施的自动化支持。其核心目标是通过GUI界面降低Yak语言的使用…

Fiori APP配置中的Semantic object 小bug

在配置自开发程序的Fiori Tile时&#xff0c;需要填入Semantic Object。正常来说&#xff0c;是需要通过事务代码/N/UI2/SEMOBJ来提前新建的。 但是在S4 2022中&#xff0c;似乎存在一个bug&#xff0c;即无需新建也能输入自定义的Semantic Object。 如下&#xff0c;当我们任…

shell——分支语句

文章目录 基本语法常用判断条件(1)两个整数之间比较&#xff08;2&#xff09;按照文件权限进行判断&#xff08;3&#xff09;按照文件类型进行判断&#xff08;4&#xff09;多条件判断&#xff08;&& 表示前一条命令执行成功时&#xff0c;才执行后一条命令&#xf…

Ubuntu 连接 air pods

&#xff11;&#xff0e; sudo vim /etc/bluetooth/main.conf , 修改蓝牙模式为blder &#xff12;&#xff0e;sudo /etc/init.d/bluetooth restart, 重启蓝牙&#xff0c;即可连接成功

机器学习:k近邻

所有代码和文档均在golitter/Decoding-ML-Top10: 使用 Python 优雅地实现机器学习十大经典算法。 (github.com)&#xff0c;欢迎查看。 K 邻近算法&#xff08;K-Nearest Neighbors&#xff0c;简称 KNN&#xff09;是一种经典的机器学习算法&#xff0c;主要用于分类和回归任务…

低空经济:开启未来空中生活的全新蓝海

引言 随着科技的进步&#xff0c;我们不再仅仅依赖地面交通和传统物流。你是否曾幻想过&#xff0c;未来的某一天&#xff0c;快递、外卖可以像魔法一样直接从空中送到你手中&#xff1f;或者&#xff0c;你能乘坐小型飞行器&#xff0c;快速穿梭于城市之间&#xff0c;告别拥堵…

DeepSeek核心算法解析:如何打造比肩ChatGPT的国产大模型

注&#xff1a;此文章内容均节选自充电了么创始人&#xff0c;CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》&#xff08;人工智能科学与技术丛书&#xff09;【陈敬雷编著】【清华大学出版社】 文章目录 DeepSeek大模型技术系列一DeepSeek核心算法解析&#xff1a;如何…

苍穹外卖day4 redis相关简单知识 店铺营业状态设置

内存存储 键值对 key-value 一般用于处理突发性大量请求数据操作&#xff08;暂时浅显理解&#xff09; 读写速度极快&#xff0c;常用于缓存数据&#xff0c;减少对数据库的访问压力&#xff0c;提高系统性能。例如&#xff0c;可以缓存用户会话、商品信息、页面数据 设置默…

API 接口自动化

HTTP协议 - 白月黑羽 HTTP协议简介 如果客户端是浏览器&#xff0c;如何在chrome浏览器中查看 请求和响应的HTTP消息&#xff1f;按f12-》network 清除当前信息 响应的消息体在Response里看 点preview&#xff0c;可以看响应的消息体展开的格式 HTTP请求消息 请求头 reques…

Oracle序列(基础操作)

序列概念 序列是用于生成唯一、连续序号的对象。 序列可以是升序的&#xff0c;也可以是降序的。 使用CREATE SEQUENCE语句创建序列。 start with 1 指定第一个序号从1开始 increment by 1 指定序号之间的间隔为1 increment by -1 降序1000 999 998这样 maxvalue 2000 表…

【pytorch】weight_norm和spectral_norm

apply_parametrization_norm 和spectral_norm是 PyTorch 中用于对模型参数进行规范化的方法&#xff0c;但它们在实现和使用上有显著的区别。以下是它们的主要区别和对比&#xff1a; 实现方式 weight_norm&#xff1a; weight_norm 是一种参数重参数化技术&#xff0c;将权…

unity学习44:学习Animator 的一个动作捕捉网站,实测好用

目录 1 动作捕捉网站 2 注册和下载 3 比如首页的内容&#xff0c;可以直接下载为fbx模型文件 4 上传并修改 5 在 unity里使用 5.1 下载的fbx文件直接拖入到unity 5.2 动画修改 5.3 游戏里播放 1 动作捕捉网站 一个动作捕捉网站 AI神器集合网站 千面视频动捕 | AI神器…

云原生(五十五) | ECS中自建数据库迁移到RDS

文章目录 ECS中自建数据库迁移到RDS 一、场景说明 二、ECS中自建数据库迁移到RDS实现步骤 三、 创建wordpress数据库 四、登录ECS导出wordpress数据库 五、返回RDS数据库管理控制台 六、开启外网地址并设置白名单 七、获取RDS外网访问地址 八、重新设置wordpress的wp-…

【NLP 22、语言模型 language model】

有时候我也想听听&#xff0c;我在你心里&#xff0c;是什么样子 —— 25.1.12 一、什么是语言模型 语言是灵活的&#xff0c;也是有规律的 了解一门语言的人可以判断一句话是否“合理” 通俗来讲&#xff0c;语言模型用来评价一句话(句子可以看作是字的组合)是否“合理”或…

qt + opengl 给立方体增加阴影

在前几篇文章里面学会了通过opengl实现一个立方体&#xff0c;那么这篇我们来学习光照。 风氏光照模型的主要结构由3个分量组成&#xff1a;环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看起来的样子&#xff1a; 1 环境光照(Ambient …