【ADT】鏈表的基本C語言實現


什么是抽象數據類型?
首先,這一概念是軟件開發人員在力求編寫的代碼健壯、易維護且可以復用的過程中產生的。
英文是AbstractData Type。有人將其比作“抽象”的牆壁,“它將接口和實現明確分開,所以用戶只看到接口,因此不需要參與實現。”構建者則着力實現ADT接口。ADT成為了雙方的契約,這使得代碼更容易維護。

接口:接口是把公共的方法和屬性組合起來以封裝特定功能的一個集合。

創建linked list.h頭文件

 1 #ifndef LIST_H_
 2 #define LIST_H_
 3 #include <stdbool.h>
 4 #define TSIZE 45
 5 
 6 typedef struct book{ // 建立包含元素屬性的item結構體
 7     char title[TSIZE];
 8     int rating;
 9 }Item;
10 
11 typedef struct node { // 鏈表的節點,包含item各項屬性以及一個用來存放下一項地址的指針(鏈表鏈接的關鍵)
12     Item item;
13     struct node*next;
14 }Node;
15 typedef Node * List; 
16 
17 void InitList(List * plist);
18 bool ListisEmpty(const List * plist);
19 bool ListisFull(const List * plist);
20 unsigned int ListItemCount(const List * plist);
21 bool AddItem(Item item, List * plist);
22 void Traverse(const List * plist, void(*pfun)(Item item));
23 void EmptyTheList(List * plist);
24 
25 #endif

功能函數的定義

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include "list.h"
 4 static void CopyToNode(Item item, Node * pnode) // 拷貝數據
 5 {
 6     pnode->item = item;
 7 }
 8 void InitList(List * plist) // 初始化鏈表為空
 9 {
10     *plist = NULL;
11 }
12 
13 bool ListisEmpty(const List * plist)  // 檢查鏈表是否為空
14 {
15     return *plist == NULL ? true : false;
16 }
17 bool ListisFull(const List * plist)  // 檢查鏈表是否已滿
18 {
19     Node * pt;
20     pt = (Node *)malloc(sizeof(Node));
21     return pt == NULL ? true : false;
22 }
23 unsigned int ListItemCount(const List * plist)
24 {
25     unsigned int count = 0;
26     Node * pnode = *plist;
27     while (pnode != NULL)
28     {
29         ++count;
30         pnode = pnode->next;
31     }
32     return count;
33 }
34 bool AddItem(Item item, List * plist) // 在鏈表結尾添加新的項
35 {
36     Node * pnew; // 申請一個新的節點
37     Node * scan = *plist; 
38     pnew = (Node *)malloc(sizeof(Node)); // 給新節點申請空間 
39     if (pnew == NULL) return false; // 申請失敗,返回false
40     CopyToNode(item, pnew); // 把item的內容復制到新節點中
41     pnew->next = NULL; // 將新節點的next指針設置為NULL,表示這一節點為當前的末尾項
42     if (scan == NULL) // 如果當前是空表,則將新節點設置為表的首項
43         *plist = pnew;
44     else
45     {
46         while (scan->next != NULL) //找到當前表中的末尾節點
47             scan = scan->next;
48         scan->next = pnew; //將新節點的地址保存在末尾節點的next成員里(即給鏈表添加了一個新的項)
49     }
50     return true;
51 }
52 void Traverse(const List * plist, void(*pfun)(Item item)) // 將某函數作用於鏈表的每一節點
53 {
54     Node * pnode = *plist; // 將節點指向開頭
55     while (pnode != NULL) 
56     {
57         (*pfun)(pnode->item); 
58         pnode = pnode->next;
59     }
60 }
61 void EmptyTheList(List * plist) // 清空鏈表
62 {
63     Node * psave; // 用來保存當前清除項的下一節點的地址
64     while (*plist != NULL)
65     {
66         psave = (*plist)->next;
67         free(*plist);
68         *plist = psave;
69     }
70 }

用戶接口:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include "list.h"
 5 void showmovies(Item item);
 6 char * s_gets(char * st, int n);
 7 
 8 int main(void)
 9 {
10     List book;
11     Item temp;
12 
13     InitList(&book);
14     if (ListisFull(&book))
15     {
16         fprintf(stderr, "No memory available\n");
17         exit(EXIT_FAILURE);
18     }
19 
20     puts("Enter first book title:");
21     while (s_gets(temp.title, TSIZE) != NULL&&
22         temp.title[0] != '\0')
23     {
24         puts("Enter your rating<0-10>:");
25         scanf("%d", &temp.rating);
26         while (getchar() != '\n')
27             continue;
28         if (AddItem(temp, &book) == false)
29         {
30             fprintf(stderr, "Problem allocating memory\n");
31             break;
32         }
33         if (ListisFull(&book))
34         {
35             puts("The list is now full.\n");
36             break;
37         }
38         puts("Enter next book title(empty line to stop):");
39     }
40 
41     if (ListisEmpty(&book))
42         printf("No data entered.\n");
43     else {
44         printf("Here is the movies list:\n");
45         Traverse(&book, showmovies);
46     }
47     printf("You entered %d movies.\n", ListItemCount(&book));
48 
49     EmptyTheList(&book);
50     printf("Bye\n");
51 
52     return 0;
53 }
54 void showmovies(Item item)
55 {
56     printf("book: %s Rating:%d\n", item.title, item.rating);
57 }
58 char * s_gets(char * st, int n)
59 {
60     char * ret_val;
61     char * find;
62     ret_val = fgets(st, n, stdin);
63     if (ret_val)
64     {
65         find = strchr(st, '\n');
66         if (find)
67             *find = '\0';
68         else
69             while (getchar() != '\n')
70                 continue;
71     }
72     return ret_val;
73 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM