当前位置:首页 » 服务存储 » 双向链表存储方法
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

双向链表存储方法

发布时间: 2022-09-10 03:48:26

‘壹’ 循环链表和双向链表的区别是是什么

1、最后一个结点指针指向不同

在建立一个循环链表时,必须使其最后一个结点的指针指向表头结点,而不是像双向链表那样置为NULL。此种情况还用于在最后一个结点后插入一个新的结点。

2、判断链域值不同

在判断是否到表尾时,是判断该结点链域的值是否是表头结点,当链域值等于表头指针时,说明已到表尾。而非像单链表那样判断链域值是否为NULL。

3、访问方式:

循环链表:可以从任何一个结点开始,顺序向后访问到达任意结点

双向链表:可以从任何结点开始任意向前向后双向访问

4、操作:

循环链表:只能在当前结点后插入和删除

双链表:可以在当前结点前面或者后面插入,可以删除前趋和后继(包括结点自己)

5、存储
循环链表存储密度大于双链表

(1)双向链表存储方法扩展阅读

线性表的链式存储表示的特点是用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。因此,为了表示每个数据元素与其直接后继数据元素 之间的逻辑关系,对数据元素 来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。

由这两部分信息组成一个"结点"(如概述旁的图所示),表示线性表中一个数据元素。线性表的链式存储表示,有一个缺点就是要找一个数,必须要从头开始找起,十分麻烦。

根据情况,也可以自己设计链表的其它扩展。但是一般不会在边上附加数据,因为链表的点和边基本上是一一对应的(除了第一个或者最后一个节点,但是也不会产生特殊情况)。不过有一个特例是如果链表支持在链表的一段中把前和后指针反向,反向标记加在边上可能会更方便。

对于非线性的链表,可以参见相关的其他数据结构,例如树、图。另外有一种基于多个线性链表的数据结构:跳表,插入、删除和查找等基本操作的速度可以达到O(nlogn),和平衡二叉树一样。

其中存储数据元素信息的域称作数据域(设域名为data),存储直接后继存储位置的域称为指针域(设域名为next)。指针域中存储的信息又称做指针或链。

由分别表示,,…,的N 个结点依次相链构成的链表,称为线性表的链式存储表示,由于此类链表的每个结点中只包含一个指针域,故又称单链表或线性链表。

‘贰’ 单双向链表原理

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
1链表操作编辑
双向链表
双向链表
线性表的双向链表存储结构:

带头结点的双向循环链表的基本操作:

销毁双向循环链表L:

重置链表为空表:

验证是否为空表:

2元素操作编辑
计算表内元素个数

赋值:

查找元素:

查找元素前驱:

查找元素后继:

查找元素地址:

元素的插入:

元素的删除:

正序查找:

逆序查找:

3循环链表编辑
循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环。因此,从循环链表中的任何一个结点出发都能找到任何其他结点。循环链表的操作和单链表的操作基本一致,差别仅仅在于算法中的循环条件有所不同。

‘叁’ 怎样使双向链表头结点指向最后一个结点

1、双向链表的每个结点的存储结构为
typedef
struct
DuLNode
{
ElemType
data;
DuLNode
*
prior,*
next;//指向前驱结点和后继结点的指针
}DuLNode,*
DuLinkList;
2、头结点的前驱指针是指向链表的最后一个结点,
用头插法建立链表时,是在链表的头部增加结点,即最后一个结点始终是不变的
即新增结点(链表只有头结点时新增结点除外)不需要修改头结点的前驱指针,
使其指向最后一个结点
3、当链表只有头结点,即p->next
=
p->prior
=
p;
时(p是头结点)
添加链表的第一个结点,此时才需要修改头结点的前驱指针使其指向最后一个结点
s->data
=
e;//s是新增的第一个结点
s->prior
=
p;//p是头结点
s->next
=
p->next;
p->next->prior
=
s;
p->next
=
s;

‘肆’ 双向链表

