算法与数据结构-单向链表的基本操作C语言实现
来源:互联网 发布:网络arp攻击怎么办 编辑:程序博客网 时间:2024/05/18 19:18
序言
通过这篇文章熟悉单向链表的常用操作。
单链表的基本操作
- 链表定义和初始化
- 单链表创建并赋值
- 检查单链表是否为空
- 清空单链表
- 遍历单链表
- 返回单链表的长度
- 单链表查找元素
- 单链表查找第pos个节点
- 交换单链表中两元素的位置
- 单链表第pos个节点后元素
- 单链表第pos个节点删除
- 单链表逆置
- 在单链表末尾添加一个节点
- 有序单链表中插入元素element保持有序
1. 单链表定义
/* 定义1 */struct listNode{ int data; struct listNode *next;};/* 定义2:推荐 */typedef linkListNode{ int data; linkListNode *next;}listNode;
2. 单链表初始化
/* 不带头结点的链表 */void InitList(struct listNode *linkList){ *linkList = NULL;}/* 带头结点的链表 */void InitList(struct listNode *linkList){ linkList = (struct listNode *)malloc(sizeof(struct listNode) * 1); if (listNode == NULL) { printf("申请内存空间失败\n"); exit(1); } linkList -> next = NULL;}
3. 单链表创建并赋值
/* 创建一个单链表,并将数组元素顺序附给链表 *//* 单链表创建:尾插法 */void *ListCreate(struct listNode *linkList,int array[], int n){ //链表初始化 InitList(linkList); //指向尾节点的变量 + 节点变量 listNode *rear, *new; rear = *linkList; for (int i = 0; i < n; i++) { new = (struct listNode *)malloc(sizeof(struct listNode) * 1); new -> data = array[i]; rear -> next = new; rear = new; } rear -> next = NULL;}
注释:
(1)rear与linkList的关系:linkList是整个单链表,rear是指向尾节点的变量。rear会随着循环不断变化节点,而linkList则随着循环增长为一个多节点链表。
(2)rear和rear->next区分:是两个独立的指针。rear->next = new将尾节点指针指向新节点
rear = new将尾节点指向新节点
rear->next = NULL将链表指针域置空,以便以后遍历时确认其是链表尾部。
4. 检查链表是否为空
/* 检查链表是否为空,为空返回1,否则返回0 */int CheckListEmpty(struct ListNode *L){ if (L == NULL) return 1; else return 0;}
5. 清空单链表
/* 清空单链表,但仍保留head节点 */int EmptyList(struct listNode *L){ struct listNode *nodeScan, *nextNode; if (L == NULL) //链表为空 return 0; nodeScan = *L; while (nodeScan -> next != NULL) { nextNode = nodeScan -> next; free(nodeScan); nodeScan = nextNode; } L->next == NULL; return 1;}
6. 遍历单链表
void TraverseList(struct listNode *L){ struct listNode *nodeScan = *L; while (nodeScan != NULL) { printf("%d ", nodeScan -> data); nodeScan = nodeScan ->next; }}
7. 返回单链表的长度
int LengthOfList(struct listNode *L){ int len = 0; struct listNode *nodeScan = *L; while (nodeScan != NULL) { len++; nodeScan = nodeScan -> next; } return len;}
8. 单链表查找元素element
int FindEleInList(struct listNode *L, int element){ int pos = 0; //元素位置计数 struct listNode *nodeScan = *L; while (nodeScan != NULL) { pos++; if (element = nodeScan -> data) { return pos; } nodeScan = nodeScan -> next; } printf("element is not within this list!\n"); return 0;}
9. 单链表查找第pos个元素
//int NodeSearch()struct listNode *NodeSearch(struct listNode *L, int pos){ struct listNode *nodeScan = *L; int count = 1; if (pos == 1) return nodeScan -> data; while (count < pos) { count++; nodeScan = nodeScan -> next; if (nodeScan == NULL) { printf("node search error\n"); exit(1); } } return nodeScan; //return nodeScan -> data;}
10. 交换单链表中两元素的位置
void ExchangeNode(struct listNode *L, int i, int j){ if (i == j) return; struct listNode *Node1,*Node2,*tempNode; //节点临时存储空间申请(需要存储数据就需要申请空间) tempNode = (struct listNode *)malloc(sizeof(struct listNode) * 1); //节点提取 Node1 = NodeSearch(L, i); Node2 = NodeSearch(L, j); //节点元素值交换 tempNode -> data = Node1 -> data; Node1 -> data = Node2 -> data; Node2 -> data = tempNode -> data; }
11. 单链表第pos个节点后元素
int NodeInsertion(struct listNode *L, int pos, int element){ int count = 1; struct listNode *nodeScan = *L; struct listNode *newNode = NULL; struct listNode *originNode = NULL; while (count != pos) { count++; nodeScan = nodeScan -> next; originNode = nodeScan -> next; } //创建新节点 newNode = (strcut listNode *)malloc(sizeof(struct listNode) * 1); if (newNode == NULL) { printf("node allocate failed\n"); return 0; } newNode -> data = element; //新节点 nodeScan -> next = newNode; newNode -> next = originNode; return 1;}
12. 单链表第pos个节点删除
int DeleteListNode(struct listNode *L, int pos){ int count = 1; struct listNode *nodeScan = *L; struct listNode *originNode= NULL; while (count != pos) { count++; originNode = nodeScan; nodeScan = nodeScan -> next; if (nodeScan == NULL) printf("pos is beyond max len of List\n"); } originNode -> next = nodeScan -> next; int temp = nodeScan -> data; free(nodeScan); return temp;}
13. 单链表逆置
/* 单链表逆置:加入原链表1->2->3->4,逆置后4->3->2->1 *///本文都是基于不带头结点的链表进行操作的void InvertList(struct listNode *L){ struct listNode *nodeScan = *L; //搜索节点 struct listNode *nextNode = nodeScan -> next; //下一节点 struct listNode *tempNode = NULL; //暂存节点 nodeScan -> next = NULL; //首节点next指向NULL while (nextNode != NULL) { tempNode = nextNode -> next; //暂存下一节点的next指针 nextNode -> next = nodeScan; //回指上一节点 //搜索节点和下一节点依次往后挪动一个 nodeScan = nextNode; nextNode = tempNode; }}
14. 在单链表末尾添加一个节点
void AddNodeInEnd(struct listNode *L, int element){ struct listNode *nodeScan = *L; struct listNode *newNode = NULL; newNode = (struct listNode *)malloc(sizeof(struct listNode) * 1); newNode -> data = element; newNode -> next = NULL; while (nodeScan -> next != NULL) { nodeScan = nodeScan -> next; } nodeScan -> next = newNode; //查找链表结尾并元素}
15. 有序单链表中插入元素element,保持有序
void AddItemToSeqList(struct listNode *L, int element){ struct listNode *newNode; newNode = (struct listNode *)malloc(sizeof(struct listNode) * 1); if (newNode == NULL) { printf("mem alocate failed\n"); exit(1); } newNode -> data = element; //比首节点元素还小,插入到链表头之前 if (L == NULL || (L -> data > element) { newNode -> next = L; L = newNode; return; } //查找插入位置 struct listNode *nodeScan = *L; struct listNode *preNode = NULL; while (nodeScan != NULL) { preNode = nodeScan; nodeScan = nodeScan -> next; } //将元素插入到preNode和nodeScan之间 preNode -> next = newNode; newNode -> next = nodeScan;}
Acknowledgements:
http://blog.csdn.net/tuwenqi2013/article/details/51800381
http://blog.csdn.net/bzhxuexi/article/details/41721429
http://blog.csdn.net/sh_frankie/article/details/48577927
http://blog.csdn.net/lzuacm/article/details/7437852
http://blog.csdn.net/guoyong10721073/article/details/9009625
http://www.cnblogs.com/Camilo/p/3927912.html(推荐)
2017.08.12
文章错误和不足之处,欢迎讨论交流。
阅读全文
0 0
- 算法与数据结构-单向链表的基本操作C语言实现
- 单向链表的C语言实现与基本操作
- 《数据结构与算法》-单链表基本操作的C语言实现
- 算法与数据结构-堆的基本操作C语言实现
- 算法与数据结构-队列的基本操作C语言实现
- 算法与数据结构-栈的基本操作C语言实现
- 算法与数据结构-堆的基本操作C语言实现
- <数据结构与算法>单向循环链表基本框架(C语言描述)
- 单向链表基本操作(C语言实现)
- 最基本的单向链表操作 C语言
- C语言实现,无头结点不带环的单向链表的基本操作
- 算法与数据结构-二叉树的基本操作C语言实现
- 数据结构与算法分析-单向链表的实现
- 数据结构C语言实现线性表(顺序实现)的初始化与基本操作
- C-单向链表的基本操作
- 数据结构——单向链表的基本操作C语言描述(克服对头结点和尾结点的操作)
- 数据结构学习之单向链表的基本操作(非递归实现)
- 数据结构(1):单向链表的基本操作
- java 内省机制与反射机制 的区别
- [交互题][二分]Codeforces#415 (Div. 1) 809B. Glad to see you!
- 连个div显示在一行,前者给定宽度,后者沾满屏幕剩余的宽度
- 关于APP进程被杀死,极光推送收不到消息的解决办法
- 线程状态与停止
- 算法与数据结构-单向链表的基本操作C语言实现
- POJ1511-Invitation Cards-最短路
- HTTP中的重定向和请求转发的区别
- Java实现高并发的处理的方式
- jdbc参数量、subList、jsp卡
- The 3n + 1 problem
- Python中reduce与lambda的结合使用
- zoj3609----Modular Inverse (扩展欧几里德)
- JavaScript离线应用与客户端存储