什么是抽象数据类型?
首先,这一概念是软件开发人员在力求编写的代码健壮、易维护且可以复用的过程中产生的。
英文是AbstractData Type。有人将其比作“抽象”的墙壁,“它将接口和实现明确分开,所以用户只看到接口,因此不需要参与实现。”构建者则着力实现ADT接口。ADT成为了双方的契约,这使得代码更容易维护。

接口:接口是把公共的方法和属性组合起来以封装特定功能的一个集合。

创建linked list.h头文件

 #ifndef LIST_H_
#define LIST_H_
#include <stdbool.h>
#define TSIZE 45 typedef struct book{ // 建立包含元素属性的item结构体
char title[TSIZE];
int rating;
}Item; typedef struct node { // 链表的节点,包含item各项属性以及一个用来存放下一项地址的指针(链表链接的关键)
Item item;
struct node*next;
}Node;
typedef Node * List; void InitList(List * plist);
bool ListisEmpty(const List * plist);
bool ListisFull(const List * plist);
unsigned int ListItemCount(const List * plist);
bool AddItem(Item item, List * plist);
void Traverse(const List * plist, void(*pfun)(Item item));
void EmptyTheList(List * plist); #endif

功能函数的定义

 #include <stdio.h>
#include <stdlib.h>
#include "list.h"
static void CopyToNode(Item item, Node * pnode) // 拷贝数据
{
pnode->item = item;
}
void InitList(List * plist) // 初始化链表为空
{
*plist = NULL;
} bool ListisEmpty(const List * plist) // 检查链表是否为空
{
return *plist == NULL ? true : false;
}
bool ListisFull(const List * plist) // 检查链表是否已满
{
Node * pt;
pt = (Node *)malloc(sizeof(Node));
return pt == NULL ? true : false;
}
unsigned int ListItemCount(const List * plist)
{
unsigned int count = ;
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; // 申请失败,返回false
CopyToNode(item, pnew); // 把item的内容复制到新节点中
pnew->next = NULL; // 将新节点的next指针设置为NULL,表示这一节点为当前的末尾项
if (scan == NULL) // 如果当前是空表,则将新节点设置为表的首项
*plist = pnew;
else
{
while (scan->next != NULL) //找到当前表中的末尾节点
scan = scan->next;
scan->next = pnew; //将新节点的地址保存在末尾节点的next成员里(即给链表添加了一个新的项)
}
return true;
}
void Traverse(const List * plist, void(*pfun)(Item item)) // 将某函数作用于链表的每一节点
{
Node * pnode = *plist; // 将节点指向开头
while (pnode != NULL)
{
(*pfun)(pnode->item);
pnode = pnode->next;
}
}
void EmptyTheList(List * plist) // 清空链表
{
Node * psave; // 用来保存当前清除项的下一节点的地址
while (*plist != NULL)
{
psave = (*plist)->next;
free(*plist);
*plist = psave;
}
}

用户接口:

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
void showmovies(Item item);
char * s_gets(char * st, int n); int main(void)
{
List book;
Item temp; InitList(&book);
if (ListisFull(&book))
{
fprintf(stderr, "No memory available\n");
exit(EXIT_FAILURE);
} puts("Enter first book title:");
while (s_gets(temp.title, TSIZE) != NULL&&
temp.title[] != '\0')
{
puts("Enter your rating<0-10>:");
scanf("%d", &temp.rating);
while (getchar() != '\n')
continue;
if (AddItem(temp, &book) == false)
{
fprintf(stderr, "Problem allocating memory\n");
break;
}
if (ListisFull(&book))
{
puts("The list is now full.\n");
break;
}
puts("Enter next book title(empty line to stop):");
} if (ListisEmpty(&book))
printf("No data entered.\n");
else {
printf("Here is the movies list:\n");
Traverse(&book, showmovies);
}
printf("You entered %d movies.\n", ListItemCount(&book)); EmptyTheList(&book);
printf("Bye\n"); return ;
}
void showmovies(Item item)
{
printf("book: %s Rating:%d\n", item.title, item.rating);
}
char * s_gets(char * st, int n)
{
char * ret_val;
char * find;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
find = strchr(st, '\n');
if (find)
*find = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}

