数据结构与算法--线性表系列(循环链表、双向链表)

hello,everybody,今天我们来学习线性表的最后两种形式,循环链表、双向链表。这两种链表,是链式存储结构的不同形式。书归正传,我们先来看看循环链表吧。

大家思考一个问题,我们把线性表各个元素比作下图的路线图上的城市:

我们的线性表各个结点的指针,都是指向唯一的后继结点,线性表的终端结点的指针为空。这样的话,如果我们在南京,我们需要先访问南京右j边的城市,再访问南京左边的城市。根据线性表的结构,我们只能返回上海,从上海依次访问到北京。因为我们的终端结点的指针为空,如果直接访问南京右边的城市,那么到北京后,就断片儿了,也就不能访问南京左边的城市了。现实生活中,如果我们选择这样的路线的话,估计要被大家笑掉大牙了。

这时候,我们的循环链表就出世了。我们把北京与上海连起来,这样就Ok了。其实,就是把线性表的终端结点的指针指向线性表的第一个结点。让线性表,联通起来,成为循环的链表。

循环链表:将单链表中终端结点的指针端由空指针改为指向头结点,就使得整个单链表成为一个环,这种头尾相接的单链表称为单循环链表,简称循环链表(circular
linked list).

从刚才的例子中,我们可以发现,循环链表解决了一个严重的问题。它的出现,使得我们可以从当中一个结点遍历整个线性表。

为了使空循环链表与非空循环链表操作一致,我们通常会在线性表中设立空结点。空结点对于循环链表不是必须的,它的出现只是为了统一操作。

空的带有头结点的循环链表。

非空的带有头结点的循环链表。

其实,单链表与循环链表的区别,在于判断上。单链表是判断p->next不为空,则说明遍历未结束。循环链表判断p->next为头结点,则循环未结束。

在单链表中,我们通过头指针可以花费O【1】的时间复杂度访问到第一个元素结点。但是需要遍历整个链表,花费O【n】的时间复杂度,才可以访问到终端结点。

现在我们可以修改一下链表,使得也可以花费O[1]的时间复杂度访问到终端结点。不同的之处在于,我们不用头指针,而用尾指针来指向终端结点。

从上图我们看以看出,通过尾指针rear,我们可以花费O【1】的时间复杂度访问到终端结点。而对于开始结点,其实就是rear->next->next.时间复杂度也为O【1】.

以上就是循环链表,它的出现就是为了解决从中间元素访问整个链表的问题。

我们来看一下双向链表:

还是刚才那幅图:

我们在北京开完会,需要走访北京左边的所有城市。根据我们学到的线性结构,只能先到上海,
在由上海开始依次到北京,再从北京到上海。此时,双向链表就诞生了。

单链表查找下个元素的时间复杂度为O【1】,查找上一个元素的时间时间复杂度为O【n】,因为需要我们遍历整个链表。为了克服这个弊端,设计了双向链表。双向链表(double
linked list),是在单链表的每个结点中,再设置一个指向前驱结点的指针域。

我们看一下它的代码结构:

typedef struct DulNode

{

ElemType data;

struct DulNode *prior ; /*直接前驱指针*/

struct  DulNode *next;  /*直接后继指针*/

}DulNode,*DuLinkList;

既然单链表有循环链表,那么双向链表也有循环链表。

双向链表的循环带头结点的空链表。

双向链表的循环带头结点的非空链表

关与它的一些操作,与之前的单链表很相似。

以上就是双向表的知识。

好了,让我们一起来总结一下线性表这章知识吧。

首先,我们先学习了线性表的概念,线性表就是零个或多个具有相同类型的数据元素的有限序列。接下来,我们从存储结构上,分别讲解了线性表的顺序存储,与线性表的链式存储。其中,链式存储结构中,我们又学习了循环链表与双向链表。另外,我们还学习了不用指针来描述链式存储的静态链表。

在学习总结线性表这张章时,发现了自己身上很多性格缺点。在写博客文章时,有些浮躁。好多东西,都是复制粘贴,不经过大脑思考。做人,学技术,一定要实在。不能贪图虚名,不能浮躁。

一定要有耐心,有毅力,有决心。在接下来的学习中,一定要锻炼自己这耐心、毅力、决心。

时间: 2024-10-13 15:54:06

数据结构与算法--线性表系列(循环链表、双向链表)的相关文章

数据结构与算法-线性表之双向链表

参考博客: http://www.cnblogs.com/skywang12345/p/3561803.html https://blog.csdn.net/howlaa/article/details/38513235 1.概述 线性表是一种线性结构,由数组.单项链表和双向链表组成,这里讲讨论双向链表的理论知识和实现代码. 双向链表和单项链表类似,双向链表由两个指针作为指针域,分别指向前驱节点和后驱节点.可以从任何节点开始向前或者向后删除.增加.查找节点. 双链表的示意图如下: 在插入节点的时

