當前位置:首頁 » 服務存儲 » 循環鏈表探索存儲
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

循環鏈表探索存儲

發布時間: 2022-06-09 05:13:57

『壹』 有人說,採用循環鏈表作為存儲結構的隊列就是循環隊列,這種說法有道理么

沒有道理,

『貳』 循環鏈表存儲列隊時,為什麼下標為0的存儲單元不用

既然是用鏈表怎麼會有下標?不是指針么?如果你說的是頭結點,當然不能用,不然怎麼區分你隊列的頭尾。。。
隊列是先進先出,棧是先進後出,都有push和pop操作

『叄』 單向循環鏈表存儲結構實現約瑟夫環

# include <stdio.h>
# include <malloc.h>
struct stu
{
int num;
struct stu *next;
};
int m,n;struct stu *p,*q,*s;
struct stu *create()
{
struct stu *head,*s1,*r;
int i;

head=NULL;
for(i=1;i<=n;i++)
{
s1=(struct stu *)malloc(sizeof(struct stu));
s1->num =i;
if(head==NULL)head=s1;
else r->next =s1;
r=s1;
}
if(r) r->next =head;
return head;
}
struct stu * get_index(struct stu *head,int k)
{
int j=1;
if (k<1)
{
printf ("輸入錯誤\n");
return NULL;
}
s=head;
while (s && j<k)
{
s=s->next ;j++;
}
return s;
}
void f1 (struct stu *head,struct stu *h)
{
int x,i;
x=m/2;
p=h;
i=1;printf ("依次出列的人的編號為:");
while (p->next!=p)
{
q=p->next;
for (i=1;i<x;i++)
{p=q->next;q=p->next;}
p->next =q->next ;
printf ("%d ",q->num);
free(q);
p=p->next ;
}
printf ("最後剩下的人的編號為%d\n",p->num );
}
void f2 (struct stu *head,struct stu *h)
{
int i,x;
x=m/2;
i=1;
p=h;
printf ("依次出列的人的編號為:");
do
{
for (i=1;i<=x;i++)
{q=p->next ;p=q->next ;}
q->next =p->next ;
printf ("%d ",p->num);
free(p);
p=q->next ;
}
while (q->next!=q);
printf ("\n最後剩下的人的編號為%d\n",q->num);
}
void main ()
{
int k;
struct stu *head,*h;
printf ("請輸入總人數:");
scanf ("%d",&n);
printf ("請輸入退出圈子的人的編號:");
scanf("%d",&m);
printf ("請輸入開始報數的人的編號:");
scanf ("%d",&k);
head=create ();
h=get_index(head,k);
if (m%2==0) f1(head,h);
else f2(head,h);
}

『肆』 C語言二級考試循環鏈表是循環隊列的鏈式存儲結構

循環隊列本身是一種順序存儲結構,而循環列表是一種鏈式存儲結構。兩者之間是平級關系。

線性鏈表是線性表的鏈式存儲結構,包括單鏈表,雙鏈表,循環鏈表等。

隊列的順序存儲結構一般採用循環隊列的形式。

循環隊列的操作是按數組取摸運算的,所以是順序存儲,而循環鏈表本身就是收尾相連的,所以循環鏈表不是循環隊列,兩種不同的存儲結構,雖然實現的功能是一樣的,實現循環兩種方式 順序存儲就是循環隊列,鏈式存儲就是循環鏈表。

(4)循環鏈表探索存儲擴展閱讀:

1、比順序存儲結構的存儲密度小(鏈式存儲結構中每個結點都由數據域與指針域兩部分組成,相比順序存儲結構增加了存儲空間)。

2、邏輯上相鄰的節點物理上不必相鄰。

3、插入、刪除靈活 (不必移動節點,只要改變節點中的指針)。

4、查找節點時鏈式存儲要比順序存儲慢。

5、每個節點是由數據域和指針域組成。

6、由於簇是隨機分配的,這也使數據刪除後覆蓋幾率降低,恢復可能提高。

『伍』 循環鏈表和雙向鏈表的區別是是什麼

1、最後一個結點指針指向不同

在建立一個循環鏈表時,必須使其最後一個結點的指針指向表頭結點,而不是像雙向鏈表那樣置為NULL。此種情況還用於在最後一個結點後插入一個新的結點。

2、判斷鏈域值不同

在判斷是否到表尾時,是判斷該結點鏈域的值是否是表頭結點,當鏈域值等於表頭指針時,說明已到表尾。而非像單鏈表那樣判斷鏈域值是否為NULL。

3、訪問方式:

循環鏈表:可以從任何一個結點開始,順序向後訪問到達任意結點

