【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 ...
随机推荐
- Gs_Class.Gs_DataFunction数据操作类库20160225
using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security ...
- SQLite语句
搜索某属性: select exp from player where level = 2; 创建表: create table player (level integer primary key, ...
- SharePoint:备份和还原
注意事项: 1.备份和还原最好都用PowerShell,用时候用管理中心会遇到错误. 2.备份PowerShell要注意数据库服务器名,要与管理中心的数据库服务器一致,用ip可能会报错. Restor ...
- tomcat7或8如何修改浏览器标题上的ICON小图标
替换tomcat根目录/webapps/ROOT下的favicon.ico文件,之后重启了服务器,可是还是显示那只猫的图标. 如果不能显示,请清除浏览器的缓存
- ios开发的系统兼容性问题解决
对于系统中过时的方法或者是为了向下兼容兼容不同的版本使用最新的方法都要判断当前的系统版本号,在进行方法的调用 1.系统方法过时的注释 ````objc - (void)imagePickerContr ...
- c#中命令copy已退出,返回值为1
c#中命令copy已退出,返回值为1 本正经的道:董姐刚才你说的修心养性其中的'修心'我 有孕在身刚好由戴梦瑶顶替了她的位置按照的指示 ╋旆呆 湎术葶页 邾箕砜笳 烦璜卿廑 奶奶个腿儿的等下次非让你 ...
- H264的coded_block_pattern编码块模式
1 词汇约定 CodedBlockPatternLuma:一个宏块的亮度分量的coded_block_pattern CodedBlockPatternChroma:一个宏块的色度分量的coded_b ...
- xfs文件系统磁盘配额
引言 这篇文章简单介绍一下xfs文件系统的磁盘配额配置. 文章目录 0×1.开启分区磁盘配额 0×2.使用xfs_quota命令配置磁盘配额 0×1.开启分区磁盘配额 对于ext4文件以前的文件系统, ...
- Boolean对象 识记
Boolean 对象表示两个值:"true" 或 "false". 1.创建 new Boolean(value); //构造函数 返回 对象+返回值 Bool ...
- Hibernate 异常 集锦
异常1.Error parsing JNDI name [foo] 异常信息摘要: org.hibernate.engine.jndi.JndiException: Error parsing JND ...