【ADT】链表的基本C语言实现的更多相关文章

  1. 由链表初始化看C语言的二级指针

    先来看C语言创建链表.插入节点和遍历链表的一段代码: #include <stdio.h> #include <stdlib.h> typedef int ElemType; ...

  2. 链表的创建(C语言实现)

    学习链表之前,我们要知道为什么要引入链表. C语言中的数组使用之前,我们必须要定义数组的大小.但是当我们不知道数据个数(或者很大)时,定义数组大小就成了一个困扰,而且对于这么多数据的处理也会很麻烦.所 ...

  3. 数据结构—单链表(类C语言描写叙述)

    单链表 1.链接存储方法 链接方式存储的线性表简称为链表(Linked List). 链表的详细存储表示为: ① 用一组随意的存储单元来存放线性表的结点(这组存储单元既能够是连续的.也能够是不连续的) ...

  4. 链表源代码(C语言实现)

    源代码(C语言实现) ①.构造链表节点 typedef struct Node    //一个单独的节点                   {                         int ...

  5. 不带头结点的单链表(基于c语言)

    本篇文章的代码大多使用无头结点的单链表: 相关定义: #include <stdio.h> #include <stdlib.h> #include <assert.h& ...

  6. 链表的实现(Java语言描述)

    代码如下: public interface ListInterface<T> { public T getElem(int i); public boolean insertElem(i ...

  7. 链表数据结构(C/C++语言实现)

    注意:没有使用malloc和free:加了一个头文件,用于清屏和暂停:还有就是一个错误特别容易被忽略,那就是主函数中声明了LinkList p,然后就直接创建链表,忘了给p分配空间.一定要先初始化链表 ...

  8. 1025 反转链表 (25 分)C语言

    题目描述 给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转.例如:给定L为1→2→3→4→5→6,K为3,则输出应该为 3→2→1→6→5→4:如果K为4,则输出应该为4→3→2→1→5 ...

  9. PTA 学生成绩链表处理(C语言)

    本题要求实现两个函数,一个将输入的学生成绩组织成单向链表:另一个将成绩低于某分数线的学生结点从链表中删除. 函数接口定义: struct stud_node *createlist(); struct ...

随机推荐

  1. Android如何查看应用签名信息

    转自http://www.trinea.cn/android/android-view-signatures/comment-page-1/ 介绍Android如何查看自己的应用签名及三方APK或系统 ...

  2. [SQL基础教程] 3-3 HAVING

    [SQL基础教程] 3-3 HAVING HAVING子句 SELECT col_1,col_2 FROM table GROUP BY col_1,col_2 HAVING col_1 = '2'; ...

  3. 聚类算法K-Means, K-Medoids, GMM, Spectral clustering,Ncut

    原文请戳:http://blog.csdn.net/abcjennifer/article/details/8170687 聚类算法是ML中一个重要分支,一般采用unsupervised learni ...

  4. 在一个form里边同时执行搜索和 execl导出功能

    一个form 分搜索 和 导出<form name="searchform" id="searchform" > <input type=&q ...

  5. PHP字符串转义

    与PHP字符串转义相关的配置和函数如下: 1.magic_quotes_runtime 2.magic_quotes_gpc 3.addslashes()和stripslashes() 4.mysql ...

  6. matlab,xls转换为mat文件

    b=xlsread('iris_data.xls');save iris_data.mat b

  7. python2与python3

    一.print python2 print  "hello world !" python3 print("hello world!") 二.字符编码 pyth ...

  8. Qt对xml文件的读写

    最近研究了一下qt下对xml文件的读写,小计一下,成为自己的知识. main函数调用: #include <QApplication> #include "readconfig. ...

  9. Maven项目下WEB-INFO目录下没有编译的classes文件

    建立mavan项目之后,在项目目录中没有发现编译的classes文件夹 解决办法: 因为maven是默认将编译后的classes文件存入项目下的target文件夹中,所以我们需要修改编译后存放的路径, ...

  10. Android Studio Gradle更新的解决办法

    环境: Win7_64旗舰版.Android Studio2.1.1 问题描述: 在打开Android Studio项目的时候,会下载项目对应版本的gradle,由于是国外网站导致更新较慢,该版本是在 ...