【ADT】链表的基本C语言实现
什么是抽象数据类型?
首先,这一概念是软件开发人员在力求编写的代码健壮、易维护且可以复用的过程中产生的。
英文是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语言实现的更多相关文章
- 由链表初始化看C语言的二级指针
先来看C语言创建链表.插入节点和遍历链表的一段代码: #include <stdio.h> #include <stdlib.h> typedef int ElemType; ...
- 链表的创建(C语言实现)
学习链表之前,我们要知道为什么要引入链表. C语言中的数组使用之前,我们必须要定义数组的大小.但是当我们不知道数据个数(或者很大)时,定义数组大小就成了一个困扰,而且对于这么多数据的处理也会很麻烦.所 ...
- 数据结构—单链表(类C语言描写叙述)
单链表 1.链接存储方法 链接方式存储的线性表简称为链表(Linked List). 链表的详细存储表示为: ① 用一组随意的存储单元来存放线性表的结点(这组存储单元既能够是连续的.也能够是不连续的) ...
- 链表源代码(C语言实现)
源代码(C语言实现) ①.构造链表节点 typedef struct Node //一个单独的节点 { int ...
- 不带头结点的单链表(基于c语言)
本篇文章的代码大多使用无头结点的单链表: 相关定义: #include <stdio.h> #include <stdlib.h> #include <assert.h& ...
- 链表的实现(Java语言描述)
代码如下: public interface ListInterface<T> { public T getElem(int i); public boolean insertElem(i ...
- 链表数据结构(C/C++语言实现)
注意:没有使用malloc和free:加了一个头文件,用于清屏和暂停:还有就是一个错误特别容易被忽略,那就是主函数中声明了LinkList p,然后就直接创建链表,忘了给p分配空间.一定要先初始化链表 ...
- 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 ...
- PTA 学生成绩链表处理(C语言)
本题要求实现两个函数,一个将输入的学生成绩组织成单向链表:另一个将成绩低于某分数线的学生结点从链表中删除. 函数接口定义: struct stud_node *createlist(); struct ...
随机推荐
- Python学习笔记——基础篇【第二周】——解释器、字符串、列表、字典、主文件判断、对象
目录 1.Python介绍 2.Python编码 3.接受执行传参 4.基本数据类型常用方法 5.Python主文件判断 6.一切事物都是对象 7. int内部功能介绍 8.float和long内 ...
- cocos2d-x中的init,onEnter,onExit......
CCNode的init()方法和onEnter()方法: 一.调用顺序显示FirstScene时: FirstLayer::initFirstLayer::onEnterFirstLayer::onE ...
- 利用requestjs优化响应式移动端js加载
html: <script data-main="main" src="require.js"></script> main.js re ...
- Chapter 17_1 弱引用table
Lua采用了自动内存管理.所以不用担心新创建的对象需要的内存如何分配出来,也不用考虑对象不再被使用后怎样释放它们所占用的内存. Lua实现了一个增量标记-扫描收集器.它使用这两个数字来控制垃圾收集循环 ...
- 工具类 util.Date 日期类
/** * @description format the time * @author xf.radish * @param {String} format The format your want ...
- windows下寻找端口
netstat -aon|findstr "5037" 找到占用5037的进程号: 根据进程号杀死进程 taskkill /pid 5136 /f tasklist|findstr ...
- CentOs + Nginx + php-fpm + MySql 依赖库安装
依赖库和开发工具 yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype free ...
- Webdriver常用的元素定位
Webdriver常用定位元素的方法有以下八种: id.name.class name.tag name.link text.partial link text.xpath.class selecto ...
- tomcat + jenkins启动tomcat后打开jenkins页面提示404错误的解决方案
首先下载tomcat和jenkins,将下载的jenkins2.12 war放到tomcat的webapps文件夹下后执行/bin文件夹下的start启动后,打开http://localhost:80 ...
- Webform动态创建删除行及后台取值
开发过程中经常碰到许多不确定事项,所以有时需要动态生成新的记录,如图所示,点击新增时新增一条参考记录,点击删除时则删除该记录:第一步,创建一个表格,用hidden记录当前最大行数,添加时则只需复制模板 ...