节点(结构体描述)

struct Node {
int _id;
char s[50];
struct Node* pre;// 指向前一个节点的地址
struct Node* next;// 指向下一个节点的地址
};

新建节点(开辟内存空间)

参数: 为新节点id字段赋值

返回值:新节点的地址(指针)

struct Node* node_new(int id) {
struct Node* q = (struct Node*)malloc(sizeof(struct Node));
memset(q, 0, sizeof(struct Node));
q->_id = id;
return q;
}

添加节点

如果只有一个节点,不用添加


在最后追加节点

/*
* 为链表追加节点(加在最后)
* 参数:头节点,需要追加的节点
* 返回值:无
*/
void chain_add(struct Node* qFirst, struct Node* qAdd) {
// 定位到链表头
struct Node* q = qFirst;
// 只要后面(next)有节点,往后找;直到没有next的节点(最后一个)
for(q; q->next != NULL; q=q->next ) {
node_print(q);
}
// 此时定位在最后一个节点,下图1
// 将新节点加在最后节点的后面(next)
q->next = qAdd;// 下图2
qAdd->pre = q;//下图3
}

图1 定位到最后的节点:

图2 最后节点的next指向新节点:

图3 新节点的preview指针指向(前)最后节点:


计算链表中节点的个数

/*
* 获取链表长度(即节点的个数)
* 参数:头节点
* 返回值:链表长度
*/
int chain_count(struct Node* qFirst) {
if (qFirst == NULL) {
// 头节点都没有,长度为0
return 0;
}
int i = 0;
// 遍历链表
struct Node* q = qFirst;
for(q; q != NULL; q=q->next) {
// 顺藤摸瓜,直到最后一个节点
i++;// 找到一个就+1
}
return i;
}

获取节点(仿数组按序号查找,从0开始)

struct Node* chain_get(struct Node* qFirst, int index) {
printf("---获取index = %d的节点:", index);
int i = 0;
// 遍历链表
struct Node* q = qFirst;
for(q; q!= NULL; q=q->next,i++ ) {
if (index == i) {
return q;
}
}
return NULL;
}

打印节点

void node_print(struct Node* q) {
if (NULL == q) {
puts("节点打印:空节点,无可打印");
return;
}
printf("---id = %2d---", q->_id);
printf("preview = %10d ", q->pre);
printf("【address = %10d】 ", q);
printf("next = %10d\n", q->next);
}

打印链表

void chain_print(struct Node* qFirst) {
if (qFirst == NULL) {
puts("没有元素可以打印");
return;
}
puts("----------↓↓↓打印链表------------");
// 遍历链表
struct Node* q;
for(q = qFirst; q != NULL; q=q->next ) {
node_print(q);
}
puts("----------↑↑↑打印链表------------");
}

删除节点

自定义函数:释放空间

节点指针是要置空的,在函数中改指针的指向,需要使用二级指针

void node_free(struct Node** q) {
if( *q != NULL) {
printf("free %d\n",(*q)->_id);
free(*q);
*q = NULL;
}
}

删除节点

图4 删除头结点

图5 删除中间节点

图6 删除尾节点

1.定位到尾节点,找到其前一节点(倒数第二个节点,即将来的尾节点)

2.倒数第二节点的next节点置空

3.释放掉最后的节点

/*
* 删除节点
* 参数:1.头结点 2.待删除的结点
* 因为被删除的结点需要置空,所以需要使用二级指针
* 返回值:-1 删除失败/0 删除成功
*/
int chain_remove(struct Node** qFirst, struct Node** qRemove) {
struct Node* qPre = NULL;
struct Node* qNext = NULL;
struct Node* q = *qFirst; // 1.输入Check
if(NULL == *qRemove){
puts("删无可删!");
return -1;
}else{
printf("删除节点:id=%d\n", (*qRemove)->_id);
} // 2.删除头结点,特殊对待
if(*qFirst == *qRemove ) { if((*qFirst)->next == NULL){
// 就一个头结点的场合
node_free(qFirst);
}else{
qNext = q->next;
node_free(qFirst);
*qFirst = qNext;
}
return 0;
}
// 3.遍历链表
for(q; q != NULL; q=q->next ) {
if (q == *qRemove) {
qPre = q->pre;
qNext = q->next; if (qNext!=NULL) {
qNext->pre = qPre;
qPre->next= qNext;
} else {
// 尾节点的场合
qPre->next= NULL;
}
node_free(qRemove);
return 0;
}
}
}

清空链表

void chain_clear(struct Node** qFirst) {
puts("\n----------Clear------------"); if (qFirst == NULL) {
puts("已经是空");
return;
} // 遍历链表
// 不断删除第一个元素
while(*qFirst != NULL) {
chain_remove(qFirst,qFirst);
}
}

C语言讲义——链表的实现的更多相关文章

  1. C语言讲义——链表完整代码

    #include <stdio.h> #include <stdlib.h> #include <string.h> struct Node { int _id; ...

  2. C语言之链表

    这两天在复习C语言的知识,为了给下个阶段学习OC做准备,以下的代码的编译运行环境是Xcode5.0版本,写篇博文把昨天复习的C语言有关链表的知识给大家分享一下,以下是小菜自己总结的内容,代码也是按照自 ...

  3. C语言习题 链表建立,插入,删除,输出

    Problem B: C语言习题 链表建立,插入,删除,输出 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 222  Solved: 92 [Subm ...

  4. YTU 2430: C语言习题 链表建立,插入,删除,输出

    2430: C语言习题 链表建立,插入,删除,输出 时间限制: 1 Sec  内存限制: 128 MB 提交: 576  解决: 280 题目描述 编写一个函数creatlink,用来建立一个动态链表 ...

  5. 关于c语言单项链表尾添加

    犹豫了几天,看了很多大牛写的关于c语言链表,感触很多,终于下定决心,把自己对于链表的理解随之附上,可用与否,自行裁夺.由于作者水平有限也是第一次写,不足之处,竭诚希望得到各位大神的批评指正.制作不易, ...

  6. C语言之链表list

    #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h& ...

  7. C语言:链表实现的一个实例

    问题:写一个程序输入你一年看过的所有电影以及每部电影的各种信息(简化问题:每部电影只要求输入片名和评价) 链表实现: #include<stdio.h> #include<stdli ...

  8. C语言单链表实现19个功能完全详解

    谢谢Lee.Kevin分享了这篇文章 最近在复习数据结构,想把数据结构里面涉及的都自己实现一下,完全是用C语言实现的. 自己编写的不是很好,大家可以参考,有错误希望帮忙指正,现在正处于编写阶段,一共将 ...

  9. (转)c语言_链表实例讲解(两个经典例子)

    建立一个学生成绩的线性链表,对其实现插入,删除,输出,最后销毁. #include <stdio.h>#include <stdlib.h> struct grade {    ...

随机推荐

  1. F. Moving Points 解析(思維、離散化、BIT、前綴和)

    Codeforce 1311 F. Moving Points 解析(思維.離散化.BIT.前綴和) 今天我們來看看CF1311F 題目連結 題目 略,請直接看原題. 前言 最近寫1900的題目更容易 ...

  2. D. Kilani and the Game 解析(裸BFS、實作)

    Codeforce 1105 D. Kilani and the Game 解析(裸BFS.實作) 今天我們來看看CF1105D 題目連結 題目 給一個\(n\times m\)的地圖,地圖上有幾種格 ...

  3. Azure Data Factory(三)集成 Azure Devops 实现CI/CD

    一,引言 由于上一节文章内容过长,无法分享Azure Data Factory 的持续集成,持续发布.今天将着重介绍一下在使用 Azure DevOps Pipeline 发布,自动进行持续集成,并且 ...

  4. 【CF1443F】Identify the Operations 题解

    原题链接 题意简介 建议去原题看.这题意我表达不清楚. 大概就是给你一个 n 的排列,现在要求你进行 m 次操作. 每次操作,你会在现有的排列中删去一个数,然后选择其左边或右边的一个与之相邻的数加入 ...

  5. 【kata Daily 190905】What's a Perfect Power anyway?(完美幂)

    原题: A perfect power is a classification of positive integers: In mathematics, a perfect power is a p ...

  6. 三分钟快速解析GraphQL基本工作思路!

    欢迎阅读 本文会通过实际场景介绍一下 GraphQL,目的是让你快速了解 GraphQL 是什么,以及基本工作思路,不包含实际用法,所以阅读很轻松. 一.GraphQL 是什么? GraphQL 是后 ...

  7. http服务器文件名大小写忽略

    问题 文件从windows里面放到nginx里面去的时候,文件在windows下面是大小写忽略,也就是不论大小写都可以匹配的,而到linux下面的时候,因为linux是区分大小写的,也就是会出现无法忽 ...

  8. ubuntu无法关机

    在/etc/default/halt 增加下面 INIT_HALT = POWEROFF 另一种方法: I have the same problem and found a solution whi ...

  9. Spring之事务源码

    对@Transactional注解的类进行动态代理 同前文<Spring AOP源码分析>中分析动态代理入口一样,都是在initializeBean时执行. Object exposedO ...

  10. Nacos服务发现源码解析

    1.Spring服务发现的统一规范 Spring将这套规范定义在Spring Cloud Common中 discovery包下面定义了服务发现的规范 核心接口:DiscoveryClient 用于服 ...