数据结构第二天

news2024/11/13 7:56:58
分文件编程实现

main.c

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

int main(int argc, char const *argv[])
{
    seqlist_p p = CreateEpSeqlist();
    InsertIntoSeqlist(p, 0, 10);
    InsertIntoSeqlist(p, 1, 20);
    InsertIntoSeqlist(p, 2, 30);
    ShowSeqlist(p);

    DeleteIntoSeqlist(p, 1);
    ShowSeqlist(p);

    ChangePostSeqList(p, 0, 99);
    ShowSeqlist(p);

    printf("search 99:%d\n", SearchDataSeqList(p, 99));
    return 0;
}

seqlist.c

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

// 创建一个空的顺序表
seqlist_p CreateEpSeqlist() //create创造 empty 空的 seqlist顺序表
{
    //动态申请一块顺序表结构体大小空间
    seqlist_p p = (seqlist_p)malloc(sizeof(seqlist_t));
    if (NULL == p)
    {
        perror("malloc lost"); //perror打印上一个函数报的错误信息
        return NULL;           //错误情况让函数返回空指针
    }
    //对结构体初始化
    p->last = -1;

    return p;
}

//判断顺序表是否为满,满返回1,未满返回0
int IsFullSeqlist(seqlist_p p) //full满
{
    return p->last + 1 == N;
}

//向顺序表的指定位置插入数据
int InsertIntoSeqlist(seqlist_p p, int post, int data)
{
    //容错判断:判满,对post做判断
    if (IsFullSeqlist(p) || post < 0 || post > p->last + 1)
    {
        printf("InsertIntoSeqlist err\n");
        return -1; //错误返回
    }
    //让最后一个元素到插入位置的元素向后移动一个单位
    for (int i = p->last; i >= post; i--)
        p->data[i + 1] = p->data[i];
    //插入数据
    p->data[post] = data;
    //让last加一
    p->last++;
    return 0;
}

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

//判断顺序表是否为空,为空返回1,不为空返回0
int IsEpSeqlist(seqlist_p p)
{
    return p->last == -1;
}

//删除顺序表中指定位置的数据,post为删除位置
int DeleteIntoSeqlist(seqlist_p p, int post)
{
    //容错判断:判空,对post判断
    if (IsEpSeqlist(p) || post < 0 || post > p->last)
    {
        printf("DeleteIntoSeqlist err\n");
        return -1;
    }

    //从删除位置元素的后一个元素到最后一个元素向前移动一个单位
    for (int i = post + 1; i <= p->last; i++)
        p->data[i - 1] = p->data[i];

    //让last减一,因为删除了一个元素有效元素少了一个
    p->last--;

    return 0;
}

// 修改指定位置上数据
int ChangePostSeqList(seqlist_p p, int post, int data)
{
    //容错判断:判空,对post判断
    if (IsEpSeqlist(p) || post < 0 || post > p->last)
    {
        printf("ChangePostSeqList err\n");
        return -1;
    }

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

    return 0;
}

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

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

seqlist.h

#ifndef __SEQLIST_H__
#define __SEQLIST_H__
#define N 10
typedef struct seqlist //封装顺序表结构体类型
{
    int data[N]; //用来存数据的数组
    int last;    //代表数组中最后一个有效元素的下标
} seqlist_t, *seqlist_p;

// 创建一个空的顺序表
seqlist_p CreateEpSeqlist(); //create创造 empty 空的 seqlist顺序表

//判断顺序表是否为满,满返回1,未满返回0
int IsFullSeqlist(seqlist_p p); //full满

//向顺序表的指定位置插入数据
int InsertIntoSeqlist(seqlist_p p, int post, int data);

//遍历顺序表sequence顺序list表
void ShowSeqlist(seqlist_p p);

//判断顺序表是否为空,为空返回1,不为空返回0
int IsEpSeqlist(seqlist_p p);

//删除顺序表中指定位置的数据,post为删除位置
int DeleteIntoSeqlist(seqlist_p p, int post);

