数据结构之单链表(C语言实现)
来源:互联网 发布:怎么查看网络拨号密码 编辑:程序博客网 时间:2024/05/01 15:10
数据结构之单链表(C语言实现)
本次介绍三种单链表:普通单链表、循环链表和双向链表,后面的博客会继续介绍后两种链表
首先介绍单链表的特点:
1.链表是由一个个内存地址不连续的节点组成
2.每个节点最多只有一个前驱,一个后记(第一个节点只有后继没有前驱,最后一个节点只有前驱没有后继)
3.链表不支持随机存取(意思就是不能通过下标来进行找某个节点,只能从头到尾进行遍历)
4.链表的查找只能从头到尾对链表进行遍历,时间复杂度为O(n);而顺序表查找元素只要给一个下标即可,时间复杂度为O(1)
5.删除链表的某个节点时只需改变节点的指针,不需要移动大量元素
然后从三个方面来介绍三种链表的通用操作:
1.链表的初始化
2.申请一个链表节点
3.链表的头插法
4.链表的尾插法
5.获取链表长度
6.删除链表节点
7.查找指定值的节点
8.销毁链表(释放链表所有节点的内存空间)
9.输出单链表(输出单链表所有节点的数据域)
说明:以下单链表的实现,是数据域以整型为例,而且带有头结点。
一、普通单链表
1.单链表的结构
typedef struct _Node
{
int data;//数据域
struct _Node* next;//指针域
}Node, *List;
2.链表的操作
(1)链表的初始化(带头结点)
这里的初始化只要是指初始化头结点的指针域
void InitList(List plist){if (NULL == plist)return;plist->next = NULL;}
(2).申请一个链表节点
从堆中申请一个节点,注意这里是从堆中申请的内存,只能通过free(p)显式释放内存。即使是局部变量,该内存也不会随着函数调用完成而释放该内存。
static Node* BuyNode(int val){Node* pTmp = (Node*)malloc(sizeof(Node));pTmp->next = NULL;return pTmp;}
(3).链表头插法
这里的链表是带有头结点的,所以每次新插入的节点应插入头结点后面。
void InsertHead(List plist, int val){Node *pTmp = BuyNode(val);//申请一个节点,数据域为valpTmp->next = plist->next;plist->next = pTmp;}
(4).链表尾接法
每次将新插入的节点插入到最后一个节点后面,所以采用尾接法插入节点时首先要找到尾节点
void InsertTail(List plist, int val){Node *pTmp = BuyNode(val);Node *pCur;for (pCur = plist; NULL != pCur; pCur = pCur->next)//查找尾节点{;//空语句}pCur->next = pTmp;//将新节点插入到尾节点之后}
(5).获取链表长度
对链表进行遍历,每遍历一个节点,计数器加一。
int GetListLen(List plist){Node *pTmp = plist->next;int iCount = 0;while (NULL != pTmp){++iCount;pTmp = pTmp->next;}return iCount;}
(6).删除链表节点
删除指定值的链表节点时,需要遍历该链表,找到对应节点后想要删除该节点必须要知道该节点的前驱节点,这样才能正确删除该节点。
bool Delete(List plist, int val){Node* pPre = plist;//指向前驱节点Node* pCur = plist->next;//指向当前比较的节点while (NULL != pCur)//当链表没找完就继续找{if (pCur->data != val)//链表没找到就更新当前节点和它的前驱节点{pPre = pCur;//更新前驱节点为当前节点pCur = pCur->next;//更新当前节点为下一个节点}else{pPre->next = pCur->next;free(pCur);//释放待删节点的内存return true;//找到该节点返回true}}return false;}
(7).查找指定值的节点
查找指定值的节点也需要从头到尾遍历链表,若找到则返回该节点,没找到则返回NULL。
Node* Search(List plist, int val){Node *pCur = plist->next;while (NULL != pCur){if (pCur->data == val){return pCur;}pCur = pCur->next;}return NULL;}
(8).销毁链表
销毁链表就是释放链表中所有节点的内存。
void Destroy(List plist){Node* pCur = plist->next;//注意销毁链表后头结点的内存空间还是存在的,即空链表就是只有一个头结点的单链表while (NULL != pCur){plist = pCur->next;free(pCur);pCur = plist->next;}}
(9).输出单链表
输出单链表的操作也比较简单,从头到尾遍历单链表,每遍历一个节点就输出该节点的指针域
void Show(List plist){Node* pCur = plist->next;while (NULL != pCur){printf("%5d", pCur->data);pCur = pCur->next;}printf("\n");}
最后附上完整代码和运行结果:
//Link.h#include<stdio.h>#include<stdlib.h>typedef struct _Node{int data;struct _Node* next;}Node, *List;void InitList(List plist);void InsertHead(List plist, int val);void InsertTail(List plist, int val);bool Delete(List plist, int val);Node* Search(List plist, int val);int GetListLen(List plist);void Destroy(List plist);static Node* BuyNode(int val);void Show(List plist);
//Link.c#include "test.h"int main(){Node head;InitList(&head);for (int i = 0; i < 13; ++i){InsertTail(&head, i);//尾插法}ShowList(&head);printf("链表长度:%d\n", GetListLen(&head));for (int i = 0; i < 12; ++i){InsertHead(&head, i);//头插法}ShowList(&head);printf("链表长度:%d\n", GetListLen(&head));printf("search 12:\n");Node *p = Search(&head, 12);//查找节点if (p != NULL){printf("%d\n", p->data);}else{printf("Not Found\n");}printf("删除节点12:\n");//删除节点if (Delete(&head, 12)){ShowList(&head);}else{printf("链表中无此节点\n");}Destroy(&head);//销毁链表return 0;}void InitList(List plist){if (NULL == plist)return;plist->next = NULL;}void InsertHead(List plist, int val){Node *pTmp = BuyNode(val);pTmp->next = plist->next;plist->next = pTmp;}void InsertTail(List plist, int val){Node *pTmp = BuyNode(val);Node *pCur;for (pCur = plist; NULL != pCur->next; pCur = pCur->next){;//空语句}pCur->next = pTmp;}bool Delete(List plist, int val){Node* pPre = plist;Node* pCur = plist->next;while (NULL != pCur){if (pCur->data != val){pPre = pCur;pCur = pCur->next;}else{pPre->next = pCur->next;free(pCur);return true;}}return false;}Node* Search(List plist, int val){Node *pCur = plist->next;while (NULL != pCur){if (pCur->data == val){return pCur;}pCur = pCur->next;}return NULL;}int GetListLen(List plist){Node *pTmp = plist->next;int iCount = 0;while (NULL != pTmp){++iCount;pTmp = pTmp->next;}return iCount;}void Destroy(List plist){Node* pCur = plist->next;//注意销毁链表后头结点的内存空间还是存在的,即空链表就是只有一个头结点的单链表while (NULL != pCur){plist = pCur->next;free(pCur);pCur = plist->next;}}static Node* BuyNode(int val){Node* pTmp = (Node*)malloc(sizeof(Node));pTmp->next = NULL;pTmp->data = val;return pTmp;}void ShowList(List plist){Node* pCur = plist->next;while (NULL != pCur){printf("%5d", pCur->data);pCur = pCur->next;}printf("\n");}
- 数据结构之单链表(C语言实现)
- 数据结构之单链表C语言实现
- 数据结构C语言之单链表简单实现
- 数据结构C语言实现之单链表
- 数据结构c语言实现之单链表
- 数据结构c语言实现之静态单链表
- 数据结构之---c语言实现单链表
- 【数据结构之C语言实现】单链表
- 数据结构之单链表的C语言实现
- 数据结构之栈(C语言实现)
- 数据结构之 队列(C语言实现)
- 数据结构之 栈(C语言实现)
- 数据结构之数组(C语言实现)
- 数据结构之循环单链表(C语言实现)
- 数据结构之---C语言实现括号匹配(栈实现)
- 数据结构.单链表(C语言实现)
- 数据结构--单链表c语言实现
- 【数据结构】C语言实现单链表
- 排序算法---直接插入排序和希尔排序
- Struts2—拦截器实现权限控制
- [J2SE基础篇]~类继承,static静态变量内存解析
- 数据结构实验之图论八:欧拉回路
- HDU 1001 Sum Problem
- 数据结构之单链表(C语言实现)
- 在 Excel 中以编程方式复制工作表会导致运行时错误 1004
- linux(CentOS)安装redis (多图)
- C++中容器迭代器删除失效问题
- 学习1——MongDB安装
- POJ 1364 King(差分约束系统+bellmanford)
- windows核心编程-句柄的获取与复制
- ECSHOP后台getshell漏洞
- 把图片转换成视频-ffmpeg