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

25072班8.25日 数据结构作业

思维导图

完成双向循环链表的重要功能代码

双向循环链表头插

//头插
void head_insert(dlink_p head,int element)
{//判存if(head==NULL){printf("头插:链表不存在!\n");return ;}dlink_p p=create_node(element);p->next=head->next;p->prev=head;head->next=p;p->next->prev=p;head->len++;
}

双向循环链表尾插

//尾插
void last_insert(dlink_p head,int element)
{//判存if(head==NULL){printf("头插:链表不存在!\n");return ;}//尾节点dlink_p p=head;//新节点dlink_p q=create_node(element);if(head->next!=NULL){while(p->next!=head){p=p->next;}}q->next=head;q->prev=p;p->next=q;head->prev=q;head->len++;
}

双向循环链表头删

//头删
void head_del(dlink_p head)
{//判存if(head==NULL){printf("头删:链表不存在!\n");return ;}//判空if(empty(head)==-1){printf("头删:链表为空!\n");return ;}dlink_p del=head->next;if(del->next==head){head->next=head;}else{del->next->prev=head;head->next=del->next;head->len--;}free(del);del=NULL;
}

双向循环链表尾删

//尾删
void last_del(dlink_p head)
{//判存if(head==NULL){printf("尾删:链表不存在!\n");return ;}//判空if(empty(head)==-1){printf("尾删:链表为空!\n");return ;}dlink_p p=head;while(p->next->next!=head){p=p->next;}dlink_p del=p->next;p->next=head;free(del);del=NULL;head->len--;
}

双向循环链表按位插

//位插
void pos_insert(dlink_p head,int pos,int element)
{//判存if(head==NULL){printf("按位插:链表不存在!\n");return ;}//判位if(pos_right(head,pos)<pos-1||pos<0){printf("按位插:输入位置不合理!\n");return ;}//创建新节点dlink_p q=create_node(element);dlink_p p=head;//找到pos位int i=0;while(i!=pos-1){i++;p=p->next;}q->next=p->next;q->prev=p;p->next=q;p->next->prev=q;head->len++;	
}

双向循环链表按位删

//按位删
void pos_del(dlink_p head,int pos)
{//判存if(head==NULL){printf("按位删:链表不存在!\n");return ;}//判位if(pos_right(head,pos)<pos-1||pos<0){printf("按位删:输入位置不合理!\n");return ;}dlink_p p=head;//找到pos位int i=0;while(i!=pos){i++;p=p->next;}p->prev->next=p->next;p->next->prev=p->prev;free(p);p=NULL;head->len--;	
}

源码(功能代码)

