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

嵌入式开发学习———Linux环境下数据结构学习(二)

链表的基本概念

链表是一种线性数据结构,由一系列节点组成,每个节点包含数据域和指针域。与数组不同,链表中的元素在内存中不需要连续存储,而是通过指针动态链接。

单向链表的特点

  • 每个节点包含数据和一个指向下一个节点的指针(next)。
  • 只能单向遍历(从头节点到尾节点)。
  • 插入和删除操作的时间复杂度为 $O(1)$(已知位置时),但查找需 $O(n)$。

单向链表的简单实现(Python示例)

class Node:def __init__(self, data):self.data = dataself.next = Noneclass LinkedList:def __init__(self):self.head = None

核心操作

插入节点

def insert_at_end(self, data):new_node = Node(data)if not self.head:self.head = new_nodeelse:current = self.headwhile current.next:current = current.nextcurrent.next = new_node

删除节点

def delete_node(self, key):current = self.headif current and current.data == key:self.head = current.nextreturnprev = Nonewhile current and current.data != key:prev = currentcurrent = current.nextif current:prev.next = current.next

优缺点

  • 优点:动态大小,高效插入/删除。
  • 缺点:随机访问慢,额外内存存储指针。

 作业:

单向链表建立等一系列操作 。

#include "linklist.h"int main(int argc, const char *argv[])
{//int i;//int n;//头节点指针linklistptr headptr=NULL;//头节点申请headptr=HeadNodeApply();//定义一个新数据datatype nwedata;for(i=0;i<9;i++){puts("请输入一个数:");scanf(" %d",&nwedata);//调用单向链表的头插函数LinklistHeadinsert(headptr,nwedata);}//调用单向链表的遍历函数LinklistShow(headptr);puts("请输入一个数:");scanf(" %d",&nwedata);//调用单向链表的尾插函数LinklistTailinsert(headptr,nwedata);//调用单向链表的遍历函数LinklistShow(headptr);//调用单向链表的尾删函数puts("尾删后:");LinklistTaildelete(headptr);//调用单向链表的遍历函数LinklistShow(headptr);//调用单向链表的头删函数puts("头删后:");LinklistHeaddelete(headptr);LinklistHeaddelete(headptr);//调用单向链表的遍历函数LinklistShow(headptr);puts("请输入一个数:");scanf(" %d",&nwedata);puts("请输插入的位置:");scanf(" %d",&n);//调用单向链表按位置插入函数LinklistSeatinsert(headptr,n,nwedata);//调用单向链表的遍历函数LinklistShow(headptr);puts("请输删除的位置:");scanf(" %d",&n);//调用单向链表按位置删除函数LinklistSeatdelete(headptr,n);//调用单向链表的遍历函数LinklistShow(headptr);puts("请输入一个数:");scanf(" %d",&nwedata);puts("请输修改的位置:");scanf(" %d",&n);//调用单向链表按位置修改函数LinklistSeatalter(headptr,n,nwedata);//调用单向链表的遍历函数LinklistShow(headptr);puts("请输查找的位置:");scanf(" %d",&n);//调用单向链表按位置查找函数LinklistSeatsift(headptr,n);//调用单向链表的逆置函数Linklistreverse(headptr);//调用单向链表的遍历函数LinklistShow(headptr);puts("请输查找的倒数位置:");scanf(" %d",&n);//调用单向链表按位置查找函数LinklistSeatreversesift(headptr,n);datatype olddata;puts("请输查找的数据:");scanf(" %d",&olddata);//调用单向链表按数据查找函数int seat=LinklistDatasift(headptr,olddata);LinklistSeatsift(headptr,seat);puts("请输入要修改的数据:");scanf(" %d",&olddata);puts("请输入修改后的数据:");scanf(" %d",&nwedata);//调用 单向链表按数据修改函数LinklistDataalter(headptr,olddata,nwedata);//调用单向链表的遍历函数LinklistShow(headptr);puts("请输入要删除的数据:");scanf(" %d",&olddata);//调用单向链表按数据删除函数LinklistDatadelete(headptr,olddata);//调用单向链表的遍历函数LinklistShow(headptr);//单向链表的排序函数LinklistSort(headptr);//调用单向链表的遍历函数LinklistShow(headptr);return 0;
}  
#ifndef _LINKLIST_H__
#define _LINKLIST_H__#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>enum returntype
{//失败返回FAULSE=-1,//成功返回SUCCESS
};//存储的数据的数据类型
typedef int datatype;//单向链表的节点结构体
typedef struct Node
{//数据域union {//头节点数据域int len;//普通节点数据域datatype data;}; //指针域struct Node *next;
}linklist,*linklistptr;//头节点申请函数
linklistptr HeadNodeApply(void);//普通节申请函数
linklistptr CommonNodeApply(datatype nwedata);//单向链表的头插函数
int LinklistHeadinsert(linklistptr headptr,datatype nwedata);//单向链表的遍历函数
int LinklistShow(linklistptr headptr);//单向链表的尾插函数
int LinklistTailinsert(linklistptr headptr,datatype nwedata);//单向链表的尾删函数
int LinklistTaildelete(linklistptr headptr);//单向链表的头删函数
int LinklistHeaddelete(linklistptr headptr);//单向链表按位置插入函数
int LinklistSeatinsert(linklistptr headptr,int n,datatype nwedata);//单向链表按位置删除函数(作业)
int LinklistSeatdelete(linklistptr headptr,int n);//单向链表按位置修改函数(作业)
int LinklistSeatalter(linklistptr headptr,int n,datatype nwedata);//单向链表按位置查找函数(作业)
int LinklistSeatsift(linklistptr headptr,int n);//单向链表的逆置函数
int Linklistreverse(linklistptr headptr);//查找链表倒数第n个数据
int LinklistSeatreversesift(linklistptr headptr,int n);//单向链表按数据查找
int LinklistDatasift(linklistptr headptr,datatype olddata);//单向链表按数据修改函数
int LinklistDataalter(linklistptr headptr,datatype olddata,datatype nwedata);//单向链表按数据删除函数
int LinklistDatadelete(linklistptr headptr,datatype olddata);//单向链表的排序函数
int LinklistSort(linklistptr headptr);#endif
#include "linklist.h"//头节点申请函数
linklistptr HeadNodeApply(void)
{//堆区申请linklistptr headptr=(linklistptr)malloc(sizeof(linklist));//判断创建是否成功if(headptr==NULL){return NULL;}//初始化headptr->next=NULL;headptr->len=0;//返回地址return headptr;
}//普通节申请函数
linklistptr CommonNodeApply(datatype nwedata)
{//堆区申请linklistptr comptr=(linklistptr)malloc(sizeof(linklist));//判断创建是否成功if(comptr==NULL){return NULL;}//赋值,初始化comptr->next=NULL;comptr->data=nwedata;//返回地址return comptr;
}//单链表的头插函数
int LinklistHeadinsert(linklistptr headptr,datatype nwedata)
{//判断头指针是否为空if(headptr==NULL){return FAULSE;}//创建一个普通节点并初始化linklistptr comptr=CommonNodeApply(nwedata);//判断普通节点是否为NULLif(comptr==NULL){return FAULSE;}//头插comptr->next=headptr->next;headptr->next=comptr;//链表长度自增headptr->len++;return SUCCESS;
}//单向链表的遍历函数
int LinklistShow(linklistptr headptr)
{//定义一个链表指针linklistptr ptr=NULL;//判断头指针是否为NULL//判断链表是否为空if(headptr==NULL||headptr->len==0){return FAULSE;}//赋值下一个节点地址ptr=headptr->next;//循环输出数据puts("链表现有数据:");while(ptr){printf(" %d",ptr->data);ptr=ptr->next;  //}putchar(10);return SUCCESS;
}//单向链表的尾插函数
int LinklistTailinsert(linklistptr headptr,datatype nwedata)
{//定义一个链表指针linklistptr ptr=NULL;//判断头指针是否为空if(headptr==NULL){return FAULSE;}//赋值头结点地址ptr=headptr;//循环找到链表尾部while(ptr->next){ptr=ptr->next;}//创建一个普通节点并初始化linklistptr comptr=CommonNodeApply(nwedata);//判断普通节点是否为空if(comptr==NULL){return FAULSE;}//尾插comptr->next=ptr->next;ptr->next=comptr;//链表长度自增headptr->len++;return SUCCESS;
}//单向链表的尾删函数
int LinklistTaildelete(linklistptr headptr)
{//定义一个链表指针linklistptr ptr=NULL,qtr=NULL;//判断头指针是否为NULL//判断链表是否为空if(headptr==NULL||headptr->len==0){return FAULSE;}//赋值头结点地址ptr=headptr;//循环找到链表次尾部while(ptr->next->next){ptr=ptr->next;}free(ptr->next);ptr->next=NULL;headptr->len--;return SUCCESS;
}//单向链表的头删函数
int LinklistHeaddelete(linklistptr headptr)
{//定义一个链表指针linklistptr ptr=NULL,qtr=NULL;//判断头指针是否为NULL//判断链表是否为空if(headptr==NULL||headptr->len==0){return FAULSE;}//赋值头结点地址ptr=headptr->next;headptr->next=headptr->next->next;//释放删除的空间free(ptr);ptr=NULL;headptr->len--;return SUCCESS;
}//单向链表按位置插入函数
int LinklistSeatinsert(linklistptr headptr,int n,datatype nwedata)
{//定义循环变量int i;//定义一个链表指针linklistptr ptr=NULL,qtr=NULL;//判断头指针是否为NULL//判断链表是否为空//判断n是否合法if(headptr==NULL||headptr->len==0||n<=0||n>headptr->len+1){return FAULSE;}//循环找到链表对应位置ptr=headptr;for(i=0;i<n-1;i++){ptr=ptr->next;}//创建一个普通节点并初始化linklistptr comptr=CommonNodeApply(nwedata);//判断普通节点是否为空if(comptr==NULL){return FAULSE;}//进行插入comptr->next=ptr->next;ptr->next=comptr;headptr->len++;return SUCCESS;
}//单向链表按位置删除函数
int LinklistSeatdelete(linklistptr headptr,int n)
{//定义循环变量int i;//定义一个链表指针linklistptr ptr=NULL,qtr=NULL;//判断头指针是否为NULL//判断链表是否为空//判断n是否合法if(headptr==NULL||headptr->len==0||n<=0||n>headptr->len){return FAULSE;}//循环找到链表对应位置ptr=headptr;for(i=0;i<n-1;i++){ptr=ptr->next;}//进行删除qtr=ptr->next;ptr->next=ptr->next->next;free(qtr);qtr=NULL;headptr->len--;return SUCCESS;
}//单向链表按位置修改函数
int LinklistSeatalter(linklistptr headptr,int n,datatype nwedata)
{//定义循环变量int i;//定义一个链表指针linklistptr ptr=NULL,qtr=NULL;//判断头指针是否为NULL//判断链表是否为空//判断n是否合法if(headptr==NULL||headptr->len==0||n<=0||n>headptr->len){return FAULSE;}//找到对应位置ptr=headptr;for(i=0;i<n;i++){ptr=ptr->next;}//赋值修改ptr->data=nwedata;return SUCCESS;
}//单向链表按位置查找函数
int LinklistSeatsift(linklistptr headptr,int n)
{//定义循环变量int i;//定义一个链表指针linklistptr ptr=NULL,qtr=NULL;//判断头指针是否为NULL//判断链表是否为空//判断n是否合法if(headptr==NULL||headptr->len==0||n<=0||n>headptr->len){return FAULSE;}//找到对应位置ptr=headptr;for(i=0;i<n;i++){ptr=ptr->next;}printf("linklist[%d]=%d\n",n,ptr->data);return SUCCESS;
}//单向链表的逆置函数
int Linklistreverse(linklistptr headptr)
{//定义循环变量int i;//定义两个链表指针linklistptr ptr=NULL,qtr=NULL;//判断头指针是否为NULL//判断链表是否为空或者只有一个数据if(headptr==NULL||headptr->len<=1){return FAULSE;}//存储头指针指向并断开ptr=headptr->next;headptr->next=NULL;//循环头插for(i=0;i<headptr->len;i++){qtr=ptr;ptr=ptr->next;qtr->next=headptr->next;headptr->next=qtr;}return SUCCESS;
}//查找链表倒数第n个数据
int LinklistSeatreversesift(linklistptr headptr,int n)
{//定义循环变量int i;//定义两个链表指针linklistptr ptr=NULL,qtr=NULL;//判断头指针是否为NULL//判断链表是否为空//判断n是否合法if(headptr==NULL||headptr->len==0||n<=0||n>headptr->len){return FAULSE;}//第一种单循环找倒数ptr=headptr->next;for(i=0;i<headptr->len-n;i++){ptr=ptr->next;}printf("linklist[-%d]=%d\n",n,ptr->data);//第二种双循环找倒数ptr=headptr;qtr=headptr;for(i=0;i<n;i++){qtr=qtr->next;}while(qtr){ptr=ptr->next;qtr=qtr->next;}printf("linklist[-%d]=%d\n",n,ptr->data);return SUCCESS;
}//单向链表按数据查找函数
int LinklistDatasift(linklistptr headptr,datatype olddata)
{//定义循环变量int i;//定义一个链表指针linklistptr ptr=NULL;//判断头指针是否为NULL//判断链表是否为空if(headptr==NULL||headptr->len==0){return FAULSE;}//赋值第一个节点位置并把位置置1ptr=headptr->next;int seat=1;for(i=0;i<headptr->len;i++){if(ptr->data==olddata){//返回位置return seat;}seat++;ptr=ptr->next;}return FAULSE;
}//单向链表按数据修改函数
int LinklistDataalter(linklistptr headptr,datatype olddata,datatype nwedata)
{//定义位置变量int seat;//调用单向链表按数据查找函数并判断seat=LinklistDatasift(headptr,olddata);if(seat==FAULSE){return FAULSE;}//调用单向链表按位置修改函数并判断if(LinklistSeatalter(headptr,seat,nwedata)==FAULSE){return FAULSE;}return SUCCESS;
}//单向链表按数据删除函数
int LinklistDatadelete(linklistptr headptr,datatype olddata)
{//定义位置变量int seat;//调用单向链表按数据查找函数并判断seat=LinklistDatasift(headptr,olddata);if(seat==FAULSE){return FAULSE;}//调用单向链表按位置删除函数并判断if(LinklistSeatdelete(headptr,seat)==FAULSE){return FAULSE;}return SUCCESS;
}//单向链表的排序函数
int LinklistSort(linklistptr headptr)
{int i,j;datatype temp;//定义一个链表指针linklistptr ptr=NULL,qtr=NULL;ptr=headptr->next;for(i=0;i<headptr->len-1;i++){qtr=ptr;for(j=0;j<headptr->len-1;j++){if(qtr->data>qtr->next->data){temp=qtr->data;qtr->data=qtr->next->data;qtr->next->data=temp;}qtr=qtr->next;}}return SUCCESS;
}


