数据结构基础篇(4)

十六.循环链表

  • 概念
    • 循环链表是一种头尾相接的链表(最后一个结点的指针域指向头结点,整个链表形成一个环)
  • 优点
    • 从表任一结点出发均可找到表中其他结点
  • 判断终止
    • 由于循环链表中没有NULL指针,所以涉及遍历操作时,终止条件不像非循环链表那样判断p或p->next是否为空,而是是否等于头指针
    • 循环条件从p!=NULL到p!=L,p->next!=NULL到p->next!=L(单循环链表)
  • 时间复杂度
    • 头指针表示单循环链表
      • 找a~1的时间复杂度:O(1)
      • 找a~n的时间复杂度:O(n)
        • 注意
          • 表的操作常常在表的首尾位置上进行
    • 尾指针表示单循环链表
      • a~1的存储位置是:R->next->next
      • a~n的存储位置是:R
      • 时间复杂度均为O(1)
  • LinkList Connect(LinkList Ta,LinkList Tb)    //假设Ta.Tb都是非空的单循环链表
    {vp=Ta->next;    //p存表头结点Ta->next=Tb->next->next;    //Tb表头连接Ta表尾delete Tb->next;    //释放Tb表头结点Tb->next=p;    //修改指针return Tb;
    }  

十七.双向链表

  • 双向链表的由来
    • 查找某结点的后续结点的执行时间=O(1)
      • 单链表结点->有指示后继的指针域->后继结点
    • 查找某结点的前驱结点的执行时间=O(n)
      • - ->无指示前驱的指针域->依次寻找前驱结点
  • 双向链表的概念
    • 在单链表的每个结点里再增加一个指向其直接前驱的指针域prior,这样链表就形成了有两个方向不同的链。
  • 双向链表的特点
    • 双向链表也有循环表
      • 让头结点的前驱指针指向链表的最后一个节点
      • 让最后一个节点的后继指针指向头结点
  • 双向链表结构的对称性
    • p->prior->next=p=p->next->prior
  • 在双向链表中有些操作(如:ListLength、GetElem等),因仅涉及一个方向的指针,所以它们的算法与线性链表的相同。
  • 在插入、删除时,则需同事修改两个方向上的指针,两个的操作的时间复杂度都为O(n)。

双向链表的插入

void ListInsert_DuL(DuLinkList &L,Init i,ElemType e)    //在带头结点的双向循环链表L中第i个位置之前插入元素e
{if(!(p=GetElemP_DuL(L,i)))return ERROR;s=new DuLNOde;s->date=e;s->prior=p->prior;p->prior->next=s;s->next=p;p->prior=s;return OK;
}//ListInsert_Dul

双向链表的删除

void ListDelete_DuL(DuLinkList &L,Init i,ElemType &e)    //删除带头节点的双向循环链表L的第i个元素,并返回e
{if(!(p=GetElemP_DuL(L,i)))return ERROR;e=p->data;p->prior->next=p->next;p->next->prio=p->prior;free(p)return OK;
}//ListDelete_Dul

十八.单链表,循环链表和双向链表的时间效率比较

时间效率的比较

查找表头结点(首元结点)

查找表尾结点

查找结点*P的前驱结点

带头结点的单链表L

L->next

时间复杂度O(1)

从L->next依次向后遍历时间复杂度O(n)

通过p->next无法找到其前驱

带头结点仅设头指针L的循环单链表

L->next

时间复杂度O(1)

从L->next依次向后遍历时间复杂度O(n)

通过p->next可以找到其前驱 时间复杂度O(n)

带头结点仅设尾指针R的循环单链表

R->next|

时间复杂度O(1)

R 时间复杂度O(1)

通过p->next可以找到其前驱 时间复杂度O(n)

带头结点的双向循环链表L

L->next

时间复杂度O(1)

L->prior

时间复杂度O(1)

p->prior 时间复杂度O(1)

十九.顺序表和链表的比较

  • 链式存储结构的优点
    • 节点空间可以动态申请和释放
    • 数据元素的逻辑次序靠节点的指针来指示,插入和删除时不需要移动数据元素
  • 链式存储结构的缺点
    • 存储密度小,每个结点的指针域需额外占用存储空间。当每个节点的数据域所占字节不多时,指针域所占存储空间的比重闲得很大。
      • 存储密度
        • 概念
          • 结点数据本身所占的存储量和整个节点结构所占的存储量之比
        • 公式
          • 存储密度=结点数据本身占用的空间/结点占用的空间总量
        • 比较
          • 顺序表存储密度1,链式小于1。
    • 链式存储结构是非随机存储结构。对任一结点的操作都要从头指针依指针链查找到该结点,增加了算法的复杂度。
  • 顺序表和链表比较图