// 修改指定位置上数据
int ChangePostSeqList(seqlist_p p, int post, int data);

// 查找指定数据出现的位置,返回下标,未找到返回-1
int SearchDataSeqList(seqlist_p p, int data);

// 清空顺序表(清空:访问不到,但是内存中还有。销毁:内存清空)
void ClearSeqList(seqlist_p p);

#endif

makefile

CC=gcc
GFLAGS=-c -g -Wall
OBJS=seqlist.o main.o

seqlist:$(OBJS)
	$(CC) $^ -o $@
%.o:%.c
	$(CC) $(GFLAGS) $< -o $@
.PHONY:clean
clean:
	$(RM) seqlist *.o

顺序表特点

  1. 顺序表内存空间连续
  2. 顺序表长度固定
  3. 插入删除操作效率低修改查找效率

3.2 链表 Linklist

链表又称单链表、链式存储结构,用于存储逻辑关系为“一对一”的数据。

和顺序表不同同,使用链表存储数据,不强制要求数据在内存中集中存储,各个元素可以分散存储在内存中。

所以在链表中,每个数据元素可以配有一个指针用于找到下一个元素即节点,这意味着,链表上的每个“元素”都长下图这个样子:

3.2.1 链表特性

逻辑结构线性结构

存储结构链式存储

特点内存连续需要通过指针链接大小不固定解决顺序表插入删除麻烦问题

操作增删改查

struct node
{
    int data;   //数据域:存储数据
    struct node *next;    //指针域:存储下一个节点的地址
};

3.2.2 单向链表

有头链表存在一个节点节点数据域无效指针域有效

无头链表每一个节点数据域指针域有效

遍历无头单向链表

#include <stdio.h>
#include <stdlib.h>
typedef char datatype;
typedef struct node
{
    datatype data;     //数据域用来存数据
    struct node *next; //指针域用来存下一个节点的地址
} node_t, *node_p;

// node_t A; //等同于 struct node A;
// node_p p; //等同于 struct node *p;

int main(int argc, char const *argv[])
{
    //1.定义4个节点
    node_t A = {'a', NULL};
    node_t B = {'b', NULL};
    node_t C = {'c', NULL};
    node_t D = {'d', NULL};

    //2.连接四个节点
    A.next = &B; //连接A和B
    B.next = &C;
    C.next = &D;

    //3.定义一个头指针指向第一个节点
    node_p p = &A;

    //4. 通过指针遍历无头单向链表
    while (p != NULL)
    {
        printf("%c ", p->data); //打印节点中的数据域 a b c d
        p = p->next;            //让p指向下一个节点
    }
    printf("\n");

    return 0;
}

遍历有头单向链表

#include <stdio.h>
#include <stdlib.h>
typedef char datatype;
typedef struct node
{
    datatype data;     //数据域用来存数据
    struct node *next; //指针域用来存下一个节点的地址
} node_t, *node_p;

// node_t A; //等同于 struct node A;
// node_p p; //等同于 struct node *p;

int main(int argc, char const *argv[])
{
    //1.定义4个节点
    node_t A = {'a', NULL};
    node_t B = {'b', NULL};
    node_t C = {'c', NULL};
    node_t D = {'d', NULL};

    //2.连接四个节点
    A.next = &B; //连接A和B
    B.next = &C;
    C.next = &D;

    //3. 定义头节点,数据域无效,指针域有效
    node_t H = {'\0', &A};

    //4. 定义一个头指针,指向头结点
    node_p p = &H;

#if 0
    p = p->next; //先跨越头节点,指向第一个数据域有效的节点A
    while (p != NULL)    //相当于遍历无头链表
    {
        printf("%c ", p->data);
        p = p->next;
    }
    printf("\n");
#else
    while (p->next != NULL)
    {
        p = p->next;
        printf("%c ", p->data);
    }
    printf("\n");
#endif

    return 0;
}

链表尾插法练习

