单链表的C语言实现
来源:互联网 发布:中国战略布局知乎 编辑:程序博客网 时间:2024/05/17 18:45
在学习数据结构中,紧接着顺序表接触的就是单链表,那么单链表是什么呢?
1.什么是单链表?
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。
2.结构?
链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。以“结点的序列”表示线性表称作线性链表(单链表)。单链表是链式存取的结构,为找第 i 个数据元素,必须先找到第 i-1 个数据元素。
把单链表的特征说清楚后,我们就开始实现单链表的功能了。最基础的功能是实现它的增加、删除、查找等,因为它的线性特征,在增加的时候会存在头插、尾插,同样删除也一样。
SListNode.h#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<assert.h>#include<stdlib.h>typedef int DataType;typedef struct SListNode{ DataType data; struct SListNode* next;}SListNode;void InitSList(SListNode*& pHead); //初始化SListNode* BuyNode(DataType data); //开辟空间void Print(SListNode*& pHead); //打印void Destory(SListNode*& pHead); //销毁void PushBack(SListNode*& pHead, DataType data); //尾插void PopBack(SListNode*& pHead); //尾删void PushFront(SListNode*& pHead, DataType data); //头插void PopFront(SListNode*& pHead); //头删void Insert(SListNode*& pos,DataType data);//在某个位置插入某个数据void Erase(SListNode*& pHead,SListNode* pos);//删除某个节点的数据void Remove(SListNode*& pHead,DataType data); //删除某个数据所在的节点SListNode* Find(SListNode*& pHead,DataType data); //查找某个数据所在的位置
SListNode.c#include"SListNode.h"void InitSList(SListNode*& pHead) //初始化{ pHead = NULL;}SListNode* BuyNode(DataType data) //开辟空间{ SListNode* node = (SListNode*)malloc(sizeof(SListNode)); assert(node); node->data = data; node->next = NULL; return node;}void Print(SListNode*& pHead) //打印{ SListNode* cur = pHead; if (cur == NULL) printf("null\n"); while (cur) { printf("%d ", cur->data); cur = cur->next; } printf("\n");}void PushBack(SListNode*& pHead, DataType data) //尾插{ if (pHead == NULL) pHead = BuyNode(data); else { SListNode* cur = pHead; while (cur->next) { cur = cur->next; } cur->next = BuyNode(data); }}void PopBack(SListNode*& pHead) //尾删{ assert(pHead); if (pHead->next == NULL) { free(pHead); pHead = NULL; } else { SListNode* cur = pHead; SListNode* pcur = cur; while(cur->next) { pcur = cur; cur = cur->next; } free(cur); cur = NULL; pcur->next = NULL; }}void PushFront(SListNode*& pHead, DataType data) //头插{ if (pHead == NULL) pHead=BuyNode(data); else { SListNode* newHead = BuyNode(data); newHead->next = pHead; pHead = newHead; }}void PopFront(SListNode*& pHead) //头删{ if (pHead == NULL) //pHead为空 return; else if (pHead->next == NULL) //pHead->next为空 { free(pHead); pHead = NULL; } else //正常的删除 { SListNode* cur = pHead; pHead = pHead->next; free(cur); }}void Insert(SListNode*& pos, DataType data) //在某个位置插入某个数据{ if (NULL == pos) return; SListNode* newNode = BuyNode(data); newNode->next = pos->next; pos->next = newNode;}void Erase(SListNode*& pHead, SListNode* pos) //删除某个节点的数据{ assert(pHead&&pos); if (pos == pHead) { SListNode* tmp = pHead; pHead = pHead->next; free(tmp); tmp = NULL; } else { SListNode* cur = pHead; while (cur->next != pos) { cur = cur->next; } cur->next = pos->next; free(pos); pos = NULL; }}void Remove(SListNode*& pHead, DataType data) //删除某个数据所在的节点{ assert(pHead); SListNode* pos = Find(pHead, data); if (pos == pHead) { SListNode* tmp = pHead; pHead = pHead->next; free(tmp); tmp = NULL; } else { SListNode* cur = pHead; while (cur->next!=pos) { cur = cur->next; } cur->next = pos->next; free(pos); pos = NULL; }}SListNode* Find(SListNode*& pHead, DataType data) //查找某个数据所在的位置{ SListNode* cur = pHead; assert(pHead); while(cur) { if(cur->data == data) return cur; cur = cur->next; } return NULL;}void Destory(SListNode*& pHead) //销毁{ assert(pHead); free(pHead); pHead = NULL;}
测试函数#include"SListNode.h"void Test1() //尾插尾删{ SListNode* Slistnode; InitSList(Slistnode); PushBack(Slistnode, 1); PushBack(Slistnode, 2); PushBack(Slistnode, 3); PushBack(Slistnode, 4); PushBack(Slistnode, 5); Print(Slistnode); PopBack(Slistnode); PopBack(Slistnode); PopBack(Slistnode); PopBack(Slistnode); Print(Slistnode);}void Test2() //头插头删{ SListNode* Slistnode; InitSList(Slistnode); PushFront(Slistnode, 1); PushFront(Slistnode, 2); PushFront(Slistnode, 3); PushFront(Slistnode, 4); PushFront(Slistnode, 5); Print(Slistnode); PopFront(Slistnode); PopFront(Slistnode); PopFront(Slistnode); PopFront(Slistnode); Print(Slistnode);}void Test3() //任意位置的插入删除{ SListNode* Slistnode; InitSList(Slistnode); PushFront(Slistnode, 1); PushFront(Slistnode, 2); PushFront(Slistnode, 3); PushFront(Slistnode, 4); PushFront(Slistnode, 5); Print(Slistnode); SListNode* pos1 = Find(Slistnode, 3); Insert(pos1, 7); Print(Slistnode); SListNode* pos2 = Find(Slistnode, 4); Erase(Slistnode, pos2); Print(Slistnode); Remove(Slistnode, 1); Print(Slistnode); Destory(Slistnode); Print(Slistnode);}int main(){ Test1(); Test2(); Test3(); system("pause");}
总结:整体代码部分如上,在这里需要注意几点:
1.对链表进行插入删除时,一定要分析可能出现的情况,比如头插时可能三种情况,当链表为空;当链表指向的下一个为空;正常的头插。只有将情况分析清楚,你才能按照逻辑去写代码。
2.在实现链表的时候,代码都差不多,但很多细节需要我们去注意。该断言的时候可以用assert,不需要的部分进行判断即可。
3.在测试较多的功能时,可以分步分模块测试,哪里有问题也比较好调试。
0 0
- 单链表的C语言实现
- 单链表的C语言实现
- c语言单链表的实现
- 单链表C语言的实现
- 单链表的C语言实现
- C语言单链表的实现
- 【C语言】单链表的实现
- [c语言]单链表的实现
- 单链表的C语言实现
- C语言 单链表的实现
- 单链表的C语言实现
- 单链表的C语言实现
- C语言一个单链表的实现
- C语言实现单链表的各种操作
- C语言又一个单链表的实现
- c语言又一个单链表的实现
- 单链表的C语言算法实现
- C语言实现单链表的逆置
- Java基础之内部类
- C语言OJ项目参考(2569)统计字符串种类
- 第十六周 -排序(二) 项目1 -验证算法(3)冒泡排序
- 在Keil里面仿真stm32程序出现Communication failure错误
- 支付宝支付接口中 notify_url 与 return_url 的区别是什么
- 单链表的C语言实现
- linux 下php 服务器权限问题
- hadoop学习第六节:MapReduce应用案例
- C语言OJ项目参考(2424)字符串比较
- HDU 1043 Eight(A* + 奇偶剪枝 + 康拓展开)
- 基于Http协议的Android网络编程
- RabbitMQ 实现延时队列
- springMVC源码分析--拦截器HandlerExecutionChain(三)
- 关于DialogFragment的一些学习