单链表 就好比火车

火车头-->链表头部
火车尾-->链表尾部
火车厢-->链表的节点
火车厢连接的部分-->指针
火车中的内容-->链表节点的的数据
链表节点包含数据域和指针域
数据域存放数据
指针域存放要连接的节点的首地址

在造火车的时候 先是火车头 然后是车厢
--->链表的首节点和之后的节点

先从内存中申请头结点的存储空间
--->PLTST phead=(PLTST)malloc(sizeof(LTST));
首节点在创建时会让指针域指向空
--->既链表的初始化

链表连接的规则,要先连接后断开
对于单链表的插入有两种方法
1、头插法
2、尾插法(比较简单的)

尾插法 申请好一个新的节点后将链表的最后一个节点的指针域指向新节点

头插法 首先创建新节点,找到链表头节点,将指针指向新节点,将新节点指针指向第二节点

单链表测试代码笔记如下:

 #include<stdio.h>
#include <stdlib.h> //malloc 要用到 typedef struct Node
{
int data; //数据域:用来存放数据
struct Node* pNext; //指针域:用来存储下一个结点地址
}LIST,*PLIST; //1. 创建一个火车头. 相当于创建链表 =用函数来创建一个链表的头部
//创建链表的头部
PLIST CreateListHead()
{
//1.1 申请内存
PLIST phead = (PLIST)malloc(sizeof(LIST));
//1.2 判断是否申请成功
if (NULL == phead)
{
printf("头结点的内存申请失败!\n");
return NULL;
}
phead->pNext = NULL;
//phead->data 可以赋值也可以不赋值,因为头结点不存储数据
//.它只是用来标记链表的头部
//有表头的链表头结点都不存储数据,只是用来标记链表的头部
return phead;
} //2.写一个创建结点的函数,用来申请结点内存
PLIST CreateListNode(int data)
{
PLIST newNode = (PLIST)malloc(sizeof(LIST));
if (NULL == newNode)
{
printf("结点内存申请失败!\n");
return NULL;
}
newNode->pNext = NULL;
newNode->data = data;
return newNode;
} //3.插入一个结点 头部插入 指定位置插入 尾部插入
void InsertListHead(PLIST p_list, int data)//1. 要说明要插入的链表是哪一个 2.要插入的数据
{
//3.1 申请一个结点
PLIST node = CreateListNode(data);
//先连接后断开
node->pNext = p_list->pNext;
p_list->pNext = node;
} //4. 尾插法
void InsertListTail(PLIST p_list, int data)
{
//4.1 申请结点内存
PLIST node = CreateListNode(data);
//我们只知道链表的头部 尾部就要去遍历得到
PLIST p_Temp = p_list;
//遍历找到尾结点
while (p_Temp->pNext!=NULL) // 表达式非0就是真
{
p_Temp = p_Temp->pNext;
}
//循环结束 就是找到了最后一个结点
node->pNext = NULL;
p_Temp->pNext = node;
} //在链表p_list中的pos位置插入data
void InsertListAppoint(PLIST p_list, int pos, int data)
{
PLIST node = CreateListNode(data);
PLIST p_Temp1 = p_list;
PLIST p_Temp2 = p_list;
for (int i = ; i < pos; i++)
{
if (p_Temp1->pNext != NULL)
{
p_Temp1 = p_Temp1->pNext;
if (i>)
p_Temp2 = p_Temp2->pNext;
}
else
{ //如果pos大于链表结点的个数,就插入到尾部
p_Temp1->pNext = node;
node->pNext = NULL;
return; //退出函数 不往下执行
}
}
//循环结束 --> 说明我找到了我要插入的位置
node->pNext = p_Temp1;
p_Temp2->pNext = node; } // 遍历链表的每一个结点
void PrintList(PLIST p_list)
{
PLIST p_Temp = p_list->pNext; //从头部的下一个结点开始输出里面的数据
while (p_Temp)
{
printf("%d -> ", p_Temp->data);//打印结点里面的数据
p_Temp = p_Temp->pNext;
}
printf("NULL\n");
}
//删除 删除头结点 指定位置删除 尾部删除
//知道这个逻辑 多画图 多写代码
//后面还会有双向循环链表 要处理四个指针 现在只需要处理两个 双向循环链表不画图很难理解
//画图之后会发现很简单 只需要照着画的图去链接各个指针就OK了
void DeleteListHead(PLIST p_list) //PLIST p_list=head.
{
PLIST p_Temp = p_list->pNext;
//先链接还是先释放
p_list->pNext = p_Temp->pNext; //连接
free(p_Temp);
} //不用循环 删除所有结点
void DeleteList(PLIST p_list)//函数会执行5 5 4 3 2 1
{
//满足条件的情况下 自己调用自己
if (p_list->pNext!=NULL) //if括号里面不是0就是成立
{
DeleteList(p_list->pNext);
}
free(p_list); } int fun(int n)
{
if (n == )
{
return ;
}
else
{
return n + fun(n - );
} //5 +4+3+2+1 //函数嵌套调用
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
///内循环结束又回到了外循环
}
}
} int main()
{
PLIST head = CreateListHead(); //创建头部 把堆内存的首地址返回给head
for (int i = ; i <= ; i++)
InsertListHead(head, i);
PrintList(head); ////尾插法
//InsertListTail(head, 98);
//PrintList(head); ////指定位置插入
//InsertListAppoint(head, 2, 520);
//PrintList(head);
//InsertListAppoint(head, 88, 520);
//PrintList(head);
//DeleteListHead(head);
//PrintList(head); DeleteList(head);
PrintList(head);
head = NULL;
return ;
}