比较项目\存储结构

顺序表

链表

空间-存储空间

预先分配,导致空间闲置或溢出现象

动态分配,不会出现存储空间闲置或溢出现象

空间-存储密度

不用为表示结点间的逻辑关系而增加额外的存储开销,存储密度等于1

需要借助指针来体现元素间的逻辑关系,存储密度小于1.

时间-存取元素

随机存储,按位置访问元素的时间复杂度O(1)

顺序存储,按位置访问元素时间复杂度O(n)

时间-插入、删除

平均移动约表中一半元素,时间复杂度O(n)

不需要移动元素,确定插入,删除位置后,时间复杂度O

适用情况

  • 表长变化不大,能事先确定变化的范围。
  • 很少进行插入或删除操作,经常按元素位置序号访问数据元素。
  • 长度变化较大
  • 频繁进行插入或删除操作

二十.线性表的应用

  • 线性表的合并
    • 问题
      • 假设利用两个线性表La和Lb分别表示两个集合A和B,现要求一个新的集合A=AUB
    • 解决
void union(List &La,List Lb)
{La_len=ListLength(La);Lb_len=ListLength(Lb);for(i=1;i<=Lb_len;i++){GetElem(Lb,i,e);if(!LocateElem(La,e))ListInsert(&La,++La_len,e);    }
}    //算法的时间复杂度是:O(ListLength(La)*ListLength(Lb))
  • 有序表的合并
    • 问题
      • 已知线性表La和Lb中的数据元素按值非递减有序排列,现要求LA和Lb归并为一个新的线性表Lc,Lc中的数据元素扔按值非递减有序排列。
    • 解决
      • 创建一个空表Lc
      • 依次从La或Lb中“摘取”元素值较小的节点插入到Lc表的最后,直到其中一个表边空为止
      • 继续将La或Lb其中一个表的剩余节点插入在Lc表的最后

用顺序表来实现

void MergeList_Sq(SqList LA,SqList Lb,SqList &LC)
{pa=LA.elem;pb=LB.elem;    //指针pa和pb的初值分别指向两个表的第一个元素LC.length=LA.length+LB.length;    //新表长度为待合并量表的长度之和LC.elem=new ElemType[LC.length];    //为合并后的新表分配一个数组空间pc=LC.elem;    //指针pc指向新表的第一个元素pa_last=LA.elem+LA.length-1;    //指针pa_last指向LA表的最后一个元素pb_last=LB.elem+LB.length-1;     //指针pa_last指向LB表的最后一个元素while(pa<=pa_last && pb<=pb_last)    //两个表都非空{if(*pa<=*pb)*pc++=*pa++;    //依次“摘取”两表中的最小值else *pc++=*pb++;                                                          }while(pa<=pa_last)*pc++=*pa++;     //LB表已到达表尾,将LA中剩余元素加入LCwhile(pb<=pb_last)*pc=++=*pb++;    //LA表已到达表尾,将LB中剩余元素加入LC
}    //MergeList_Sq//算法的时间复杂度是:O(ListLength(La)*ListLength(Lb))

用链表来实现

void MergeList_L(SqList &La,SqList &Lb,SqList &Lc)
{pa=La->next;pb=Lb->next;pc=Lc=La;    //用La的头结点作为Lc的头结点while(pa&&pb){if(pa->data<=pb->data){pc->next=pa;pc=pa;pa=pa->next;        }               else{pc->next=pb;pc=pb;pb=pb->next;        }     }pc->next=pa?pa:pb;  //插入剩余段delete Lb;    //释放Lb的头结点
}    //算法的时间复杂度是:O(ListLength(La)*ListLength(Lb))
  • 一元多项式的运算
    • 多项式创建
    • 创建一个只有头结点的空链表
    • 根据多项式的项的个数n,循环n次执行以下操作
      • 生成一个新结点*s
      • 输入多项式当前项的系数和指数赋给新节点*s的数据域
      • 设置一前驱指针pre,用于指向待找到的第一个大于输入项指数的结点的前驱,pre初值指向头结点。
      • 指针q初始化,指向首元结点
      • 循链向下逐个比较链表中当前结点与输入项指数,找到第一个大与输入项指数的节点*q
      • 将输入项结点*s插入到结点*q之前
