C說話單輪回鏈表的表現與完成實例詳解。本站提示廣大學習愛好者:(C說話單輪回鏈表的表現與完成實例詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是C說話單輪回鏈表的表現與完成實例詳解正文
1.概述:
關於一個輪回鏈表來講,其首節點和小節點被銜接在一路。這類方法在單向和雙向鏈表中皆可完成。要轉換一個輪回鏈表,可以選擇開端於隨意率性一個節點然後沿著列表的任一偏向直到前往開端的節點。再來看另外一種辦法,輪回鏈表可以被視為“無頭無尾”。這類列表很利於勤儉數據存儲緩存, 假定你在一個列表中有一個對象而且願望一切其他對象迭代在一個非特別的分列下。
指向全部列表的指針可以被稱作拜訪指針。
用單向鏈表構建的輪回鏈表
輪回鏈表中第一個節點之前就是最初一個節點,反之亦然。輪回鏈表的無界限使得在如許的鏈表上設盤算法會比通俗鏈表加倍輕易。關於新參加的節點應當是在第一個節點之前照樣最初一個節點以後可以依據現實請求靈巧處置,差別不年夜(詳見上面實例代碼)。固然,假如只會在最初拔出數據(或許只會在之前),處置也是很輕易的。
別的有一種模仿的輪回鏈表,就是在拜訪到最初一個節點以後的時刻,手工的跳轉到第一個節點。拜訪到第一個節點之前的時刻也一樣。如許也能夠完成輪回鏈表的功效,在直接用輪回鏈表比擬費事或許能夠會湧現成績的時刻可以用。
2.法式完成:
/* c2-2.h 線性表的單鏈表存儲構造 */ struct LNode { ElemType data; struct LNode *next; }; typedef struct LNode *LinkList; /* 另外一種界說LinkList的辦法 */
/* bo2-4.c 設立尾指針的單輪回鏈表(存儲構造由c2-2.h界說)的12個根本操作 */ Status InitList_CL(LinkList *L) { /* 操作成果:結構一個空的線性表L */ *L=(LinkList)malloc(sizeof(struct LNode)); /* 發生頭結點,並使L指向此頭結點 */ if(!*L) /* 存儲分派掉敗 */ exit(OVERFLOW); (*L)->next=*L; /* 指針域指向頭結點 */ return OK; } Status DestroyList_CL(LinkList *L) { /* 操作成果:燒毀線性表L */ LinkList q,p=(*L)->next; /* p指向頭結點 */ while(p!=*L) /* 沒到表尾 */ { q=p->next; free(p); p=q; } free(*L); *L=NULL; return OK; } Status ClearList_CL(LinkList *L) /* 轉變L */ { /* 初始前提:線性表L已存在。操作成果:將L重置為空表 */ LinkList p,q; *L=(*L)->next; /* L指向頭結點 */ p=(*L)->next; /* p指向第一個結點 */ while(p!=*L) /* 沒到表尾 */ { q=p->next; free(p); p=q; } (*L)->next=*L; /* 頭結點指針域指向本身 */ return OK; } Status ListEmpty_CL(LinkList L) { /* 初始前提:線性表L已存在。操作成果:若L為空表,則前往TRUE,不然前往FALSE */ if(L->next==L) /* 空 */ return TRUE; else return FALSE; } int ListLength_CL(LinkList L) { /* 初始前提:L已存在。操作成果:前往L中數據元素個數 */ int i=0; LinkList p=L->next; /* p指向頭結點 */ while(p!=L) /* 沒到表尾 */ { i++; p=p->next; } return i; } Status GetElem_CL(LinkList L,int i,ElemType *e) { /* 當第i個元素存在時,其值賦給e並前往OK,不然前往ERROR */ int j=1; /* 初始化,j為計數器 */ LinkList p=L->next->next; /* p指向第一個結點 */ if(i<=0||i>ListLength_CL(L)) /* 第i個元素不存在 */ return ERROR; while(j<i) { /* 順指針向後查找,直到p指向第i個元素 */ p=p->next; j++; } *e=p->data; /* 取第i個元素 */ return OK; } int LocateElem_CL(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType)) { /* 初始前提:線性表L已存在,compare()是數據元素剖斷函數 */ /* 操作成果:前往L中第1個與e知足關系compare()的數據元素的位序。 */ /* 若如許的數據元素不存在,則前往值為0 */ int i=0; LinkList p=L->next->next; /* p指向第一個結點 */ while(p!=L->next) { i++; if(compare(p->data,e)) /* 知足關系 */ return i; p=p->next; } return 0; } Status PriorElem_CL(LinkList L,ElemType cur_e,ElemType *pre_e) { /* 初始前提:線性表L已存在 */ /* 操作成果:若cur_e是L的數據元素,且不是第一個,則用pre_e前往它的先驅, */ /* 不然操作掉敗,pre_e無界說 */ LinkList q,p=L->next->next; /* p指向第一個結點 */ q=p->next; while(q!=L->next) /* p沒到表尾 */ { if(q->data==cur_e) { *pre_e=p->data; return TRUE; } p=q; q=q->next; } return FALSE; } Status NextElem_CL(LinkList L,ElemType cur_e,ElemType *next_e) { /* 初始前提:線性表L已存在 */ /* 操作成果:若cur_e是L的數據元素,且不是最初一個,則用next_e前往它的後繼, */ /* 不然操作掉敗,next_e無界說 */ LinkList p=L->next->next; /* p指向第一個結點 */ while(p!=L) /* p沒到表尾 */ { if(p->data==cur_e) { *next_e=p->next->data; return TRUE; } p=p->next; } return FALSE; } Status ListInsert_CL(LinkList *L,int i,ElemType e) /* 轉變L */ { /* 在L的第i個地位之前拔出元素e */ LinkList p=(*L)->next,s; /* p指向頭結點 */ int j=0; if(i<=0||i>ListLength_CL(*L)+1) /* 沒法在第i個元素之前拔出 */ return ERROR; while(j<i-1) /* 尋覓第i-1個結點 */ { p=p->next; j++; } s=(LinkList)malloc(sizeof(struct LNode)); /* 生成新結點 */ s->data=e; /* 拔出L中 */ s->next=p->next; p->next=s; if(p==*L) /* 轉變尾結點 */ *L=s; return OK; } Status ListDelete_CL(LinkList *L,int i,ElemType *e) /* 轉變L */ { /* 刪除L的第i個元素,並由e前往其值 */ LinkList p=(*L)->next,q; /* p指向頭結點 */ int j=0; if(i<=0||i>ListLength_CL(*L)) /* 第i個元素不存在 */ return ERROR; while(j<i-1) /* 尋覓第i-1個結點 */ { p=p->next; j++; } q=p->next; /* q指向待刪除結點 */ p->next=q->next; *e=q->data; if(*L==q) /* 刪除的是表尾元素 */ *L=p; free(q); /* 釋放待刪除結點 */ return OK; } Status ListTraverse_CL(LinkList L,void(*vi)(ElemType)) { /* 初始前提:L已存在。操作成果:順次對L的每一個數據元素挪用函數vi()。一旦vi()掉敗,則操作掉敗 */ LinkList p=L->next->next; while(p!=L->next) { vi(p->data); p=p->next; } printf("\n"); return OK; }
/* main2-4.c 單輪回鏈表,磨練bo2-4.c的主法式 */ #include"c1.h" typedef int ElemType; #include"c2-2.h" #include"bo2-4.c" Status compare(ElemType c1,ElemType c2) { if(c1==c2) return TRUE; else return FALSE; } void visit(ElemType c) { printf("%d ",c); } void main() { LinkList L; ElemType e; int j; Status i; i=InitList_CL(&L); /* 初始化單輪回鏈表L */ printf("初始化單輪回鏈表L i=%d (1:初始化勝利)\n",i); i=ListEmpty_CL(L); printf("L能否空 i=%d(1:空 0:否)\n",i); ListInsert_CL(&L,1,3); /* 在L中順次拔出3,5 */ ListInsert_CL(&L,2,5); i=GetElem_CL(L,1,&e); j=ListLength_CL(L); printf("L中數據元素個數=%d,第1個元素的值為%d。\n",j,e); printf("L中的數據元素順次為:"); ListTraverse_CL(L,visit); PriorElem_CL(L,5,&e); /* 求元素5的先驅 */ printf("5後面的元素的值為%d。\n",e); NextElem_CL(L,3,&e); /* 求元素3的後繼 */ printf("3前面的元素的值為%d。\n",e); printf("L能否空 %d(1:空 0:否)\n",ListEmpty_CL(L)); j=LocateElem_CL(L,5,compare); if(j) printf("L的第%d個元素為5。\n",j); else printf("不存在值為5的元素\n"); i=ListDelete_CL(&L,2,&e); printf("刪除L的第2個元素:\n"); if(i) { printf("刪除的元素值為%d,如今L中的數據元素順次為:",e); ListTraverse_CL(L,visit); } else printf("刪除不勝利!\n"); printf("清空L:%d(1: 勝利)\n",ClearList_CL(&L)); printf("清空L後,L能否空:%d(1:空 0:否)\n",ListEmpty_CL(L)); printf("燒毀L:%d(1: 勝利)\n",DestroyList_CL(&L)); }