运行示例:

2.牛客网刷题

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

相关文章:

  • MYSQL 笔记3
  • vscode怎么安装MINGW
  • Https以及CA证书
  • VUE接口任务轮询查询任务封装hooks
  • 免费的远程电脑控制软件
  • 银河麒麟v10 更换linux内核(降内核版本5.15->5.4)
  • kanzi3.6.10 窗口插件-网页生成界面
  • istio-proxy用哪个端口代理http流量的?
  • 百度文心大模型ERNIE全面解析
  • 绿地集团携手深兰科技推动AI医诊大模型快速落地
  • AI产品经理面试宝典第48天:产品设计与用户体验优化策略
  • 从零解析DeepSeek Excel公式生成器的深度学习实现原理
  • Mybatis_1
  • Spring Bean初始化及@PostConstruc执行顺序
  • 零侵入加解密方案:Spring Boot + Jasypt + AOP实现敏感数据自动保护
  • Leetcode力扣解题记录--第54题(矩阵螺旋)
  • 表征工程中哪里用到内积 :内积vs余弦相似度--谁更胜一筹?
  • 智慧农业平台-农资农服农业数字化转型
  • 算法第三十七天:动态规划part05(第九章)
  • Golang各版本特性
  • 算法:数组part01:704. 二分查找 +977.有序数组的平方
  • ZeroMQ源码深度解析:高性能网络库的架构设计与性能优化
  • 高效编程革命:DeepSeek V3多语言支持与性能优化实战
  • 【前端】当前主流的 CSS 预处理器语言Sass / SCSS、Less、Stylus
  • C++:list(1)list的使用
  • HomeAssistant本地开发笔记
  • 「iOS」——KVO
  • MCP客户端架构与实施
  • SQL基础⑦ | 子查询
  • Linux——System V 共享内存 IPC