抽象数据类型ADT
计算机科学领域已开发了一种定义新类型的好方法,用 3 个步骤完成从抽象到具体的过程。
- 提供类型属性和相关操作的抽象描述。这些描述既不能依赖特定的实现,也不能依赖特定的编程语言。这种正式的抽象描述被称为抽象数据类型 (ADT)。
- 开发一个实现 ADT 的编程接口。也就是说,指明如何储存数据和执行所需操作的函数。例如在 C中,可以提供结构定义和操控该结构的函数原型。这些作用于用户定义类型的函数相当于作用于 C 基本类型的内置运算符。需要使用该新类型的程序员可以使用这个接口进行编程。
- 编写代码实现接口。这一步至关重要,但是使用该新类型的程序员无需了解具体的实现细节。
建立ADT的步骤实践 以链表为例
建立抽象
链表应该实现以下功能。
- 初始化一个空链表
- 再链表结尾添加一个新的项
- 判断链表是否为空
- 判断链表是否已经满了
- 确定链表中的元素个数
- 访问链表中的项 例如数组的 [] 运算符和指针的 -> 运算符
- 在链表中的任意位置添加一个项
- 移除链表中的任意一项
- 更替链表中的某一项
- 在链表中搜索一个项 根据某个数据找到对应的项比如最大值
建立接口
数据隐藏是一种从编程的更高层次隐藏数据表示细节的艺术
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
| #define TSIZE 100 struct film { char title[TSIZE]; int rating; };
typedef struct film Item;
struct node { Item item; struct node *next; };
typedef struct node Node;
typedef struct node *List;
void InitializeList(List *plist);
bool Empty(const List *plist);
bool Full(const List *plist);
unsigned int Count(const List *plist);
bool AddItem(Item item, List *plist);
void Traverse(List *plist, void (*pfun)(Item item));
bool Clear(List *plist);
|
实现接口
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
|
void InitializeList(List *plist) { *plist = NULL; }
bool Empty(const List *plist) { return (*plist == NULL); }
bool Full(const List *plist) { Node *pt; bool full; pt = (Node *)malloc(sizeof(Node)); if (pt == NULL) full = true; else full = false; free(pt); return full; }
unsigned int Count(const List *plist) { unsigned int count = 0; Node *pnode = *plist; while (pnode != NULL) { count++; pnode = pnode->next; } return count; }
bool AddItem(Item item, List *plist) { Node *pnew; Node *scan = *plist; pnew = (Node *)malloc(sizeof(Node)); if (pnew == NULL) return false; pnew->item = item; pnew->next = NULL; if (*plist == NULL) *plist = pnew; else { scan = *plist; while (scan->next != NULL) { scan = scan->next; } scan->next = pnew; } return true; }
void Traverse(List *plist, void (*pfun)(Item item)) { Node *scan = *plist; while (scan != NULL) { pfun(scan->item); scan = scan->next; } }
void Clear(List *plist) { Node *scan = *plist; while (*plist != NULL) { *plist = scan->next; free(scan); scan = *plist; } }
|
使用接口
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
| #include "list.h" #include <stdio.h> #include <stdlib.h> #include <string.h> void pfun(Item Item) { printf("%s %d\n", Item.title, Item.rating); }
int main() { List mylist; printf("初始化链表\n"); InitializeList(&mylist); Item myitem; strcpy(myitem.title, "cuiwenyaono.1"); myitem.rating = 100;
printf("当前链表内的元素数量为%d\n", Count(&mylist)); printf("添加项目\n"); AddItem(myitem, &mylist); printf("当前链表内的元素数量为%d\n", Count(&mylist)); if (Empty(&mylist)) printf("当前链表为空\n"); else printf("当前链表不空\n"); if (Full(&mylist)) printf("当前链表满了\n"); else printf("当前链表不满\n"); printf("打印链表\n"); Traverse(&mylist, (*pfun)); Clear(&mylist); if (Empty(&mylist)) printf("当前链表为空\n"); else printf("当前链表不空\n"); }
|