『壹』 循環鏈表和雙向鏈表的區別是是什麼
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;
}