#include "head.h"
//创建头结点
dlink_p create_head()
{//申请空间dlink_p head=(dlink_p)malloc(sizeof(dlink));if(head==NULL){printf("头结点创建失败!\n");return NULL;}//初始化头结点head->next=head;head->prev=head;head->len=0;return head;
}
//创建节点
dlink_p create_node(int element)
{//申请空间dlink_p p=(dlink_p)malloc(sizeof(dlink));if(p==NULL){printf("创建节点:创建失败!\n");return NULL;}//初始化节点p->data=element;p->next=p;p->prev=p;return p;
}
//判空
int empty(dlink_p head)
{if(head->next==head){printf("空!\n");return -1;}return 0;
}
//头插
void head_insert(dlink_p head,int element)
{//判存if(head==NULL){printf("头插:链表不存在!\n");return ;}dlink_p p=create_node(element);p->next=head->next;p->prev=head;head->next=p;if(p->next!=head){p->next->prev=p;}else{head->prev=p;}head->len++;}
//尾插
void last_insert(dlink_p head,int element)
{//判存if(head==NULL){printf("头插:链表不存在!\n");return ;}//尾节点dlink_p p=head;//新节点dlink_p q=create_node(element);if(head->next!=NULL){while(p->next!=head){p=p->next;}}q->next=head;q->prev=p;p->next=q;head->prev=q;head->len++;}
//输出
void output(dlink_p head)
{//判存if(head==NULL){printf("输出:链表不存在!\n");return ;}//判空if(empty(head)==-1){printf("输出:链表为空!\n");return;}dlink_p p=head->next;while(p!=head){printf("%-4d",p->data);p=p->next;}putchar(10);}
//判位
int pos_right(dlink_p head,int pos)
{dlink_p p=head->next;int i=1;while(p->next!=head){p=p->next;i++;}return i;
}
//位插
void pos_insert(dlink_p head,int pos,int element)
{//判存if(head==NULL){printf("按位插:链表不存在!\n");return ;}//判位if(pos_right(head,pos)<pos-1||pos<0){printf("按位插:输入位置不合理!\n");return ;}//创建新节点dlink_p q=create_node(element);dlink_p p=head;//找到pos位int i=0;while(i!=pos-1){i++;p=p->next;}q->next=p->next;q->prev=p;p->next=q;if(p->next!=head){p->next->prev=q;}else{head->prev=q;}head->len++;	
}//头删
void head_del(dlink_p head)
{//判存if(head==NULL){printf("头删:链表不存在!\n");return ;}//判空if(empty(head)==-1){printf("头删:链表为空!\n");return ;}dlink_p del=head->next;if(del->next==head){head->next=head;}else{del->next->prev=head;head->next=del->next;head->len--;}free(del);del=NULL;
}
//尾删
void last_del(dlink_p head)
{//判存if(head==NULL){printf("尾删:链表不存在!\n");return ;}//判空if(empty(head)==-1){printf("尾删:链表为空!\n");return ;}dlink_p p=head;while(p->next->next!=head){p=p->next;}dlink_p del=p->next;p->next=head;free(del);del=NULL;head->len--;}//按位删
void pos_del(dlink_p head,int pos)
{//判存if(head==NULL){printf("按位删:链表不存在!\n");return ;}//判位if(pos_right(head,pos)<pos-1||pos<0){printf("按位删:输入位置不合理!\n");return ;}dlink_p p=head;//找到pos位int i=0;while(i!=pos){i++;p=p->next;}p->prev->next=p->next;p->next->prev=p->prev;free(p);p=NULL;head->len--;	}


整理顺序栈的代码,输出栈,销毁栈

输出栈

销毁栈

代码集

#include "head.h"
//创建顺序栈
stack_p create_stack()
{stack_p stk=(stack_p)malloc(sizeof(stack));if(stk==NULL){printf("创建顺序栈失败!\n");return NULL;}stk->top=-1;bzero(stk,sizeof(stk->data));return stk;}
//压数据入栈
void push_stack(stack_p stk,int element)
{if(stk==NULL){printf("入参为空,请检查\n");return;}//先加再压//先加栈顶位置,再将元素压入栈stk->data[++(stk->top)] = element;
}
//判空
int empty(stack_p stk)
{if(stk==NULL){printf("入参为空!\n");return -1;}return stk->top==-1;	
}
//判满
int full(stack_p stk)
{	if(stk==NULL){printf("入参为空!\n");return -1;}return stk->top==MAX-1;		
}
//出栈(弹栈)
int pop_stack(stack_p stk)
{if(stk==NULL){printf("入参为空!\n");return -1;}return stk->data[stk->top--];	
}//输出
int main()
{//创建顺序栈stack_p stk=create_stack();int element;for(int i=0;i<MAX;i++){printf("请输入入栈元素:");scanf("%d",&element);push_stack(stk,element);}//循环输出for(int i=0;i<MAX;i++){printf("输出栈:%d\n",pop_stack(stk));}//销毁栈free(stk);stk=NULL;empty(stk);return 0;
}


总结顺序表和链表的区别和优缺点。

区别:

存储结构

顺序表:在内存中占用一段连续的存储空间,逻辑上相邻的元素在物理地址上也相邻。比如在 C 语言中,定义一个整型数组 int arr[5],它在内存中是连续存储这 5 个整数的 。

链表:是一种链式存储结构,每个节点除了存储数据元素外,还包含一个或多个指针,用于指向其他节点,节点在内存中的存储位置不一定连续。以单链表为例,每个节点包含数据域和指针域,指针指向下一个节点 。

数据元素的访问方式

顺序表:可以通过下标直接访问元素,时间复杂度为 O(1) 。例如,对于数组 arr,访问 arr[i] 可以直接定位到相应位置。

链表:只能从链表的头节点开始,通过指针依次向后查找元素,时间复杂度为 O(n),其中 n 是链表的长度。比如要找单链表中第 k 个节点,需要从表头开始遍历 k 次 。

插入和删除操作

顺序表:在插入或删除元素时,可能需要移动大量元素。例如在数组中间位置插入一个元素,需要将插入位置之后的所有元素向后移动一位,时间复杂度为 O(n) 。

链表:插入和删除操作相对简单,只需要修改指针指向即可。例如在单链表中插入一个节点,只需修改插入位置前一个节点的指针,时间复杂度为 O(1) ,但在找到插入位置前,可能需要遍历链表,整体时间复杂度在链表中间或尾部插入删除为 O(n),在头部插入删除为 O(1) 。

优点

顺序表

随机访问效率高:可以快速访问任意位置的元素,适合频繁进行查找操作的场景,比如在数组中查找学生成绩 。

存储密度高:不需要额外存储指针,空间利用率较高。

实现简单:在一些简单的场景下,顺序表的代码实现相对容易,理解和维护成本低 。

链表

插入和删除灵活:在插入和删除操作上不需要移动大量元素,效率更高,尤其适合数据频繁变动的场景,如实现一个任务队列,不断添加和删除任务 。

内存分配灵活:链表的节点在需要时才分配内存,不需要预先分配连续的大块内存,适合内存资源有限或数据量不确定的情况 。

缺点

顺序表

插入和删除效率低:在顺序表中间位置插入或删除元素时,需要移动大量元素,操作耗时较长。

空间扩展困难:如果需要增加顺序表的容量,可能需要重新分配更大的连续内存空间,并将原数据复制过去,操作复杂且耗时 。

链表

访问效率低:不能像顺序表那样随机访问元素,查找特定元素需要从头开始遍历,时间复杂度较高。

存储开销大:每个节点除了存储数据外,还需要存储指针,会占用一定的额外空间 。

实现相对复杂:链表的操作涉及到指针的管理,如指针的赋值、释放等,代码实现相对复杂,容易出现指针错误,如空指针引用、内存泄漏等问题 。

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

相关文章:

  • 04-Maven工具介绍
  • kafka 副本集设置和理解
  • 《Spring Boot 进阶:从零到一打造自定义 @Transactional》 ——支持多数据源、动态传播行为、可插拔回滚策略
  • AI系列 - Claude 与 Qwen 模型自动补全对比:谁更胜一筹?
  • 电力系统稳定性的挑战与智能控制新范式
  • 网络与信息安全有哪些岗位:(8)安全审计员
  • C 语言:第 20 天笔记:typedef(类型重命名规则、应用场景与实战案例)
  • 黑客窃取 EDR 检测未检测到的 Windows 机密和凭证
  • 讲解计网中OSI模型及各层作用
  • 网闸和防火墙各有什么长处?
  • ValueTask 实战指南:解锁 .NET 异步编程的性能秘密
  • maui中配置安卓手机在测试环境连接网络
  • 创建Java集成开发环境
  • 车载诊断架构 --- 基于以太网做software download的疑问汇总
  • [QMT量化交易小白入门]-八十四、LSTM模型对期货市场的秒级Tick数据进行预测
  • 14.examples\01-Micropython-Basics\demo_yield.py 加强版
  • 深入浅出 ArrayList:从基础用法到底层原理的全面解析(中)
  • 深度剖析 Grok2 开源:技术原理与创新洞察
  • 奶茶品牌ESG实践:从绿色供应链到可持续竞争力
  • 离线可用的网络急救方案
  • [RK3568][Android11] Android->默认显示设置->系统->开发者选项(不用连续点击版本号)
  • FunASR基础语音识别工具包
  • 学习Python第13天
  • .NET表格控件Spread .NET v18.0——支持富文本、增强PDF导出
  • 【Linux基础知识系列】第一百零七篇 - 使用crontab设置定期任务
  • 【文献阅读】SparseGPT: Massive Language Models Can be Accurately Pruned in One-Shot
  • 【保姆级】AutoCAD 2026安装包下载及详细图文安装教程!
  • Mysql杂志(一)
  • 大模型中常用的提示词框架
  • Python爬虫第五课:selenium自动化爬虫实战