1. 程式人生 > >線性表鏈式存儲

線性表鏈式存儲

位置 頭插 回收 操作 sizeof .data link 鏈式 ++

  1 #include "stdio.h"
  2 #include "string.h"
  3 #include "ctype.h"
  4 #include "stdlib.h"
  5 #include "math.h"
  6 #include "time.h"
  7 
  8 #define OK 1
  9 #define ERROR 0
 10 #define TRUE 1
 11 #define FALSE 0
 12 
 13 #define MAXSIZE 20 /* 存儲空間初始分配量 */
 14 
 15 typedef int Status;/* Status是函數的類型,其值是函數結果狀態代碼,如OK等 
*/ 16 typedef int ElemType;/* ElemType類型根據實際情況而定,這裏假設為int */ 17 18 19 Status visit(ElemType c) 20 { 21 printf("%d ",c); 22 return OK; 23 } 24 25 typedef struct Node 26 { 27 ElemType data; 28 struct Node *next; 29 }Node; 30 typedef struct Node *LinkList; /* 定義LinkList */ 31
32 /* 初始化順序線性表 */ 33 Status InitList(LinkList *L) 34 { 35 *L=(LinkList)malloc(sizeof(Node)); /* 產生頭結點,並使L指向此頭結點 */ 36 if(!(*L)) /* 存儲分配失敗 */ 37 return ERROR; 38 (*L)->next=NULL; /* 指針域為空 */ 39 40 return OK; 41 } 42 43 /* 初始條件:順序線性表L已存在。操作結果:若L為空表,則返回TRUE,否則返回FALSE
*/ 44 Status ListEmpty(LinkList L) 45 { 46 if(L->next) 47 return FALSE; 48 else 49 return TRUE; 50 } 51 52 /* 初始條件:順序線性表L已存在。操作結果:將L重置為空表 */ 53 Status ClearList(LinkList *L) 54 { 55 LinkList p,q; 56 p=(*L)->next; /* p指向第一個結點 */ 57 while(p) /* 沒到表尾 */ 58 { 59 q=p->next; 60 free(p); 61 p=q; 62 } 63 (*L)->next=NULL; /* 頭結點指針域為空 */ 64 return OK; 65 } 66 67 /* 初始條件:順序線性表L已存在。操作結果:返回L中數據元素個數 */ 68 int ListLength(LinkList L) 69 { 70 int i=0; 71 LinkList p=L->next; /* p指向第一個結點 */ 72 while(p) 73 { 74 i++; 75 p=p->next; 76 } 77 return i; 78 } 79 80 /* 初始條件:順序線性表L已存在,1≤i≤ListLength(L) */ 81 /* 操作結果:用e返回L中第i個數據元素的值 */ 82 Status GetElem(LinkList L,int i,ElemType *e) 83 { 84 int j; 85 LinkList p; /* 聲明一結點p */ 86 p = L->next; /* 讓p指向鏈表L的第一個結點 */ 87 j = 1; /* j為計數器 */ 88 while (p && j<i) /* p不為空或者計數器j還沒有等於i時,循環繼續 */ 89 { 90 p = p->next; /* 讓p指向下一個結點 */ 91 ++j; 92 } 93 if ( !p || j>i ) 94 return ERROR; /* 第i個元素不存在 */ 95 *e = p->data; /* 取第i個元素的數據 */ 96 return OK; 97 } 98 99 /* 初始條件:順序線性表L已存在 */ 100 /* 操作結果:返回L中第1個與e滿足關系的數據元素的位序。 */ 101 /* 若這樣的數據元素不存在,則返回值為0 */ 102 int LocateElem(LinkList L,ElemType e) 103 { 104 int i=0; 105 LinkList p=L->next; 106 while(p) 107 { 108 i++; 109 if(p->data==e) /* 找到這樣的數據元素 */ 110 return i; 111 p=p->next; 112 } 113 114 return 0; 115 } 116 117 118 /* 初始條件:順序線性表L已存在,1≤i≤ListLength(L), */ 119 /* 操作結果:在L中第i個位置之前插入新的數據元素e,L的長度加1 */ 120 Status ListInsert(LinkList *L,int i,ElemType e) 121 { 122 int j; 123 LinkList p,s; 124 p = *L; 125 j = 1; 126 while (p && j < i) /* 尋找第i個結點 */ 127 { 128 p = p->next; 129 ++j; 130 } 131 if (!p || j > i) 132 return ERROR; /* 第i個元素不存在 */ 133 s = (LinkList)malloc(sizeof(Node)); /* 生成新結點(C語言標準函數) */ 134 s->data = e; 135 s->next = p->next; /* 將p的後繼結點賦值給s的後繼 */ 136 p->next = s; /* 將s賦值給p的後繼 */ 137 return OK; 138 } 139 140 /* 初始條件:順序線性表L已存在,1≤i≤ListLength(L) */ 141 /* 操作結果:刪除L的第i個數據元素,並用e返回其值,L的長度減1 */ 142 Status ListDelete(LinkList *L,int i,ElemType *e) 143 { 144 int j; 145 LinkList p,q; 146 p = *L; 147 j = 1; 148 while (p->next && j < i) /* 遍歷尋找第i個元素 */ 149 { 150 p = p->next; 151 ++j; 152 } 153 if (!(p->next) || j > i) 154 return ERROR; /* 第i個元素不存在 */ 155 q = p->next; 156 p->next = q->next; /* 將q的後繼賦值給p的後繼 */ 157 *e = q->data; /* 將q結點中的數據給e */ 158 free(q); /* 讓系統回收此結點,釋放內存 */ 159 return OK; 160 } 161 162 /* 初始條件:順序線性表L已存在 */ 163 /* 操作結果:依次對L的每個數據元素輸出 */ 164 Status ListTraverse(LinkList L) 165 { 166 LinkList p=L->next; 167 while(p) 168 { 169 visit(p->data); 170 p=p->next; 171 } 172 printf("\n"); 173 return OK; 174 } 175 176 /* 隨機產生n個元素的值,建立帶表頭結點的單鏈線性表L(頭插法) */ 177 void CreateListHead(LinkList *L, int n) 178 { 179 LinkList p; 180 int i; 181 srand(time(0)); /* 初始化隨機數種子 */ 182 *L = (LinkList)malloc(sizeof(Node)); 183 (*L)->next = NULL; /* 先建立一個帶頭結點的單鏈表 */ 184 for (i=0; i<n; i++) 185 { 186 p = (LinkList)malloc(sizeof(Node)); /* 生成新結點 */ 187 p->data = rand()%100+1; /* 隨機生成100以內的數字 */ 188 p->next = (*L)->next; 189 (*L)->next = p; /* 插入到表頭 */ 190 } 191 } 192 193 /* 隨機產生n個元素的值,建立帶表頭結點的單鏈線性表L(尾插法) */ 194 void CreateListTail(LinkList *L, int n) 195 { 196 LinkList p,r; 197 int i; 198 srand(time(0)); /* 初始化隨機數種子 */ 199 *L = (LinkList)malloc(sizeof(Node)); /* L為整個線性表 */ 200 r=*L; /* r為指向尾部的結點 */ 201 for (i=0; i<n; i++) 202 { 203 p = (Node *)malloc(sizeof(Node)); /* 生成新結點 */ 204 p->data = rand()%100+1; /* 隨機生成100以內的數字 */ 205 r->next=p; /* 將表尾終端結點的指針指向新結點 */ 206 r = p; /* 將當前的新結點定義為表尾終端結點 */ 207 } 208 r->next = NULL; /* 表示當前鏈表結束 */ 209 } 210 211 int main() 212 { 213 LinkList L; 214 ElemType e; 215 Status i; 216 int j,k; 217 i=InitList(&L); 218 printf("初始化L後:ListLength(L)=%d\n",ListLength(L)); 219 for(j=1;j<=1;j++) 220 i=ListInsert(&L,1,j); 221 printf("在L的表頭依次插入1~5後:L.data="); 222 ListTraverse(L); 223 224 printf("ListLength(L)=%d \n",ListLength(L)); 225 i=ListEmpty(L); 226 printf("L是否空:i=%d(1:是 0:否)\n",i); 227 // 228 i=ClearList(&L); 229 printf("清空L後:ListLength(L)=%d\n",ListLength(L)); 230 i=ListEmpty(L); 231 printf("L是否空:i=%d(1:是 0:否)\n",i); 232 233 for(j=1;j<=10;j++) 234 ListInsert(&L,j,j); 235 printf("在L的表尾依次插入1~10後:L.data="); 236 ListTraverse(L); 237 238 printf("ListLength(L)=%d \n",ListLength(L)); 239 240 ListInsert(&L,1,0); 241 printf("在L的表頭插入0後:L.data="); 242 ListTraverse(L); 243 printf("ListLength(L)=%d \n",ListLength(L)); 244 245 GetElem(L,5,&e); 246 printf("第5個元素的值為:%d\n",e); 247 for(j=3;j<=4;j++) 248 { 249 k=LocateElem(L,j); 250 if(k) 251 printf("第%d個元素的值為%d\n",k,j); 252 else 253 printf("沒有值為%d的元素\n",j); 254 } 255 256 257 k=ListLength(L); /* k為表長 */ 258 for(j=k+1;j>=k;j--) 259 { 260 i=ListDelete(&L,j,&e); /* 刪除第j個數據 */ 261 if(i==ERROR) 262 printf("刪除第%d個數據失敗\n",j); 263 else 264 printf("刪除第%d個的元素值為:%d\n",j,e); 265 } 266 printf("依次輸出L的元素:"); 267 ListTraverse(L); 268 269 j=5; 270 ListDelete(&L,j,&e); /* 刪除第5個數據 */ 271 printf("刪除第%d個的元素值為:%d\n",j,e); 272 // 273 printf("依次輸出L的元素:"); 274 ListTraverse(L); 275 // 276 i=ClearList(&L); 277 printf("\n清空L後:ListLength(L)=%d\n",ListLength(L)); 278 CreateListHead(&L,20); 279 printf("整體創建L的元素(頭插法):"); 280 ListTraverse(L); 281 // 282 i=ClearList(&L); 283 printf("\n刪除L後:ListLength(L)=%d\n",ListLength(L)); 284 CreateListTail(&L,20); 285 printf("整體創建L的元素(尾插法):"); 286 ListTraverse(L); 287 288 289 return 0; 290 }

線性表鏈式存儲