链表操作实例(创建节点,增加节点,倒序链表,销毁链表等)
来源:互联网 发布:订单系统数据库设计 编辑:程序博客网 时间:2024/06/10 16:11
链表操作实例
该实例为:不断输入学生信息(学生姓名,性别,年龄,分数)后,打印输出所有的结果。其中用到了链表的初始化,创建,长度计算,增加节点,倒序链表内容等。这里简单介绍几个重要的链表操作函数。
完整代码下载地址:http://download.csdn.net/download/edroid1530/9671470
github下载地址:https://github.com/Edroid/student_linklist
一 简要了解
先简单了解一下链表的基础知识
什么是链表,书上给出的定义是:链表由一系列节点(链表中每一个元素称为节点)组成,节点可以在运行时动态生成。每个节点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个节点地址的指针域。如图:
我们首先定义一个结构体类型 link_note_t
typedef student_t Item;typedef struct link_node_s{ Item item; struct link_node_s *next;} link_node_t; /*--- end of struct link_node_s ---*/
下面我们先来弄清楚几个变量
link_node_t head; //head为结构体变量,其存放的是结构体内容,我们假设其地址为0x0001
link_node_t *head1; //head1 为结构体指针变量,其存放的是结构体的地址(0x0001),假设其本身地址为0x0008
link_node_t **head2; //head2为结构体指针的指针,其存放的是结构体指针变量的地址(0x0008),假设其本身地址为0x000b。
二,链表操作实例
1.统计链表长度,即链表中节点的个数。
int list_item_count(link_node_t *head) //传入形参为指向结构体的指针{ int count = 0; link_node_t *pnode = head; if(!head) //异常处理:如果链表为空,直接返回0 return 0; while(pnode != NULL)//链表不为空时,计算并返回count的值 { ++count; pnode = pnode->next; } return count;}
2.增加节点
向链表中添加新的节点,该其指针域的指针指向的是新的结构体变量
int list_add_item(link_node_t **head, Item item) //传入形参为指向节点的指针和新的结构体变量中的内容{ link_node_t *pnew; //定义新的结构体指针用来指向新的结构体 link_node_t *pnode = *head; //定义一个结构体指针用来找到尾节点 pnew = (link_node_t *)malloc(sizeof(*pnew));//开辟新的内存空间用来存放新的节点 if(pnew == NULL) return -1; memset(pnew, 0, sizeof(*pnew));//清空pnew,Memset 用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为‘ ’或‘/0’; pnew->item = item; if(NULL == *head) //如果第一个节点为空,则将头节点作为新的节点 { *head = pnew; } else //否则,找到链表中最后一个节点并设置其为新的节点 { while(pnode->next != NULL) { pnode = pnode->next; } pnode->next = pnew; } return 0;}
3.对链表中节点使用函数
void list_traverse(link_node_t *head, void (*pfunc)(Item item)) //传入形参为节点和函数指针{ link_node_t *pnode = head; while(pnode != NULL) { pfunc(pnode->item); pnode = pnode->next; }}说明:void (*pfunc)(Item item)为函数指针,该函数返回值为空,函数形参为结构体Item中的item
4.倒序链表中的内容
void link_reverse(link_node_t **head){ link_node_t *revsd_ptr; /* Last one time reversed linker pointer*/ link_node_t *cur_ptr; /* Currently need reverse node pointer*/ link_node_t *next_ptr; /* Next need revers node pointer*/ revsd_ptr = NULL; cur_ptr = *head; while( cur_ptr != NULL) { /* first circulating second circulating * Step1: * revsd */ cur next revsd cur next * | | | | | * NULL A -> B -> C -> D -> E NULL <- A B -> C -> D -> E next_ptr = cur_ptr->next; /* Step2: * revsd cur next revsd cur next * | | | | | * NULL <- A B -> C -> D -> E NULL <- A <- B C -> D -> E */ cur_ptr->next = revsd_ptr; /* Step3: * revsd cur/next revsd cur/next * | | | | * NULL <- A B -> C -> D -> E NULL <- A <- B C -> D -> E */ revsd_ptr = cur_ptr; cur_ptr = next_ptr; }
5.销毁链表
int list_destroy(link_node_t **head){ link_node_t *psave; while( *head )//当节点不为NULL时 { psave = (*head)->next; free(*head); //释放内存 *head = psave; }}
关于什么时候形参为节点(link_note_t *head),什么时候形参为节点地址(link_note_t **head) 的问题:
刚开始学链表的时候最难理解的地方就是形参的确定,不妨对比一下经典的swap函数
void swap(int *a, int *b){ int c; c = *a; *a = *b; *b =*a;}int main(void){ int a = 2,b = 3; swap(&a,&b); printf("%d,%d\n",a,b)}
只有给swap传入a, b 的地址的时候才能真正改变其内容本身,如果只是传入变量a,b本身,swap函数中改变的是形参也就是swap中的局部变量,并没有改变a,b本身的内容。对比一下就会发现,其实链表的操作也是一样的,如果涉及到链表本身内容的改变,我们需要传入节点的地址,即 link_note_t **head,如果不改变链表内容本身,则传入节点 link_note_t *head。
本人能力有限,以上只是个人学习链表之后的一个总结和看法,难免有错误之处。若发现错误欢迎指正,感激不尽。
0 0
- 链表操作实例(创建节点,增加节点,倒序链表,销毁链表等)
- 括链表的创建,增加、删除节点,链表的逆序、排序和销毁
- 倒序打印链表节点值
- java实现创建链表以及插入节点,查找结点,删除节点等操作
- 链表创建节点
- 链表节点的增加和删除
- C语言实现双向链表删除节点、插入节点、双向输出等操作
- javascript中dom节点操作(创建节点、增加节点、删除节点、克隆节点)
- 链表操作-创建、输出、删除,添加节点
- 链表中的添加节点和删除节点的操作
- 链表的创建以及链表节点的增加和删除
- C语言 链表的创建,以及节点的增加和删除
- 反转链表,取得链表中间值,增加节点操作
- java实现单链表(增加节点,删除节点,根据下标获取节点,获取链表大小,链表逆序)
- java实现单链表(增加节点,删除节点,根据下标获取节点,获取链表大小,链表逆序)
- c++之链表篇1:单向链表的创建,打印,删除,插入,销毁等基本操作
- 双向链表创建、删除某节点
- 链表----增加删除节点、链表反转、链表合并
- Linux电源管理-wakelock
- Struts2 学习笔记(2) 接受参数问题
- 第七天 使用Arrays类操作数组和方法的基本介绍
- 摄像头对焦Vuforia摄像机采集内容模糊
- Android Studio导出Jar包
- 链表操作实例(创建节点,增加节点,倒序链表,销毁链表等)
- 银行取款程序 线程
- MIT6.824 Lab 3: Fault-tolerant Key/Value Service (1)
- bzoj 1646: [Usaco2007 Open]Catch That Cow 抓住那只牛 bfs
- 安装ubuntu16.04遇到错误-->无法将grub-efi-amd64-signed软件包安装到/target/中
- 4-10 二分查找
- BZOJ 1578 [Usaco2009 Feb]Stock Market 股票市场
- HDU2209+POJ3279 枚举+dfs
- java singleton