写一个有头单向链表,用于保存输入的学生成绩,实现一输入学生成绩就创建一个新的节点,将成绩保存起来。再将该节点链接到链表的尾,直到输入-1结束。

要求:每个链表的节点由动态内存分配得到 , 也就是用malloc。

过程:

  1. malloc申请空间link_node_t大小作为头节点
  2. 将新节点放到链表尾部

#include <stdio.h>
#include <stdlib.h>
typedef int datatype;
typedef struct node
{
    datatype data;
    struct node *next;
} node_t, *node_p;

int main(int argc, char const *argv[])
{
    node_p pnew = NULL;
    node_p ptail = NULL;
    int score = -1;

    //1. 创建一个头结点,用头指针p指向头节点
    node_p p = (node_p)malloc(sizeof(node_t));
    if (NULL == p)
    {
        perror("p malloc err");
        return -1;
    }
    p->next = NULL; //初始化头节点
    ptail = p;      //让尾指针一开始指向头节点

    //2. 循环输入学生成绩直到-1结束,创建新节点保存学生成绩,尾插到链表。
    while (1)
    {
        scanf("%d", &score);
        if (score == -1)
            break;

        //(1) 创建新节点用来保存学生成绩
        pnew = (node_p)malloc(sizeof(node_t));
        if (NULL == pnew)
        {
            perror("pnew malloc err");
            return -1;
        }
        //(2) 初始化新节点,数据域保存学生成绩,指针域置空
        pnew->data = score;
        pnew->next = NULL;
        //(3) 将新节点连接到链表尾部,也就是ptail所指节点的指针域等于新节点地址
        ptail->next = pnew;
        //(4) 将尾指针移动到新节点,因为尾指针ptail要一直指向最后一个节点
        ptail = pnew;
    }

    //3. 遍历有头链表
    while (p->next != NULL)
    {
        p = p->next;
        printf("%d ", p->data);
    }
    printf("\n");

    return 0;
}

有头单向链表函数操作

插入指定位置节点:

删除指定节点

#include <stdio.h>
#include <stdlib.h>
typedef int datatype;
typedef struct node
{
    datatype data;
    struct node *next;
} node_t, *node_p;

//创建一个空的有头单向链表
node_p createEmptyLinkList() //create创建 Empty空的 LinkList单向链表
{
    //开辟链表节点大小空间
    node_p p = (node_p)malloc(sizeof(node_t));
    if (NULL == p)
    {
        perror("createEmptyLinkList");
        return NULL;
    }
    //初始化头节点
    p->next = NULL;

    return p;
}

//计算链表的长度。
int lengthLinkList(node_p p)
{
    int len = 0;
    while (p->next != NULL)
    {
        p = p->next;
        len++;
    }
    return len;
}

//向单向链表的指定位置插入数据
//p保存链表的头指针 post 插入的位置 data插入的数据
int insertIntoPostLinkList(node_p p, int post, datatype data)
{
    //容错判断
    if (post < 0 || post > lengthLinkList(p))
    {
        printf("insertIntoPostLinkList err\n");
        return -1;
    }

    node_p pnew = NULL; //记录新节点
    // 将指针 遍历到插入位置的前一个节点
    for (int i = 0; i < post; i++)
        p = p->next;
    // malloc创建一个新节点, 初始化新节点
    pnew = (node_p)malloc(sizeof(node_t));
    if (NULL == pnew)
    {
        perror("insertIntoPostLinkList err");
        return -1;
    }
    pnew->data = data;
    pnew->next = NULL;
    // 连接新节点到链表, 先连后面,再连前面。(不然前面断了后面就找不到了)
    pnew->next = p->next;
    p->next = pnew;

    return 0;
}

//遍历单向链表
void showLinkList(node_p p)
{
    while (p->next != NULL)
    {
        p = p->next;
        printf("%d ", p->data);
    }
    printf("\n");
}

int isEmptyLinkList(node_p p)
{
}

//删除单向链表中指定位置的数据 post 代表的是删除的位置
int deletePostLinkList(node_p p, int post)
{
}

