C语言实现单向链表的基本操作
"这篇资源是关于单向链表的基础知识,包括如何在C语言中实现单向链表的初始化、创建、销毁等操作。" 在数据结构中,链表是一种非常重要的非线性数据结构。单向链表是其中一种形式,每个节点包含一个数据元素和一个指向下一个节点的指针,但没有指向前一个节点的指针。这种数据结构允许高效地插入和删除元素,尤其是在内存不连续的情况下。 1. 单向链表初始化 `InitList` 函数用于初始化单向链表。它首先分配一个新节点,并将该节点的数据成员设置为未定义(通常为0或NULL),然后将其`next`指针设置为NULL,表示链表的结束。如果内存分配失败,函数会打印错误信息并退出程序。 ```c DAT* InitList(DAT* head) { head = (DAT*)malloc(LEN); if (!head) { printf("\n--ʧ--\n"); // 内存分配失败提示 exit(FALSE); } head->next = NULL; return head; } ``` 2. 单向链表创建 `creatList` 函数用于创建单向链表。用户可以输入一系列整数,这些整数会被存储为链表中的节点。链表的创建过程包括分配新的节点,输入数据,然后将新节点连接到链表的末尾。当用户不再输入时,链表创建完成。 ```c DAT* creatList(DAT* head) { DAT* p1, *p2; char ch; int n = 1; // ... 省略部分代码 ... while (ch == 'Y' || ch == 'y') { // 当用户输入 'Y' 或 'y' 时继续添加节点 // ... 省略部分代码 ... p2->next = p1; // 将新节点 p1 连接到链表 p2 = p1; // 更新 p2 指针指向新节点 // ... 省略部分代码 ... } p2->next = NULL; // 设置最后一个节点的 next 为 NULL // ... 省略部分代码 ... } ``` 3. 单向链表销毁 `ClearList` 函数用于释放单向链表所占用的内存。这个函数遍历链表,逐个释放节点,直到链表头为空。然而,给定的代码片段中,`ClearList` 函数并未完整显示,仅剩开头部分。完整的实现应该包含循环来遍历链表并释放每个节点。 ```c int ClearList(DAT* head) { if (head == NULL) { printf("\n----\n"); // 链表为空提示 return FALSE; } // ... 缺失部分:遍历链表并释放节点 ... } ``` 此外,单向链表还有其他操作,如搜索、插入、删除节点等。搜索通常通过遍历链表找到特定数据的节点;插入操作需要在特定位置创建新节点并更新指针;删除操作涉及移除指定节点并调整相邻节点的指针。这些操作在实际编程中都十分常见,理解和熟练掌握单向链表的这些基本函数至关重要。
#include <stdio.h>
#define LEN sizeof(DAT)
#define TRUE 1
#define FALSE -1
#define NULL 0
typedef struct LNode{
int data;
struct LNode *next;
}DAT;
DAT *InitList(DAT *head)//创建空表
{
head = (DAT *)malloc(LEN);
if(!head)
{printf("\n--链表创建失败--\n");exit(FALSE);}
head ->next = NULL;
return head;
}
DAT *creatList(DAT *head)//数据录入
{
DAT *p1,*p2;
char ch;
int n = 1;
p1 = p2 = (DAT *)malloc(LEN);
if(p1 != NULL)
{
printf("\n请输入数据:\n");
scanf("%d",&p1->data);//p1需要存储数据,每一次存储都需要申请空间
head -> next = p1;//注意:本程序的头结点不存储数据,因为ClearList函数和destroyList函数无法区分实现
//所以ListTraverse输出函数也是从头结点的下一个才开始输出的!
//p2 = p1;为什么这步可以省略呢?就是因为p1,p2在申请空间的时候被赋予的地址是一致的!
printf("\n继续录入(y/any other keys to exit)?\n");
getchar();
scanf("%c",&ch);
while(ch == 'Y'||ch == 'y')
{
printf("\n请输入数据:\n");
p1 = (DAT *)malloc(LEN);
if(p1 != NULL)
scanf("%d",&p1->data);
p2 -> next = p1;
p2 = p1;
printf("\n继续录入(y/any other keys to exit)?\n");
getchar();
scanf("%c",&ch);
}
p2 -> next = NULL;//p2作为连接新建节点的指针,如果next为空,那自然是结束了录入
printf("\n--录入结束--\n");
}
剩余24页未读,继续阅读
- 粉丝: 122
- 资源: 4
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- C++标准程序库:权威指南
- Java解惑:奇数判断误区与改进方法
- C++编程必读:20种设计模式详解与实战
- LM3S8962微控制器数据手册
- 51单片机C语言实战教程:从入门到精通
- Spring3.0权威指南:JavaEE6实战
- Win32多线程程序设计详解
- Lucene2.9.1开发全攻略:从环境配置到索引创建
- 内存虚拟硬盘技术:提升电脑速度的秘密武器
- Java操作数据库:保存与显示图片到数据库及页面
- ISO14001:2004环境管理体系要求详解
- ShopExV4.8二次开发详解
- 企业形象与产品推广一站式网站建设技术方案揭秘
- Shopex二次开发:触发器与控制器重定向技术详解
- FPGA开发实战指南:创新设计与进阶技巧
- ShopExV4.8二次开发入门:解决升级问题与功能扩展