附:

C++学习(三十五)(C语言部分)之 单链表的更多相关文章

  1. Salesforce LWC学习(三十五) 使用 REST API实现不写Apex的批量创建/更新数据

    本篇参考: https://developer.salesforce.com/docs/atlas.en-us.224.0.api_rest.meta/api_rest/resources_compo ...

  2. Java开发学习(三十五)----SpringBoot快速入门及起步依赖解析

    一.SpringBoot简介 SpringBoot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化 Spring 应用的初始搭建以及开发过程. 使用了 Spring 框架后已经简化了我 ...

  3. python学习 (三十五) logging

    1  demo import logging # log level: # DEBUG # INFO # Warning # Error # CRITICAL logging.basicConfig( ...

  4. python学习三十五天函数递归的用法

    python函数递归就是自己调用自己,无限循环,但是python限制了调用的次数1000次,就会终止,递归用在栏目分类,采集程序比较多,下面简单说函数递归用法和实例 1,函数递归用法 def func ...

  5. 前端学习(三十五)模块化es6(笔记)

    RequireJs:一.安装.下载    官网: requirejs.org    Npm:  npm i requirejs二.使用    以前的开发方式的问题:        1).js 是阻塞加 ...

  6. Java开发学习(三十六)----SpringBoot三种配置文件解析

    一. 配置文件格式 我们现在启动服务器默认的端口号是 8080,访问路径可以书写为 http://localhost:8080/books/1 在线上环境我们还是希望将端口号改为 80,这样在访问的时 ...

  7. 风炫安全web安全学习第三十五节课 文件下载和文件读取漏洞

    风炫安全web安全学习第三十五节课 文件下载和文件读取漏洞 0x03 任意文件下载漏洞 一些网站由于业务需求,往往需要提供文件下载功能,但若对用户下载的文件不做限制,则恶意用户就能够下载任意敏感文件, ...

  8. “全栈2019”Java多线程第三十五章:如何获取线程被等待的时间?

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  9. “全栈2019”Java第三十五章:面向对象

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  10. 孤荷凌寒自学python第三十五天python的文件操作之针对文件操作的os模块的相关内容

     孤荷凌寒自学python第三十五天python的文件操作之针对文件操作的os模块的相关内容 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.打开文件后,要务必记得关闭,所以一般的写法应当 ...

随机推荐

  1. Code Pages

    https://docs.microsoft.com/en-us/windows/desktop/intl/code-pages Most applications written today han ...

  2. Perl新接触的小命令

    0,glob()函数 my @infile = glob("$indir/*.txt.gz");  #获得指定路径下的文件名,并形成列表,如果$indir为空,则自动匹配当前目录下 ...

  3. 字符串转换整数 (atoi)

    题目: 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我们寻找到的第一个非空字符为正或者负号时,则将该 ...

  4. 第 8 章 容器网络 - 063 - 如何使用 Weave 网络?

    如何使用 Weave 网络? weave 是 Weaveworks 开发的容器网络解决方案. weave 创建的虚拟网络可以将部署在多个主机上的容器连接起来. 对容器来说,weave 就像一个巨大的以 ...

  5. Ruby on Rails Tutorial 第一章笔记

    搭建开发环境 作者介绍了 Cloud9\ Coding.net 这样的云端开发环境 安装 Rails 1. 新建 rails 应用 首先,调用 rails new 命令创建一个新的 Rails 应用, ...

  6. nova相关操作的Request_Id的获取

    在分析nova的众多log文件时,如nova-api,nova-scheduler,nova-compute等,其中的request id是串联起整个flow的关键词. 而通过nova instanc ...

  7. 在ionic中使用短信验证码倒计时

    页面上 <button class="code" (click)="getCode()" [disabled]="!verifyCode.dis ...

  8. Node.js的缺陷

    Node.js最大的优点是事件机制,一切皆在回调中触发(不阻塞).我想缺点或许有正在于此,方法没有返回值,而只能在回调中使用返回结果,会导致事件回调嵌套,代码结构很差. 在jQuery中有一套很好的机 ...

  9. Android Studio酷炫插件(一)——自动化快速实现Parcelable接口序列化

    https://blog.csdn.net/kroclin/article/details/40902721 一.前言相信数据序列化大家都多多少少有接触到,比如自定义了一个实体类,需要在activit ...

  10. Descriptors;Hello1 project中的Web.xml

    Deployment Descriptors(描述符)是一个xml文件,用来描述如何部署一个模块或者应用(根据描述符中定义的配置和容器选项).举例来说,一个EJB的部署描述符会向EJB容器传递如何管理 ...