int main(int argc, char const *argv[])
{
    node_p p = createEmptyLinkList();

    for (int i = 0; i < 5; i++)
        insertIntoPostLinkList(p, i, i);
    showLinkList(p);

    insertIntoPostLinkList(p, -1, 10); //insertIntoPostLinkList err 容错判断打印结果

    return 0;
}

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

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

相关文章

打卡第四十五天:不同的子序列、两个字符串的删除操作、编辑距离

一、不同的子序列&#xff08;困难&#xff09; 题目 文章 视频 这道题目如果不是子序列&#xff0c;而是要求连续序列的&#xff0c;那就可以考虑用KMP。相对于72. 编辑距离简单了不少&#xff0c;因为本题相当于只有删除操作&#xff0c;不用考虑替换增加之类的。但相对于…

Mapreduce_Distinct数据去重

MapReduce中数据去重 输入如下的数据&#xff0c;统计其中的地址信息&#xff0c;并对输出的地址信息进行去重 实现方法&#xff1a;Map阶段输出的信息K2为想要去重的内容&#xff0c;利用Reduce阶段的聚合特点&#xff0c;对K2进行聚合&#xff0c;去重。在两阶段中&#xff…

【数据结构篇】~顺序表

顺序表前言 想要学好数据结构的三大基本功&#xff1a;1.结构体2.指针3.动态内存开辟,这三样将是贯彻整个数据结构的工具。&#xff08;可以去这里了解这三大基本功&#xff09; 顺序表也是线性表的一种&#xff0c;那线性表又是什么呢&#xff1f; 线性表&#xff08;linear …

系列:水果甜度个人手持设备检测-无损检测常用技术和方式汇总

系列:水果甜度个人手持设备检测 -- 无损检测常用技术和方式汇总 概述 无损检测以不损坏被检测对象的使用性能为前提&#xff0c;以物理或化学方法为手段&#xff0c;借助相应的设备器材&#xff0c;按照规定的技术要求&#xff0c;对材料、零部件、结构件进行有效的检验和测…

软件测试第1章 软件测试是什么

目录​​​​​​​ 内容说明 一、软件测试与质量概览需要熟悉什么 二、如何理解质量保证 三、软件测试的误区-程序员和测试的关系 四、软件测试是什么&#xff1f; 五、软件测试的目的 六、软件测试与软件质量保证 七、软件测试的必要性 八、软件测试的基本概念分析 …

HarmonyOS Next 系列之列表下拉刷新和触底加载更多数据实现(十一)

系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现&#xff08;一&#xff09; HarmonyOS Next 系列之验证码输入组件实现&#xff08;二&#xff09; HarmonyOS Next 系列之底部标签栏TabBar实现&#xff08;三&#xff09; HarmonyOS Next 系列之HTTP请求封装和Token…

智碳云/高能耗企业 水-电-气-热-油-空压机等能源数据采集系统【源码】

智碳云/高能耗企业 水-电-气-热-油-空压机等能源数据采集系统【源码】 介绍基于SpringCloud的能源管理系统-能源管理平台源码-能源在线监测平台-双碳平台源码-SpringCloud全家桶-能管管理系统源码-能管系统软件架构

js 深入学习各种继承方法使用场景

前言 问题&#xff1a; JS 如何实现继承呢&#xff1f;主要有几种继承方式及分别适用于哪些场景呢&#xff1f; 我们学习高级语言&#xff0c;就必须学习面向对象&#xff0c;想要成为高手&#xff0c;就必须学习别人不会的&#xff0c;就比如JS中的继承&#xff0c;好多前端人…

ASP.NET在线交流论坛管理系统

ASP.NET在线交流论坛管理系统 说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a; 基于asp.net架构和sql server数据库 用户功能有个人信息管理 帖了信息管理 意见反馈信息管理 点赞管理 收藏管理 后台管理员可以进行用户管理 …

部署及使用seata