#include <stdio.h>
typedef struct Link/*双向链表结构体*/
{
int data;
struct Link *lift;
struct Link *right;
}linkx,*linky;
linky Init();/*建立双向链表*/
void PrLink(linky p);/*输出双向链表*/
linky Sort(linky head);/*对双向链表排序*/
linky Swap(linky head,linky one,linky two);/*任意交换双向链表两个结点的地址*/
void main(void)
{
linky head;
head=Init();
head=Sort(head);
PrLink(head);
}
linky Init()/*建立链表*/
{
linky p,q,head;
int n=0;
head=p=q=(linky)malloc(sizeof(linkx));
clrscr();
printf("please input 10 num: ");
scanf("%d",&p->data);/*输入数据*/
head->lift=NULL;
n++;
while(n!=10)/*一直输入到规定的数字个数停止*/
{
q=p;
p=(linky)malloc(sizeof(linkx));
scanf("%d",&p->data);/*输入数据*/
q->right=p;
p->lift=q;
n++;
}
p->right=NULL;
return(head);
}
linky Swap(linky head,linky one,linky two)/*任意交换两个结点*/
{linky temp;
if(one->lift==NULL&&two->right==NULL)/*首和尾巴的交换*/
{
if(one->right==two)/*只有两个结点的情况下*/
{
two->right=one;
two->lift=NULL;
one->lift=two;
one->right=NULL;
head=two;
}
else/*有间隔的首尾交换*/
{
one->right->lift=two;
two->lift->right=one;
two->right=one->right;
one->lift=two->lift;
two->lift=one->right=NULL;
head=two;/*尾结点成为头结点*/
}
}
else if(two->right==NULL)/*尾和任意一个交换*/
{
if(one->right==two)/*交换最后两个结点*/
{
one->lift->right=two;
two->lift=one->lift;
two->right=one;
one->lift=two;
one->right=NULL;
}
else/*和前面其他结点交换*/
{
temp=two->lift;
temp->right=one;
one->lift->right=two;
one->right->lift=two;
two->lift=one->lift;
two->right=one->right;
one->lift=temp;
one->right=NULL;
}
}
else if(one->lift==NULL)/*头和任意一个交换*/
{
if(one->right==two)/*交换头两个结点*/
{
two->right->lift=one;
one->right=two->right;
one->lift=two;
two->right=one;
two->lift=NULL;
head=two;
}
else/*头结点和后面其他结点交换*/
{
temp=one->right;
temp->lift=two;
one->lift=two->lift;
one->right=two->right;
two->lift->right=one;
two->right->lift=one;
two->right=temp;
two->lift=NULL;
head=two;/*交换的结点成为头结点*/
}
}
else/*当中的任意两个交换*/
{
if(one->right==two)/*交换连在一起的两个结点*/
{
temp=one->lift;
one->lift->right=two;
one->right->lift=two;
one->lift=two;
one->right=two->right;
two->right->lift=one;
two->right=one;
two->lift=temp;
}
else/*交换隔开的两个结点*/
{
one->lift->right=two;
one->right->lift=two;
one->lift=two->lift;
temp=one->right;
one->right=two->right;
two->lift->right=one;
two->right->lift=one;
two->right=temp;
two->lift=one->lift;
}
}
return(head);
}
linky Sort(linky head)/*对链表排序*/
{
linky i,j,t,p;
int max;
p=head;
for(i=p;i->right!=NULL;i=i->right)/*用选择法的思想对这些结点排序*/
{
max=i->data;
for(j=i->right;j!=NULL;j=j->right)
if(j->data<max)
{
max=j->data;
t=j;
}
if(max!=i->data)/*如果没有找到比i小的结点*/
{
head=Swap(head,i,t);/*因为最终返回的是头结点,而头结点又有可能变化,所以每次头结点返回*/
i=t;
}
}
return(head);
}
void PrLink(linky p)/*输出链表*/
{
linky q;
printf("Now the link: ");
do
{
q=p;
printf("%d ",p->data);
p=p->right;
free(q);/*释放输出结点*/
}
while(p!=NULL);
getch();
}

‘伍’ 什么是链表 单链表;双向链表;循环链表 各是怎么进行存储和操作的

C语言中,链表的实质就是一种结构体类型。结构体清楚吧?结构体就是按一定方式组合的类型的集体,组成的一种类型。
而链表,实际上就是在这个结构体中,有这样一种变量,它们是指针,指向跟自己同种类型的结构体。当我们把a中的指针指向b,b中的指针指向c,...,就构成了一个单向的链表。
至于双向链表,是类似的,只不过一个节点同时指向了它前后的两个节点,适宜双向查找。
循环链表,与一般链表的区别,就是最后一个节点,又反过来指向了第一个节点。

‘陆’ 若某链表最常用的操作是在最后一个结点之后插入一个结点或者删除最后一个结点,则采用()存储方法最节省

线性表中最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素。

仅有尾指针的单循环链表,可以非常方便地找到尾结点,尾结点后面的第一个结点往往是头结点。对最后一个元素和第一个元素操作对带尾指针的单循环链表是非常方便的。



(6)双向链表存储方法扩展阅读:

线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的比如,循环链表逻辑层次上也是一种线性表存储。层次上属于链式存储,但是把最后一个数据元素的尾指针指向了首位结点。

若线性表需要频繁查找,很少进行插入和删除操作时,宜采用顺序存储结构。若需要频繁插入和删除时,宜采用单链表结构。

‘柒’ 双向链表必须从头节点开始遍历吗

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。

中文名
双向链表
亦称
双链表
类别
链表
特点
每个数据结点中都有两个指针
应用
孔子电路
快速
导航
元素的操作

双向链表模板

循环链表
链表的操作
线性表的双向链表存储结构:
typedef struct DuLNode
{
ElemType data;
struct DuLNode *prior,*next;
}DuLNode,*DuLinkList;
带头结点的双向循环链表的基本操作:
void InitList(DuLinkList L)
{ /* 产生空的双向循环链表L */
L=(DuLinkList)malloc(sizeof(DuLNode));
if(L)
L->next=L->prior=L;
else
exit(OVERFLOW);
}
销毁双向循环链表L:
void DestroyList(DuLinkList L)
{
DuLinkList q,p=L->next; /* p指向第一个结点 */
while(p!=L) /* p没到表头 */
{
q=p->next;
free(p);
p=q;
}
free(L);
L=NULL;
}
重置链表为空表:
void ClearList(DuLinkList L) /* 不改变L */
{ DuLinkList q,p=L->next; /* p指向第一个结点 */
while(p!=L) /* p没到表头 */
{
q=p->next;
free(p);
p=q;
}
L->next=L->prior=L; /*头结点的两个指针域均指向自身 */
}
验证是否为空表[1] :
Status ListEmpty(DuLinkList L)
{ /* 初始条件:线性表L已存在
if(L->next==L&&L->prior==L)
return TRUE;
else
return FALSE;
}
元素的操作
计算表内元素个数
int ListLength(DuLinkList L)
{ /* 初始条件:L已存在。操作结果: */
int i=0;
DuLinkList p=L->next; /* p指向第一个结点 */
while(p!=L) /* p没到表头 */
{
i++;
p=p->next;
}
return i;
}