数据结构与算法—线性表详解

前言 通过前面数据结构与算法前导我么知道了数据结构的一些概念和重要性,那么我们今天总结下线性表相关的内容.当然,我用自己的理解解分享给大家. 其实说实话,可能很多人依然分不清线性表,顺序表,和链表之间的区别和联系! 线性表:逻辑结构, 就是对外暴露数据之间的关系,不关心底层如何实现. 顺序表.链表:物理结构,他是实现一个结构实际物理地址上的结构.比如顺序表就是用数组实现.而链表用指针完成主要工作.不同的结构在不同的场景有不同的区别. 对于java来说,大家都知道List接口类型,这就是逻辑结构,

数据结构与算法-线性表

近期在学习数据结构,反反复复已经看过几遍了,也做了一些练习题,但总感觉不记录一下,思路就不是很清晰,所以,从今天开始总结这段时间对数据结构的学习. 无论学习什么,基础知识都是最总要的,数据结构也不例外.线性表就是数据结构的基础,很多常见的数据结构都是基于线性表来实现的. 那么,什么是线性表呢?官方的定义是: 零个或多个数据元素的有限序列 可以从两个方面来理解线性表,首先它是一个序列,也就是其中的元素有先后顺序,其次是有限的,对于无线数列,也只能存在于理论数学中. 说了这么多,小结一下: 1)线性

数据结构与算法——线性表顺序存储结构

今天总结一下数据结构中的线性表中的顺序存储结构,这是一种比较简单的结构. 首先,看一下什么是线性表. 什么是线性表? 线性表是一种简单的数据结构,数据元素之间是一对一的关系,即除了第一个和最后一个元素外其余元素都是首尾相接的.元素的个数称为线性表的长度,长度为零则表示线性表为空. 什么是线性表的循序存储结构? 线性表中的顺序存储结构就是把线性表中的元素按逻辑次序依次存放在一组地址连续的存储空间中,也把这种线性表称为顺序表.根据顺序表的特点,通常是用数组来存储元素的. 下面就看具体的实现(C++)

数据结构与算法-线性表的实现(1)

今天来说说线性表的实现 这里以List作为例子 package com.ray.testobject; public class List { private int length; private Man[] array; public int getLength() { return length; } public void setLength(int length) { this.length = length; } public Man[] getArray() { return ar

数据结构与算法-线性表顺序存储结构删除操作的实现

这一章节我们来看一下线性表顺序存储结构删除操作的简单实现 package com.ray.testobject; public class Test { private Object[] list; public Object[] getList() { return list; } /** * 初始化list * * @param num * 元素个数 */ private void iniList(int num) { list = new Object[num]; for (int i =

数据结构与算法-线性表的定义与特点

1.线性表概念 线性表是由零个或者多个数据元素组成的有序的序列. 图示: 2.特点 2.1 有序 我们可以从上图看见,线性表里面的元素是一个挨着一个顺序排下去的,就像平常小朋友排队等放学的样子 2.2 允许零元素,也就是空表 2.3 第一个元素有且仅有一个后继,最后一个元素有且仅有一个前驱,其他元素有且仅有一个前驱以及有且仅有一个后继 我们可以从上图看见,线性表里面第一个元素a1,他没有前驱,只有一个a2的后继,最后一个元素an,只有一个前驱a(n-1),没有对应的后继,其他某个元素ai,它有且

数据结构与算法——线性表

1.概念 线性表可以看做一种抽象的概念,也可以作为一种抽象数据类型,一个线性表是某类元素的集合,还记录着元素之间的一种顺序关系.相当于一个抽象类,只做定义. 2.具体实现 1.顺序表 顺序表的基本实现方式非常简单:表中元素顺序存放在一片足够大的连续储存区间里,首元素存入储存区的开始位置,其余元素依次顺序存放,元素之间的逻辑关系通过元素在储存区里的物理位置表示(隐式表示元素之间的关系) 顺序表在内存中的布局方式: 1.顺序表基本操作的实现 创建和访问操作 创建空表时,需要分配一块元素储存,记录表的

java数据结构和算法------线性表(顺序表结构)

1 package iYou.neugle.list; 2 3 public class MySeqList<T> { 4 private int initMaxSize = 10; 5 private T[] list; 6 private int listLen = 0; 7 8 public MySeqList() { 9 this.Init(); 10 } 11 12 public MySeqList(int size) { 13 this.initMaxSize = size; 14