实现单链表及其基本操作
来源:互联网 发布:马东眼袋在哪割的 知乎 编辑:程序博客网 时间:2024/05/29 02:12
单链表的定义:
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针
(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
单链表分为:1,有头单链表 2,无头单链表
本次主要针对无头单链表
链表的声明
#include <stdio.h>#include <assert.h>#include <malloc.h>typedef int DataType;//带头单链表typedef struct Node{DataType _data;struct Node* _pNext;}Node, *PNode;
链表的基本操作
注意:
在传入参数时,当需要修改pHead的指向时,需要传入二级指针PNode *pHead
当不需要改变pHead的指向时,只需传入一级指针PNode pHead即可。
// 初始化单链表void InitList(PNode* pHead);//销毁链表void DestroyList(PNode *pHead);// 在单链表的尾部插入一个节点void PushBack(PNode* pHead, DataType data);// 删除单链表的最后一个节点void PopBack(PNode* pHead);// 在单链表的头部插入值为data的结点void PushFront(PNode* pHead, DataType data);// 删除单链表的第一个结点void PopFront(PNode* pHead);// 在单链表中查找值为data的结点,找到了返回该结点的地址,否则返回NULLNode* Find(PNode pHead, DataType data);// 在单链表pos位置后插入值为data的结点void Insert(PNode pos, DataType data);// 在单链表中删除位置为pos的结点void Erase(PNode* pHead, PNode pos);// 移除单链表中第一个值为data的结点void Remove(PNode* pHead, DataType data);// 移除单链表中所有值为data的结点void RemoveAll(PNode* pHead, DataType data);// 获取单链表总结点的总个数size_t Size(PNode pHead);// 判断结点是否为空int Empty(PNode pHead);// 返回单链表的最后一个结点的位置PNode Back(PNode pHead);// 返回单链表的第一个结点的位置PNode Front(PNode pHead);// 构建一个新节点Node* BuyNode(DataType data);// 正向打印单链表void PrintList(PNode pHead);
链表基本功能实现
///////////////只要改变了单链表的内容(指针指向内容),应使用PNode*二级指针。///////////////////////////////不然的话,在函数中改变了pHead的内容,函数外pHead还是指向原来的地址//////////// 构建一个新节点Node* BuyNode(DataType data){PNode pTemp = (PNode)malloc(sizeof(Node));if (NULL != pTemp){pTemp->_data = data;pTemp->_pNext = NULL;}return pTemp;}// 初始化单链表void InitList(PNode* pHead){assert(NULL != pHead);*pHead = NULL; //初始化为空}// 在单链表的尾部插入一个节点void PushBack(PNode* pHead, DataType data){PNode pNewNode = NULL;assert(NULL != pHead);if (!(pNewNode = BuyNode(data))) //创建节点失败return ;if (NULL == *pHead) //链表为空时*pHead = pNewNode;else//链表不为空{PNode pTailNode = Back(*pHead);pTailNode->_pNext = pNewNode;}}// 在单链表的头部插入值为data的结点void PushFront(PNode* pHead, DataType data){PNode pNewNode = NULL;assert(NULL != pHead);if (!(pNewNode = BuyNode(data)))//创建节点失败return ;if (NULL == *pHead)//链表为空时*pHead = pNewNode;else//链表不为空{pNewNode->_pNext = *pHead;*pHead = pNewNode;}}// 删除单链表的最后一个节点void PopBack(PNode* pHead){assert(NULL != pHead);if (NULL == *pHead) //链表为空return ;if (NULL == (*pHead)->_pNext) //链表只有一个节点{free(*pHead); //删除节点*pHead = NULL; //链表为空}else//链表节点大于等于2{PNode pDelNode = *pHead; //倒数第二个节点指针while (NULL != pDelNode->_pNext->_pNext) //指向倒数第二个节点pDelNode = pDelNode->_pNext;free(pDelNode->_pNext);//删除最后一个节点pDelNode->_pNext = NULL; //倒数第二个节点指向空。}}// 删除单链表的第一个结点void PopFront(PNode* pHead){assert(NULL != pHead);if (NULL == *pHead)return ;else{PNode pFirstNode = *pHead;*pHead = (*pHead)->_pNext;free(pFirstNode);pFirstNode = NULL;}}// 在单链表pos位置后插入值为data的结点void Insert(PNode pos, DataType data){PNode pNewNode = NULL;assert(NULL != pos);if (!(pNewNode = BuyNode(data)))return ;pNewNode->_pNext = pos->_pNext;pos->_pNext = pNewNode;}// 在单链表中删除位置为pos的结点void Erase(PNode* pHead, PNode pos){PNode pPreNode = NULL;assert(NULL != pHead); //看看是该用if(pos == NULL)好,还是assert好。assert(NULL != pos);pPreNode = *pHead;//pPreNode指向pos前一节点if (NULL == *pHead)//当是空链表时return ;if (pos == *pHead)//pos为第一个节点时PopFront(pHead);else//pos为别的位置,并且链表不为空{//考虑pos不为链表内容情况while (pPreNode && pPreNode->_pNext != pos)//pCurNode指向不为空且pCurNode->_pNext不等于pospPreNode = pPreNode->_pNext;//pCurNode指向下一节点if (NULL != pPreNode)//pCurNode下一节点是pos{pPreNode->_pNext = pos->_pNext;free(pos);pos = NULL;}}}// 移除单链表中第一个值为data的结点void Remove(PNode* pHead, DataType data){PNode pDelNode = NULL;assert(NULL != pHead);if (pDelNode = Find(*pHead, data))Erase(pHead, pDelNode);}// 移除单链表中所有值为data的结点void RemoveAll(PNode* pHead, DataType data){PNode pDelNode = NULL;assert(NULL != pHead);pDelNode = *pHead;if (NULL == *pHead)//链表为空return ;if (NULL == (*pHead)->_pNext) //链表只有一个节点{if ((*pHead)->_data == data)PopFront(pHead);}else{//思路:将本该删除的节点pDelNode替换为它的下一节点pTemp,然后释放pTemp。while (pDelNode->_pNext)if (pDelNode->_data == data){PNode pTemp = pDelNode->_pNext;pDelNode->_data = pTemp->_data;pDelNode->_pNext = pTemp->_pNext;free(pTemp);pTemp = NULL;}elsepDelNode = pDelNode->_pNext;}}//销毁链表void DestroyList(PNode *pHead){PNode pCurNode = NULL;assert(NULL == pHead);while (NULL != *pHead){PNode pTemp = *pHead;*pHead = (*pHead)->_pNext;free(pTemp);pTemp = NULL;}}///////////////////////////////////////// 在单链表中查找值为data的结点,找到了返回该结点的地址,否则返回NULLNode* Find(PNode pHead, DataType data){assert(NULL != pHead);while (pHead)if (pHead->_data == data)break;elsepHead = pHead->_pNext;return pHead;}// 获取单链表总结点的总个数size_t Size(PNode pHead){size_t n = 0;while (pHead) //当pHead不为空时{++n;pHead = pHead->_pNext;}return n;}// 判断结点是否为空int Empty(PNode pHead){if (pHead)//pHead不是空链表return 1;return 0;}// 返回单链表的最后一个结点的位置PNode Back(PNode pHead){if (NULL != pHead) //pHead不是空链表while (pHead->_pNext)pHead = pHead->_pNext;return pHead;}// 返回单链表的第一个结点的位置PNode Front(PNode pHead){return pHead;}// 正向打印单链表void PrintList(PNode pHead){PNode pCurNode = NULL;assert(NULL != pHead);pCurNode = pHead;while (pCurNode){printf("%d->", pCurNode->_data);pCurNode = pCurNode->_pNext;}printf("<null>\n");}
0 0
- 实现单链表及其基本操作
- 单链表及其基本操作(C语言实现)
- c语言实现单链表数据结构及其基本操作
- 单链表的存储结构及其基本操作的实现
- 带头节点的单链表及其基本操作(Java实现)
- 模拟单链表及其基本操作
- 排序二叉树实现及其基本操作
- 基本的字符串操作及其实现
- 线性表基本概念及其基本操作实现
- 字符串的基本操作及其实现
- 线性表的实现及其基本操作
- 队列的基本操作实现及其应用
- 单链表的存储结构及其基本操作
- 单链表的实现及其操作
- 堆-及其基本操作
- 单链表基本操作实现
- 单链表基本操作实现
- C语言实现单链表的基本操作及其部分面试题
- Java基础之反射机制
- 基于docker的hexo博客系统
- 《用python写网络爬虫》--寻找网站所有者
- ROS系列之初识gmapping
- 可变参数...
- 实现单链表及其基本操作
- WordPress插件 Pdf Premium PFD完美嵌入式专业版插件[更新至3.0.1]
- WordPress插件 WooCommerce最新微信支付接口集成插件
- 《用python写网络爬虫》--识别网站所用技术
- 大整数类
- css3的pointer-events属性
- swift3使用协议和泛型简化UITableView的使用
- Unity3D说明文档翻译-Mobile Keyboard
- Leetcode 21 Merge Two Sorted Lists