一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C語言單循環鏈表的表示與實現實例詳解

C語言單循環鏈表的表示與實現實例詳解

2021-01-21 14:01C語言程序設計 C/C++

這篇文章主要介紹了C語言單循環鏈表的表示與實現,對于學習數據結構與算法的朋友來說很有參考借鑒價值,需要的朋友可以參考下

1.概述:

對于一個循環鏈表來說,其首節點和末節點被連接在一起。這種方式在單向和雙向鏈表中皆可實現。要轉換一個循環鏈表,可以選擇開始于任意一個節點然后沿著列表的任一方向直到返回開始的節點。再來看另一種方法,循環鏈表可以被視為“無頭無尾”。這種列表很利于節約數據存儲緩存, 假定你在一個列表中有一個對象并且希望所有其他對象迭代在一個非特殊的排列下。

指向整個列表的指針可以被稱作訪問指針。

C語言單循環鏈表的表示與實現實例詳解
用單向鏈表構建的循環鏈表

循環鏈表中第一個節點之前就是最后一個節點,反之亦然循環鏈表的無邊界使得在這樣的鏈表上設計算法會比普通鏈表更加容易。對于新加入的節點應該是在第一個節點之前還是最后一個節點之后可以根據實際要求靈活處理,區別不大(詳見下面實例代碼)。當然,如果只會在最后插入數據(或者只會在之前),處理也是很容易的。
另外有一種模擬的循環鏈表,就是在訪問到最后一個節點之后的時候,手工的跳轉到第一個節點。訪問到第一個節點之前的時候也一樣。這樣也可以實現循環鏈表的功能,在直接用循環鏈表比較麻煩或者可能會出現問題的時候可以用。

2.程序實現:

?
1
2
3
4
5
6
7
/* c2-2.h 線性表的單鏈表存儲結構 */
 struct LNode
 {
  ElemType data;
  struct LNode *next;
 };
 typedef struct LNode *LinkList; /* 另一種定義LinkList的方法 */
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* 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;
 }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/* 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));
 }

 

延伸 · 閱讀

精彩推薦
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
主站蜘蛛池模板: 久久久久久久99精品免费观看 | 欧美夫妇野外交换hd高清版 | 国产亚洲毛片在线 | 给我一个黄色网址 | 成人中文字幕在线观看 | 好大好深好涨好烫还要 | 太紧太深了受不了黑人 | 精品国产乱码久久久久久免费流畅 | 大伊香蕉在线精品不卡视频 | a在线观看欧美在线观看 | 美女张开腿让我了一夜 | 四虎成人免费观看在线网址 | 99精品免费视频 | 午夜办公室在线观看高清电影 | 亚洲大片免费观看 | 国产精品久久久99 | 国产精品一二区 | 国产精品99在线观看 | 成人欧美1314www色视频 | 喜爱夜蒲2三级做爰 | 九九精品国产亚洲A片无码 九九99热久久999精品 | 禁忌高h | 秘书小说阿蛮 | 国产99青草全福视在线 | 午夜爱爱爱爱爽爽爽视频网站 | 高中生放荡日记高h娜娜 | 精品国产免费观看一区高清 | 成人在线一区二区 | 亚洲日本aⅴ片在线观看香蕉 | 私人黄色影院 | 亚洲天堂视频在线免费观看 | 办公室里被迫高h | 91精品国产色综合久久不卡蜜 | 青草午夜精品视频在线观看 | 欧美日韩一区不卡 | 毛片网站大全 | 欧美vpswindows | 亚洲欧美天堂 | 天堂a视频 | 欧美一二 | 美女任你模 |