void CreatePolyn(Polynomial &P,int n)    //输入m项的系数和指数,建立表示多项式的有序链表P
{P=new PNode;p->next=NULL;    //先建立一个带头结点的单链表for(i=1;i<=n;i++)    //依次输入n个非零项{s=new PNode;    //生成新节点cin>>s->coef>>s->expn;    //输入系数和指数pre=P;    //pre用于保存q的前驱,初值为头结点q=P->next;    //q初始化,指向首元结点while(q&&q->expn<s->expn)    //找到第一个大于输入项指数的项*q{pre=q;q=q->next;        }    s->next=q;    //将输入项s插入到q和其前驱结点pre之间pre->next=s;}
}

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

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

相关文章

RocketMQ学习(2) 深入学习

RokcetMQ的介绍和基础知识见这篇博客——RocketMQ学习(1) 快速入门 本篇为上一篇的深入学习&#xff0c;很多基础知识不再赘述。 目录 消息重复消费问题(去重;幂等)布隆过滤器 重试机制死信消息 SpringBoot集成RocketMQ集成SpringBoot发送不同消息模式(同步消息)异步消息单向消…

python下载指定URL的文件

import requests # 图片的URL地址 url https://book.pep.com.cn/1212001402143/files/mobile/1.jpg?240301113921 # 发送HTTP GET请求 response requests.get(url) # 检查请求是否成功 if response.status_code 200: # 打开一个文件用于写入 with open(download…

实习碰到的问题w1

1.vueelementUI在输入框中按回车键会刷新页面 当一个 form 元素中只有一个输入框时&#xff0c;在该输入框中按下回车应提交该表单。如果希望阻止这一默认 行为&#xff0c;可以在 <el-form> 标签上添加 submit.native.prevent 。 参考&#xff1a;element-ui 表单 form …

使用el-tab,el-tab-pane循环使用循环后不显示下划线问题

在vue项目中使用element-UI el-tab里的el-tab-pane是循环出来的&#xff0c;但是循环出来后选中tab不显示下划线了 文章目录 问题问题展示效果问题代码问题原因 解决方案解决后效果解决方案1代码 解决方案2代码 问题 问题展示效果 问题代码 <el-tabs v-model"activeNa…

音量的对数表示与浮点数表示

音量用浮点数&#xff08;float&#xff09;和对数&#xff08;logarithmic scale&#xff09;表示各有特点和应用场景 浮点数&#xff1a;直接使用线性刻度表示音量&#xff0c;例如在0.0&#xff08;最小音量&#xff09;到1.0&#xff08;最大音量&#xff09;的范围内。对…

『 Linux 』缓冲区(万字)

文章目录 &#x1f9a6; 什么是缓冲区&#x1f9a6; 格式化输入/输出&#x1f9a6; 刷新策略&#x1fab6; 块缓冲(fully buffered)&#x1fab6; 无缓冲(unbuffered)&#x1fab6; 行缓冲(line buffered) &#x1f9a6; 现象解释&#x1f9a6; exit()与_exit()&#x1f9a6; 进…

list 的实现

目录 list 结点类 结点类的构造函数 list的尾插尾删 list的头插头删 迭代器 运算符重载 --运算符重载 和! 运算符重载 * 和 -> 运算符重载 list 的insert list的erase list list实际上是一个带头双向循环链表,要实现list,则首先需要实现一个结点类,而一个结点需要…

【代码随想录——回溯算法——四周目】

1.重新安排行程 1.1 我的代码&#xff0c;超时通不过 var (used []boolpath []stringres []stringisFind bool )func findItinerary(tickets [][]string) []string {sortTickets(tickets)res make([]string, len(tickets)1)path make([]string, 0)used make([]bool,…

JSON Web Token

JWT 什么是JWT JWT&#xff08;JSON Web Token&#xff09;是一种用于在各方之间作为JSON对象安全地传输信息的开放标准&#xff08;RFC 7519&#xff09;。该信息经过数字签名&#xff0c;因此是可验证和可信的。JWT 可以使用HMAC算法或使用RSA的公钥/私钥对进行签名 JWT的…

微信小程序 vant Picker组件default-index不生效的解决办法

