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

数据结构(概念及链表)

1.数据结构的概念

        程序由数据结构和算法构成,它是描述数据存储和操作的结构,是操作数据对象的方法。

        1.1.衡量代码的质量和效率

                1)时间复杂度:数据量的增长与程序运行时间的增长所呈现的比例函数关系,称为时间复杂度。以下是常见的时间复杂度:

O(1) - 常数时间复杂度:

def constant_time(n):return n * n  # 无论n多大,操作次数固定

O(n) - 线性时间复杂度:

def linear_time(n):total = 0for i in range(n):  # 循环次数与n成正比total += ireturn total

O(log n) - 对数时间复杂度:

def logarithmic_time(n):i = 1while i < n:i *= 2  # 每次循环i翻倍return i

O(n log n) - 线性对数时间复杂度

def linearithmic_time(n):result = 0for i in range(n):  # 外层循环O(n)j = 1while j < n:    # 内层循环O(log n)j *= 2result += 1return result

O(n²) - 平方时间复杂度

def quadratic_time(n):count = 0for i in range(n):      # 外层循环O(n)for j in range(n):  # 内层循环O(n)count += 1return count

O(n³) - 立方时间复杂度

def cubic_time(n):count = 0for i in range(n):          # 三层嵌套循环for j in range(n):for k in range(n):count += 1return count

O(2ⁿ) - 指数时间复杂度

def exponential_time(n):if n <= 1:return nreturn exponential_time(n-1) + exponential_time(n-2)  # 斐波那契数列的递归实现

O(n!) - 阶乘时间复杂度

def factorial_time(n):if n == 0:return 1count = 0for i in range(n):  # 每次递归调用n次count += factorial_time(n-1)return count

                                              (各个复杂度的运行时间与数据量的变换)

        2)空间复杂度:数据的增长与程序占据空间的增长所呈现的比例函数关系,称为空间复杂度。

1.2.数据结构

        1.2.1逻辑结构

                包括:线性结构(表,一对一),非线性结构(树,一对多),(图,多对多)

        1.2.2存储结构

                包括:顺序存储,链式存储,散列存储,索引存储

        1.2.3数据结构

                包括:顺序表,链式表,顺序栈,链式栈,顺序队列,链式队列,二叉树,邻接表,邻接矩阵

2.链表

        2.1链表的概念

                顺序表(数组)特点:存储空间连续,访问元素方便,无法利用小的空间,必须连续的大空间,顺序表元素必须为有限的(不存在无限连续的空间) 插入和删除效率低。

               链表特点:存储空间不需要连续,可以利用一些小的存储空间,但访问元素不方便,链表元素可以没有上限,插入和删除效率高。

        2.2链表的分类

                单向链表:只能通过链表节点找到后一个节点,访问链表元素的方向是单向的

                               

                双向链表:能够通过链表节点找到前一个节点和后一个节点

                                

                循环链表:能够通过第一节点快速找到最后一个节点,能够通过最后一个节点快速找到第一个节点

                ​​​​​​​        ​​​​​​​        

                内核链表:Linux内核所采用的一种通用的链表结构

3.单向链表

        无头链表:频繁传递二级指针,容易出错。

        有头链表:只需传递一级指针即可完成各种操作。

        3.1定义链表节点类型

//链表存放数据的类型:
typedef int datatype;
//链表节点的类型:
typedef struct node{datatype data;struct node *pnext;
}linknode;

        3.2创立空白节点(头节点)

                创建一个空的链表节点,data不需要赋值(最好赋值),空白节点不存放数据,主要为了保证链表操作的便利性,pnext必须赋值为NULL,表示该节点为最后一个节点,将节点地址返回。

#include"linklist.h"
#include<stdio.h>
#include<stdlib.h>
//创建一个空链表
linknode *create_empty_linklist(void)
{linknode *ptmpnode = NULL;ptmpnode = malloc(sizeof(linknode));if(NULL == ptmpnode){perror("file to malloc");return NULL;}ptmpnode->pnext = NULL;return ptmpnode;
}

        3.3链表的头插法

                申请新的节点空间 ,将存放的数据放入新申请的数据空间中,将新申请节点的pnext赋值为空白节点的pnext,将空白节点pnext赋值为新申请节点

//插入一个节点
int insert_head_linklist(linknode*phead,datatype tmpdata)
{linknode*ptmpnode = NULL;ptmpnode = malloc(sizeof(linknode));if (NULL == ptmpnode){perror("fail to malloc");return -1;}//存放数据ptmpnode->data = tmpdata;//存放下一个节点的地址ptmpnode->pnext = phead->pnext;//更新空白节点的下一个地址phead->pnext = ptmpnode;return 0;
}

        3.4链表的遍历

                方法一:适用于遍历所有链表节点

