概要
因为操作的需要现在重新学习了数据结构相关知识,故以此文来总结一下链表的基本操作和基本知识
声明:因个人能力有限,本文仅是个人的学习记录笔记,有错误之处还望指出
数据结构(抽象到具体)
- 提供类型属性和相关操作的抽象描述。这种抽象的描述被称为抽象数据结构即ADT(Abstract Data Type)
- 开发一个实现ADT的编程接口(指明数据如何存储和执行的函数)
- 编写代码的实现接口
具体流程
1.建立抽象
- 初始化一个空链表
- 在链表末尾添加一个新项
- 确定链表是否为空
- 确定链表是否为满
- 确定链表中的项数
- 在链表任意位置插入一个项
- 移除链表中的一个项
- 在链表中检索一个项(不改变链表)
- 用另一个项替换链表中的一个项
- 清空链表
2.建立接口
//存储的基本类型
typedef struct film{
char title[64]; //存储的电影标题
float rating; //存储的评分
}Item;
typedef struct node{
Item item;
struct node *next;
}Node;
typedef Node *list;
//在链表的实现中,每一个链节叫做节点(node),每一个节点包含形成链表内容的信息和指向下一个节点的指针。
/* 操作:把树初始化为空
前提条件:ptree指向一个树
后置条件:树被初始化为空
*/
void InitTree(Tree *ptree);
/* 操作:判断树是否为空
前提条件:ptree指向一个树
后置条件:树为空返回true,否则返回false
*/
bool TreeIsEmpty(const Tree *ptree);
/* 操作:判断树是否为满
前提条件:ptree指向一个树
后置条件:树为满返回true,否则返回false
*/
bool TreeIsFull(const Tree *ptree);
/* 操作:确定树的项数
前提条件:ptree指向一个树
后置条件:返回树的项数
*/
int TreeItemCount(const Tree *ptree);
/* 操作:在树中添加一个项
前提条件:pi是待添加项的地址
后置条件:如果可以添加该函数将在树中添加一个项,返回true
否者返回false
*/
bool AddItem(const Item *pi,Tree *ptree);
/* 操作:在树中查找一个项
前提条件:pi是待添加项的地址,ptree指向一个已初始化的树
后置条件:如果可以添加该函数将在树中添加一个项,返回true
否者返回false
*/
bool InTree(const Item *pi,Tree *ptree);
/* 操作:在树中删除一个项
前提条件:pi是删除项的地址,ptree指向一个已初始化的树
后置条件:如果可以成功删除一个项,返回true
否者返回false
*/
bool DeleteTree(const Item *pi,Tree *ptree);
/* 操作: 把函数应用于树中的每一项
前提条件: ptree指向一个树
pfun指向一个函数,
该函数接受一个Item类型的参数,并无返回值
后置条件: pfun指向的这个函数为树中的每一项执行一次*/
void Traverse(const Tree *ptree,void(*pfun)(Item item));
/* 操作:删除书中所有内容
前提条件:pi是删除项的地址,ptree指向一个已初始化的树
后置条件:树为空
*/
void DeleteAll(Tree *ptree);
3.使用接口
这一部分是通过代码来将伪代码的功能进行实现
//链表设置为空
void InitializeList(List *plist){
plist = NULL;
}
//判断链表是否为空
bool ListIsEmpty(const List *plist){
if(*plist == NULL)
return true;
else
return false;
}
//如果链表已满,返回true
bool ListIsFull(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 ListItemCount(const List *plist){
unsigned int count = 0;
Node *pnode = *plist; //设置链表的开始
while(pnode != NULL){
++count;
pnode = pnode->next; //设置下一个节点
}
return count;
}
//创建储存项的节点,并将其添加至由Plist指向的链表末尾
bool AddItem(Item item,List *plist){
Node *pnew;
Node *scan=*plist;
pnew=(Node *)malloc(sizeof(Node));
if(pnew==NULL){
return false;
}
CopyToNode(item,pnew);
pnew->next = NUUL;
if(scan == NULL) //空链表所以把pnew放在表头
*plist = pnew;
else
{
while(scan->next != NULL)
scan= scan->next; /* 找到链表的末尾 */
scan->next = pnew;/* 把pnew添加到链表的末尾 */
}
return true;
}
//访问每个节点并执行pfun指向的函数
void Traverse(const List *list ,void(*pfun)(Item item)){
Node *pnode = *plist; //设置链表的开始
while(pnode != NULL)
{
(*pfun)(pnode->item); //把函数应用链表中的项
pnode = pnode->next; //前进到下一项
}
}
//释放由malloc分配的内存
//设置链表的指针为NULL
void EmptyTheList(List *plist){
Node *psave;
while(*plist != NULL){
psave =(*plist)->next; //保存下一个节点的地址
free(*plist); //释放当前节点
*plist = psave; //前进至下一个节点
}
}
/* 局部函数定义 */
/* 把一个项拷贝到节点中 */
static void CopyToNode(Item item, Node * pnode)
{
pnode->item = item; /* 拷贝结构 */
}
结果图
此案例:是通过链表来实现一个电影的名称和排名的信息保存功能
而塞过 2021-1-11
关于我:一个就要进入互联网,经历社会毒打的99小伙