雙向鏈表:可以從任何結點開始任意向前向後雙向訪問

4、操作:

循環鏈表:只能在當前結點後插入和刪除

雙鏈表:可以在當前結點前面或者後面插入,可以刪除前趨和後繼(包括結點自己)

5、存儲:
循環鏈表存儲密度大於雙鏈表

(5)循環鏈表探索存儲擴展閱讀

線性表的鏈式存儲表示的特點是用一組任意的存儲單元存儲線性表的數據元素(這組存儲單元可以是連續的,也可以是不連續的)。因此,為了表示每個數據元素與其直接後繼數據元素 之間的邏輯關系,對數據元素 來說,除了存儲其本身的信息之外,還需存儲一個指示其直接後繼的信息(即直接後繼的存儲位置)。

由這兩部分信息組成一個"結點"(如概述旁的圖所示),表示線性表中一個數據元素。線性表的鏈式存儲表示,有一個缺點就是要找一個數,必須要從頭開始找起,十分麻煩。

根據情況,也可以自己設計鏈表的其它擴展。但是一般不會在邊上附加數據,因為鏈表的點和邊基本上是一一對應的(除了第一個或者最後一個節點,但是也不會產生特殊情況)。不過有一個特例是如果鏈表支持在鏈表的一段中把前和後指針反向,反向標記加在邊上可能會更方便。

對於非線性的鏈表,可以參見相關的其他數據結構,例如樹、圖。另外有一種基於多個線性鏈表的數據結構:跳錶,插入、刪除和查找等基本操作的速度可以達到O(nlogn),和平衡二叉樹一樣。

其中存儲數據元素信息的域稱作數據域(設域名為data),存儲直接後繼存儲位置的域稱為指針域(設域名為next)。指針域中存儲的信息又稱做指針或鏈。

由分別表示,,…,的N 個結點依次相鏈構成的鏈表,稱為線性表的鏈式存儲表示,由於此類鏈表的每個結點中只包含一個指針域,故又稱單鏈表或線性鏈表。

『陸』 循環鏈表的存儲空間是連續的,為什麼錯

循環鏈表是由單鏈表的最後一個結點指針不指向null,而是指向頭結點而成。因此我們分析單鏈表的存儲結構。
單鏈表是通過一組任意的存儲單元存儲線性表中的元素的。 這是單鏈表的定義。單鏈表的存儲單元是任意的!! 沒有說要連續。

連續的只有順序表!順序表!順序表!
順序表是用一組地址連續!!的存儲單元,依次!!存儲線性表中的數據元素。

而循環鏈表 它的定義前面已經說了,只是最後一個結點不為null(空),而是指向鏈表的頭結點哦。
循環鏈表也是鏈表,鏈表的存儲空間不一定連續的。
但是順序表是一定連續的存儲空間哦。

『柒』 線性表的雙向循環鏈表存儲結構及其上的基本操作,至少要求實現10個以上的基本操作

/*
下面有結果
*/
# include <stdio.h>
# include <stdlib.h>
# define TRUE 1
# define FALSE 0
# define OK 1
# define ERROR 0
typedef int Status;
typedef int ElemType;
typedef struct DuLNode
{
ElemType data;
DuLNode * prior,* next;
}DuLNode,* DuLinkList;
Status equal(ElemType c1, ElemType c2)
{
if (c1 == c2)
{
return TRUE;
}
else
{
return FALSE;
}
}
int comp(ElemType a, ElemType b)
{
if (a == b)
{
return 0;
}
else
{
return (a-b)/abs(a-b);
}
}
void print(ElemType c)
{
printf("%d ",c);
}
void print2(ElemType c)
{
printf("%c ",c);
}
void print1(ElemType * c)
{
printf("%d ",* c);
}
//產生空的雙向循環鏈表L,
void InitList(DuLinkList * L)
{
* L = (DuLinkList)malloc(sizeof(DuLNode));
if (* L)
{
(* L)->next = (* L)->prior = * L;
}
else
{
exit(0);
}
}
//銷毀雙向循環鏈表L
void DestroyList(DuLinkList * L)
{
DuLinkList q,p = (* L)->next;
while (p != (* L))
{
q = p->next;
free(p);
p = q;
}
free(* L);
(* L) = NULL;
}
//將L重置為空表
void ClearList(DuLinkList L)
{
DuLinkList q,p = L->next;
while (p != L)
{
q = p->next;
free(p);
p = q;
}
L->next = L->prior = L;
}
//線性表L已經存在,如果L為空表,則返回TRUE,否則返回FALSE
Status ListEmpty(DuLinkList L)
{
if (L->next==L && L->prior==L)
{
return TRUE;
}
else
{
return FALSE;
}
}
//L已經存在,返回L中數據元素的個數
int ListLength(DuLinkList L)
{
int i = 0;
DuLinkList p = L->next;
while (p != L)
{
i++;
p = p->next;
}
return i;
}
//當第i個元素存在時,將其值賦給e,並返回OK,否則返回FALSE
Status GetElem(DuLinkList L,int i,ElemType * e)
{
int j = 1;
DuLinkList p = L->next;
while (p!=L && j<i)
{
p = p->next;
j++;
}
if (p==L || j>i)
{
return ERROR;
}
* e = p->data;
return OK;
}

