节点(结构体描述)

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. UWP RSA

    正确示例: var loginPBK = "";//your public key,such as "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQ ...

  2. Docker(3)- Centos 7.x 下 Docker 镜像加速配置

    如果你还想从头学起 Docker,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1870863.html 前言 默认情况下,Docker ...

  3. mysql千万级大数据SQL查询优化30条经验(Mysql索引优化注意)

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  4. 要求用户输入用户名和密码,只要不是admin、888888就

    要求用户输入用户名和密码,只要不是admin.888888就一直提示用户名或密码错误,请重新输入 Console.WriteLine("输入账号和密码"); string a = ...

  5. MySQL 的 join 功能弱爆了?

    大家好,我是历小冰,今天我们来学习和吐槽一下 MySQL 的 Join 功能. 关于MySQL 的 join,大家一定了解过很多它的"轶事趣闻",比如两表 join 要小表驱动大表 ...

  6. 经典c程序100例 1-10

    ==1--10 [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不 ...

  7. BATJTMD,大厂招聘,都招什么样Java程序员?

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 Java学到什么程度可以找工作? 最近总看到类似这样的问题,也有一些工作3年左右的小 ...

  8. VMware虚拟机 - 解决 Vmware 启动虚拟机报:该虚拟机似乎正在使用中。 如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权。否则,请按“取消(C)”按钮以防损坏的问题

    问题背景 当虚拟机仍然在运行时,直接关闭电脑,下次重开电脑并想重新启动虚拟机时报了下图问题 解决方案 进入虚拟机所在目录,把 .lck 后缀的文件都删完 Vmware 重新启动虚拟机 成功!!

  9. Vmware Tools is currently being installed on your system

    问题描述: 使用虚拟机安装Ubuntu过程中一直停留在"PLEASE WAIT! Vmware Tools is currently being installed on your syst ...

  10. Python_字符串_方法

    #字典#把字符串中的字母提取出来改为大写并计数 a="aAsmr3idd4bgs7Dlsf9eAF" b1=[x for x in a if x.isalpha()] b=''.j ...