目录 1.下载seata1.7.0.zip 2.上传至云服务器&#xff0c;使用unar工具解压 3.配置application.yml&#xff0c;主要配置如下参数 4.为seata执行mysql脚本 5.配置nacos配置中心 *6.启动seata服务器 问题&#xff1a;“cause:can not register RM,err:can not connect to…

国外项目管理软件最佳实践:选型与应用

国内外主流的10款国外项目管理软件对比&#xff1a;PingCode、Worktile、Asana、Trello、Monday.com、ClickUp、Wrike、ProofHub、Zoho Projects、Hive。 在寻找适合的国外项目管理软件时&#xff0c;你是否感到不知从何选择&#xff1f;市场上琳琅满目的选项往往令人眼花缭乱&…

微软披露Office最新零日漏洞,可能导致数据泄露

近日&#xff0c;微软披露了 Office 中一个未修补的零日漏洞&#xff0c;如果被成功利用&#xff0c;可能导致敏感信息在未经授权的情况下泄露给恶意行为者。 该漏洞被追踪为 CVE-2024-38200&#xff08;CVSS 得分&#xff1a;7.5&#xff09;&#xff0c;被描述为一个欺骗漏洞…

关于xilinx的FFTIP的使用和仿真

工具&#xff1a;vivado2018.3&#xff0c;modelsim10.6d 场景&#xff1a;在进行数据进行频谱分析的时候&#xff0c;使用FPGA来完成FFT的计算可以加快数据的计算速度。 下面使用仿真完成DDS产生的数据的FFT以及IFFT。原始数据使用DDSIP产生&#xff0c;通过IP产生的波形数据…

旧手机NAS方案

这里写目录标题 1、参考2、alpine-term-v16.0-release.apk下载安装3、电脑端ssh连接3、安装docker3.1 网络配置3.2 配置APK源 1、参考 【Docker与Termux】闲置旧安卓手机上的NAS无缝部署方案 https://blog.csdn.net/AnRanGeSi/article/details/138717589 【Alpine Term】Andr…

线程与进程(5)

目录 信号量&#xff08;线程的同步 &#xff09; 信号量的分类&#xff1a; 框架&#xff1a; &#xff08;1&#xff09;信号量的定义(semaphore): &#xff08;2&#xff09;信号量的初始化&#xff1a; &#xff08;3&#xff09;信号量的PV 操作 &#xff08;4&#…

Ubuntu Linux安装Go语言

Golang是Google公司在2007年开始开发的一种静态强类型、编译型语言。Go语言被设计成一门简单、高效且可靠的编程语言&#xff0c;旨在解决大规模网络服务和分布式系统开发中的复杂性问题。Go语言结合了动态语言的开发速度和C/C等编译型语言的性能与安全性&#xff0c;提供了强大…

[DL]深度学习_针对图像恢复的高效扩散模型DiffIR

DiffIR: Efficient Diffusion Model for Image Restoration Abstract 扩散模型(DM)通过将图像合成过程建模为去噪网络的顺序应用&#xff0c;实现了SOTA的性能。然而&#xff0c;与图像合成不同的是&#xff0c;图像恢复(IR)对生成符合ground-truth的结果有很强的约束。因此&am…

家穷就去互联网

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330#rd 《网安面试指南》http://mp.weixin.qq.com/s?…

AI编程工具合集(附使用地址)

在AI编程工具领域&#xff0c;随着技术的飞速发展&#xff0c;越来越多的工具正在改变编程的方式。以下是目前排名前十的AI编程工具合集&#xff0c;提供了丰富的功能来提升开发效率&#xff0c;并在多个编程场景中帮助开发者解决问题。 1. GitHub Copilot • 是什么: GitHub C…

打靶笔记--medium_socnet

medium_socnet 靶机地址:https://www.vulnhub.com/entry/boredhackerblog-social-network,454/ 内容简介&#xff1a; 这是本系列的第04次打靶&#xff0c;我选择了一个中等难度的靶机。在这次打靶过程中&#xff0c;我们将使用到以下攻击手段&#xff1a; 主机发现 端口扫…