//返回L中第一個與e滿足關系compare的數據元素的位序
//如果這樣的元素不存在,則返回值為0
int LocateElem(DuLinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
{
int i = 0;
DuLinkList p = L->next;
while (p != L)
{
i++;
if (compare(p->data,e))
{
return i;
}
p = p->next;
}
return 0;
}
//如果cur_e是L的數據元素,並且不是第一個,則用pre_e返回它的前驅
Status PriorElem(DuLinkList L,ElemType cur_e,ElemType * pre_e)
{
DuLinkList p = L->next->next;//p指向第二個元素
while (p != L)
{
if (p->data == cur_e)
{
* pre_e = p->prior->data;
return TRUE;
}
p = p->next;
}
return FALSE;
}
//如果cur_e是L的數據元素,並且不是最後一個,
//則用next_e返回它的後繼元素,否則操作失敗,next_e沒有定義
Status NextElem(DuLinkList L,ElemType cur_e,ElemType * next_e)
{
DuLinkList p = L->next->next;
while (p != L)
{
if (p->prior->data == cur_e)
{
* next_e = p->data;
return TRUE;
}
p = p->next;
}
return FALSE;
}
//返回雙向鏈表L的第i個元素的地址,如果i = 0,則返回頭結點的地址
//如果第i個元素不存在,則返回NULL
DuLinkList GetElemP(DuLinkList L,int i)
{
int j;
DuLinkList p = L;
if (i<0 || i>ListLength(L))
{
return NULL;
}
for (j=1; j<=i; ++j)
{
p = p->next;
}
return p;
}
//在帶頭結點的雙鏈循環線性表L中的第i個位置之前插入元素e,
Status ListInsert(DuLinkList L,int i,ElemType e)
{
DuLinkList p,s;
if (i<1 || i>ListLength(L)+1)
{
return ERROR;
}
p = GetElemP(L,i-1);
if (!p)
{
return ERROR;
}
s = (DuLinkList)malloc(sizeof(DuLNode));
if (!s)
{
return 0;
}
s->data = e;
s->prior = p;
s->next = p->next;
p->next->prior = s;
p->next = s;
return OK;
}
//在帶頭結點的雙鏈循環線性表L中,刪除其第i個元素,
Status ListDelete(DuLinkList L,int i,ElemType * e)
{
DuLinkList p;
if (i<1)
{
return ERROR;
}
p = GetElemP(L,i);
if (!p)
{
return ERROR;
}
* e = p->data;
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
return OK;
}
//由雙鏈循環線性表L的頭結點出發,正序對每個元素調用函數visit
//主要是正序
void ListTraverse(DuLinkList L,void(*visit)(ElemType))
{
DuLinkList p = L->next;//p指向頭結點
while (p != L)
{
visit(p->data);
p = p->next;
}
printf("\n");
}
//從雙鏈循環線性表L的頭結點出發,逆序對每個數據元素調用函數visit
void ListTraverseBack(DuLinkList L,void(*visit)(ElemType))
{
DuLinkList p = L->prior;
while (p != L)
{
visit(p->data);
p = p->prior;
}
printf("\n");
}
int main(void)
{
DuLinkList L;
int i,n;
Status j;
ElemType e;
InitList(&L);
for (i=1; i<=5; ++i)
{
ListInsert(L,i,i);
}
printf("正序輸出鏈表:");
ListTraverse(L,print);
printf("逆序輸出鏈表:");
ListTraverseBack(L,print);
n = 2;
ListDelete(L,n,&e);
printf("刪除第%d個結點,其值是%d,其餘的結點是(正序輸出):\n",n,e);
ListTraverse(L,print);
printf("鏈表的元素個數為%d\n",ListLength(L));
printf("鏈表是否空:%d(1:空 0:非空)\n",ListEmpty(L));
ClearList(L);
printf("清空後,鏈表空嗎:%d(1:空 0:非空)\n",ListEmpty(L));
printf("重新插入5個元素:\n然後正序遍歷:");
for (i=1; i<=5; ++i)
{
ListInsert(L,i,i);
}
ListTraverse(L,print);//正序輸出
n = 3;
j = GetElem(L,n,&e);
if (j)
{
printf("鏈表的第%d個元素的值為%d\n",n,e);
}
else
{
printf("不存在第%d個元素\n",n);
}
n = 4;
i = LocateElem(L,n,equal);
if (i)
{
printf("L中第%d個元素是%d\n",i,n);
}
else
{
printf("L中沒有元素%d\n",n);
}
j = PriorElem(L,n,&e);
if (j)
{
printf("%d的前驅是%d\n",n,e);
}
else
{
printf("%d沒有前驅\n");
}
j = NextElem(L,n,&e);
if (j)
{
printf("%d的後繼是%d\n",n,e);
}
else
{
printf("%d沒有後繼元素\n");
}
DestroyList(&L);
return 0;
}
/*
在vc++6.0中的輸出結果:
------------------------
正序輸出鏈表:1 2 3 4 5
逆序輸出鏈表:5 4 3 2 1
刪除第2個結點,其值是2,其餘的結點是(正序輸出):
1 3 4 5
鏈表的元素個數為4
鏈表是否空:0(1:空 0:非空)
清空後,鏈表空嗎:1(1:空 0:非空)
重新插入5個元素:
然後正序遍歷:1 2 3 4 5
鏈表的第3個元素的值為3
L中第4個元素是4
4的前驅是3
4的後繼是5
Press any key to continue
------------------------------
*/

『捌』 雙向循環鏈表的主要優點

雙向鏈表的每個數據結點中都有兩個指針,分別指向直接後繼和直接前驅。所以,從雙向鏈表中的任意一個結點開始,都可以很方便地訪問它的前驅結點和後繼結點。一般我們都構造雙向循環鏈表。

單鏈表的缺點是只能往前,不能後退,雖然有循環單鏈表,但後退的成本還是很高的,需要跑一圈。在這個時候呢,雙向鏈表就應運而生了,再加上循環即雙向循環鏈表就更加不錯了。所謂雙向鏈表只不過是添加了一個指向前驅結點的指針,雙向循環鏈表是將最後一個結點的後繼指針指向頭結點。

(8)循環鏈表探索存儲擴展閱讀:

循環鏈表是一種鏈式存儲結構,它的最後一個結點指向頭結點,形成一個環。因此,從循環鏈表中的任何一個結點出發都能找到任何其他結點。循環鏈表的操作和單鏈表的操作基本一致,差別僅僅在於演算法中的循環條件有所不同。

單向鏈表(單鏈表)其特點是鏈表的鏈接方向是單向的,對鏈表的訪問要通過順序讀取從頭部開始。 通過指針連接起來,但是只能單向遍歷的內存塊。由於它是單向的,或者說不可逆的,所以我們可以把它比作人生:小學->中學->大學->工作->養老。

『玖』 循環鏈表的主要優點是

循環鏈表的特點是無須增加存儲量,僅對表的鏈接方式稍作改變,即可使得表處理更加方便靈活。

(1)單循環鏈表——在單鏈表中,將終端結點的指針域NULL改為指向表頭結點或開始結點即可。

(2)多重鏈的循環鏈表——將表中結點鏈在多個環上。

注意:

①循環鏈表中沒有NULL指針。涉及遍歷操作時,其終止條件就不再是像非循環鏈表那樣判別p或p->next是否為空,而是判別它們是否等於某一指定指針,如頭指針或尾指針等。

②在單鏈表中,從一已知結點出發,只能訪問到該結點及其後續結點,無法找到該結點之前的其它結點。而在單循環鏈表中,從任一結點出發都可訪問到表中所有結點,這一優點使某些運算在單循環鏈表上易於實現。

『拾』 什麼是鏈表 單鏈表;雙向鏈表;循環鏈表 各是怎麼進行存儲和操作的

C語言中,鏈表的實質就是一種結構體類型。結構體清楚吧?結構體就是按一定方式組合的類型的集體,組成的一種類型。
而鏈表,實際上就是在這個結構體中,有這樣一種變數,它們是指針,指向跟自己同種類型的結構體。當我們把a中的指針指向b,b中的指針指向c,...,就構成了一個單向的鏈表。
至於雙向鏈表,是類似的,只不過一個節點同時指向了它前後的兩個節點,適宜雙向查找。
循環鏈表,與一般鏈表的區別,就是最後一個節點,又反過來指向了第一個節點。