void show_linklist(linknode *phead){linknode *ptmpnode = NULL;ptmpnode = phead->pnext;while (ptmpnode != NULL)//判断下一个节点是不是空{printf("%d ", ptmpnode->data);ptmpnode = ptmpnode->pnext;}printf("\n");return;}

                方法二:适用于寻找最后一个链表节点

linknode* find_last_node(linknode *phead) 
{if (phead == NULL)  // 如果链表为空,直接返回NULLreturn NULL;linknode *ptmpnode = phead;  // 从头节点开始(如果phead是哨兵节点,则用 phead->pnext)while (ptmpnode->pnext != NULL)  // 如果下一个节点不是NULL,就继续向后移动{ptmpnode = ptmpnode->pnext;}return ptmpnode;  // 此时 ptmpnode 就是最后一个节点
}

        3.5从链表中删除所有某元素

                定义两个指针ptmpnode用来遍历链表查找要删除的节点元素,pprenode永远只想 ptmpnode的前一个节点,当ptmpnode找到要删除的节点元素,让pprenode->pnext赋值为ptmpnode->pnext 并且把将要删除的节点元素释放,让ptmpnode判断下一个节点元素是否要删除,直到该指针指向NULL为止

//删除链表中所有的某一指定元素
int delete_linklist(linknode *phead, datatype tmpdata)
{linknode *pprenode = NULL;linknode *ptmpnode = NULL;pprenode = phead;ptmpnode = phead->pnext;while (ptmpnode != NULL){if (ptmpnode->data == tmpdata){pprenode->pnext = ptmpnode->pnext;free(ptmpnode);ptmpnode = pprenode->pnext;}else {ptmpnode = ptmpnode->pnext;pprenode = pprenode->pnext;}}return 0;
}

        3.6返回链表中第一个指定元素节点的地址

//数返回链表中第一个指定元素节点的地址void find_linklist(linknode *phead, datatype tmpdata){linknode *ptmpnode = NULL;linknode *pprenode = NULL;pprenode = phead;ptmpnode = pprenode->pnext;while (ptmpnode != NULL){if (ptmpnode->data == tmpdata){printf("%p\n",&pprenode->pnext);break;}else{ptmpnode = ptmpnode->pnext;pprenode = pprenode->pnext;}}return;}

        

        3.7将链表中指定元素的值更新为新值

//将链表中指定元素的值更新为新值void update_linklist(linknode *phead, datatype olddata, datatype newdata){linknode *ptmpnode = NULL;ptmpnode = phead;while (ptmpnode != NULL){if (ptmpnode->data == olddata){ptmpnode->data = newdata;}ptmpnode = ptmpnode->pnext;}return;}

        

        3.8链表的尾插法

 //尾插(顺序)void insert_tail_linklist(linknode *phead, datatype tmpdata){linknode *ptmpnode = NULL;linknode *tail = phead;//从第一个节点寻找,不能从第一个节点的下一个节点找,因为可能为空。ptmpnode = malloc(sizeof(linknode));ptmpnode->data = tmpdata;ptmpnode->pnext = NULL;while(tail ->pnext != NULL){tail = tail->pnext;}tail->pnext = ptmpnode;//将尾节点的pnext指向新建立的节点ptmpnodereturn;}

        3.9链表的销毁

4.Makefile

        3.1 Makefile

                工程管理工具,主要用来管理代码的编译,Makefile可以根据文件中的规则来选择符合条件的代码完成编译,其能够根据依赖关系和文件修改的时间戳来决定哪些代码需要编译,哪些代码不需要重新编译。

        3.2 Makefile使用规则

                1)在工程目录下,新建一个Makefile或者makefile的文件

                 2) 在Makefile中编写对应的文件编译规则

                3) 在工程目录下使用make来调用Makefile中的规则完成代码编译

        3. 3Makefile语法规则

要生成的文件:依赖的所有文件生成命令方式

        ​​​​​​​        ​​​​​​​        ​​​​​​​                        

http://www.dtcms.com/a/313382.html

相关文章:

  • 【数据结构】队列的顺序存储与链式存储(C语言版)
  • 基于深度学习的医学图像分析:使用变分自编码器(VAE)实现医学图像生成
  • (FD Conv)Frequency Dynamic Convolution for Dense Image Prediction论文精读(逐段解析)
  • 07.config 命令实现动态修改配置和慢查询
  • [硬件电路-138]:模拟电路 - 什么是正电源?什么是负电源?集成运放为什么有VCC+和VCC-
  • Unix 发展史概览
  • 探索 Zephyr 项目:高效、可扩展的实时操作系统
  • 源代码本地安装funasr
  • C语言数据结构(6)贪吃蛇项目1.贪吃蛇项目介绍
  • 有限元方法中的数值技术:三角矩阵求解
  • Vulnhub Corrosion2靶机复现
  • 机器人抓取流程介绍与实现——机器人抓取系统基础系列(七)
  • 腾讯云CentOS7镜像配置指南
  • Pytorch实现一个简单的贝叶斯卷积神经网络模型
  • Java 中也存在类似的“直接引用”“浅拷贝”和“深拷贝”
  • [创业之路-530]:创业公司五维架构设计:借鉴国家治理智慧,打造敏捷型组织生态
  • mysql8.0集群技术
  • 第13章 文件输入/输出
  • 知识蒸馏 - 基于KL散度的知识蒸馏 HelloWorld 示例 KL散度公式对应
  • 文件拷贝-代码
  • Doris json_contains 查询报错
  • 数据结构总纲以及单向链表详解:
  • 【LeetCode刷题指南】--对称二叉树,另一颗树的子树
  • [创业之路-531]:知识、技能、技术、科学之间的区别以及它们对于职业的选择的指导作用?
  • 【OpenGL】LearnOpenGL学习笔记02 - 绘制三角形、矩形
  • 13-day10生成式任务
  • 基于MBA与BP神经网络分类模型的特征选择方法研究(Python实现)
  • 在ANSYS Maxwell中对永磁体无线充电进行建模
  • 【大模型核心技术】Agent 理论与实战
  • 【设计模式】5.代理模式