1、原始的写法以及问题 <van-popup show"{{ showPopup && cellClick Freq }}" position"bottom" bind:close"onPopupClose"><van-picker value-key"Spec" show-toolbar title"{{cellClick Freq ? showPcCha…

win10键盘按乱了,如何恢复?

今天键盘被宝宝给按乱了&#xff0c;好不容易给重新调整回来&#xff0c;记录备忘&#xff1a; 1、win10的asdf和方向键互换了&#xff1a; 使用Fnw键来回切换&#xff0c;OK&#xff01; 2、键盘的win键失效&#xff0c;例如&#xff1a;按winD无法显示桌面。此时&#xf…

Day30

Day30 CSS CSS常用样式 font-family:“微软雅黑” -设置字体 font-size: 50px -设置字体大小 font-style : italic-设置字体风格 font-weight:bolder -设置字体粗细 color: white-设置字体颜色 letter-spacing: 20px-设置文本内容的间隔 text-decoration :underline - 设置划…

电动汽车电子系统架构

电动汽车的普及正在稳步发展&#xff0c;供应链的各个环节也在发生变化。它涵盖了制造电动汽车零件的原材料、化学品、电池和各种组件。与此同时&#xff0c;汽车充电基础设施也参与其中&#xff0c;它们正经历一个历史性的阶段&#xff0c;经过彻底的重新设计。它们的电气化以…

Wpf 使用 Prism 实战开发Day30

登录界面设计 一.准备登录界面图片素材&#xff08;透明背景图片&#xff09; 1.把准备好的图片放在Images 文件夹下面&#xff0c;格式分别是.png和.ico 2.选中 login.png图片鼠标右键&#xff0c;选择属性。生成的操作选择>资源 3.MyTodo 应用程序右键&#xff0c;属性&a…

如何修改开源项目中发现的bug?

如何修改开源项目中发现的bug&#xff1f; 目录 如何修改开源项目中发现的bug&#xff1f;第一步&#xff1a;找到开源项目并建立分支第二步&#xff1a;克隆分支到本地仓库第三步&#xff1a;在本地对项目进行修改第四步&#xff1a;依次使用命令行进行操作注意&#xff1a;Gi…

地质灾害位移应急监测站

地质灾害位移应急监测站是一种专门用于地质灾害预警和应急响应的设施&#xff0c;它能够实时监测和分析山体、建筑物、管道等的位移变化情况。以下是关于地质灾害位移应急监测站的详细介绍&#xff1a; 主要组成部分 传感器&#xff1a;安装于需要监测的位置&#xff0c;用于…

RK3588+FPGA+AI高性能边缘计算盒子,应用于视频分析、图像视觉等

搭载RK3588&#xff08;四核 A76四核 A55&#xff09;&#xff0c;CPU主频高达 2.4GHz &#xff0c;提供1MB L2 Cache 和 3MB L3 &#xff0c;Cache提供更强的 CPU运算能力&#xff0c;具备6T AI算力&#xff0c;可扩展至38T算力。 产品规格 系统主控CPURK3588&#xff0c;四核…

Nginx服务器替换SSL证书记得要重启

输入访问域名&#xff0c;发现https证书过期了&#xff0c;果断申请好ssl证书&#xff0c;并在Nginx服务器上将原证书替换成新申请的证书。 打开浏览器输入网址确认一看&#xff0c;还是原来的证书并没有替换成功?感觉不合常理 以下开启了证书为什么替换不成功的排查 1、清除…

GUI 02:布局管理器相关知识,AWT 的 3 种布局管理器应用,以及嵌套布局的使用

一、前言 记录时间 [2024-05-31] 前置文章 GUI 01&#xff1a;GUI 编程概述&#xff0c;AWT 相关知识&#xff0c;Frame 窗口&#xff0c;Panel 面板&#xff0c;及监听事件的应用 本文讲述了 GUI 编程种布局管理器的相关知识&#xff0c;以及 AWT 的 3 种布局管理器——流式布…

【FPGA】Verilog语言从零到精通

接触fpga一段时间&#xff0c;也能写点跑点吧……试试系统地康康呢~这个需要耐心但是回报巨大的工作。正原子&&小梅哥 15_语法篇&#xff1a;Verilog高级知识点_哔哩哔哩_bilibili 1Verilog基础 Verilog程序框架&#xff1a;模块的结构 类比&#xff1a;c语言的基础…