听黑马程序员教程《基础数据结构和算法 (C版本)》,照着老师所讲抄的,

视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1

喜欢的朋友可以去看看。

02 单向链表

#include<stdio.h >
#include<stdlib.h>
#include<string.h> // 用户自定义数据
typedef struct Student{
int id; // 学号
char name[32]; // 姓名
char classs[32]; // 班级
int ch,ma,en; // 语、数、外、总分
}st; // 链表结点
typedef struct LINKNODE{
//int i_data; // 这样写就写死了,只能放int数据了,
void* data; // void* 是无类型指针,可以指向任何类型的数据。
struct LINKNODE* next;
}LinkNode; // 链表结构体
typedef struct LINKLIST{
LinkNode* head; // 头结点
int size; // 链表节点数
// 要像动态数组一样需要内存容量吗?不需要, 没有容量概念。
}LinkList; // 打印函数指针
typedef void(*PRINTLINKNODE)(void*); // -----------------------------------------------------------------------------
// 下面函数,就是针对上面链表结构体和结点的操作。
// ----------------------------------------------------------------------------- // 初始化链表 ,返回一个链表结构体
LinkList* Init_LinkList(); // 指定位置插入。参数:所插入的链表,位置,值
void Insert_LinkList(LinkList* list,int pos,void* data); // 删除指定位置的值。 参数:链表,位置
void RemoveByPos_LinkLIst(LinkList* list,int pos); // 获得链表的长度(结点数量)
int Size_LinkList(LinkList* list); // 根据值,查找位置
int Find_LinkList(LinkList* list,void* data); // 返回第一个节点
void* Front_LinkList(LinkList* list); // 打印链表结点
void Print_LinkList(LinkList* list,PRINTLINKNODE print); // 释放内存
void FreeSpace_LinkList(LinkList* list); // ----------------------------------- main() -------------------- // 打印函数
void MyPrint(void* data){
st* p = (st*)data;
printf("学号:%d\t姓名:%s\t班级:%s\t语文%d\t数学%d\t英语%d\t总分%d\n",
p->id,p->name,p->classs,p->ch,p->ma,p->en,p->ch+p->ma+p->en);
}
int main(){
printf("好好学习,天天向上~!(单向链表20220603)\n\n"); // 创建链表
LinkList* stList = Init_LinkList(); // 创建数据
st st1 = {2001,"宗宗","364班",100,100,100};
st st2 = {2002,"艳艳","364班",99,88,59};
st st3 = {2003,"发发","364班",88,77,66};
st st4 = {2004,"小小","364班",58,57,55};
st st5 = {2005,"小五","364班",58,57,55}; // 插入数据
Insert_LinkList(stList,0,&st1);
Insert_LinkList(stList,0,&st2);
Insert_LinkList(stList,0,&st3);
Insert_LinkList(stList,0,&st4);
Insert_LinkList(stList,0,&st5); // 打印
Print_LinkList(stList,MyPrint); printf("\n删除第3个节点\n");
RemoveByPos_LinkLIst(stList,3);
// 打印
Print_LinkList(stList,MyPrint); printf("\n返回第一个节点\n");
// 返回的是void* 类型,要转换成st*类型
st* ret = (st*)Front_LinkList(stList);
printf("学号:%d\t姓名:%s\t班级:%s\t语文%d\t数学%d\t英语%d\t总分%d\n",
ret->id,ret->name,ret->classs,ret->ch,ret->ma,ret->en,ret->ch+ret->ma+ret->en); // 销毁释放
FreeSpace_LinkList(stList);
return 0;
} // -----------------------------------------------------------------------------
// 下面函数,就是针对上面链表结构体和结点的操作。
// ----------------------------------------------------------------------------- // 初始化链表 ,返回一个链表结构体
LinkList* Init_LinkList(){
LinkList* list = (LinkList*)malloc(sizeof(LinkList));
list->size = 0;
// 添加头节点,头节点不保存数据
list->head = (LinkNode*)malloc(sizeof(LinkNode));
list->head->next = NULL; // 头结点初始化一下 return list;
} // 指定位置插入。参数:所插入的链表,位置,值(是数据指针)
void Insert_LinkList(LinkList* list,int pos,void* data){ // 判断检查参数
if(list==NULL){
return;
}
if(data==NULL){
return;
}
if(pos<0 || pos > list->size){ // 友好判断,如果位置pos越界,由插入到尾部
pos = list->size;
} // 创建新的节点
LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
newNode->data = data; // 新节点赋值 // 找结点
LinkNode* pCurrent = list->head; // 辅助指针,用于找当前节点(插入位置的前一个节点)
int i;
for(i=0;i<pos;i++){ // 通过循环找到插入位置的前一个节点
pCurrent = pCurrent->next;
}
// 插入
newNode->next = pCurrent->next;
pCurrent->next = newNode; list->size++; // 更新节点数量的记录。 } // 删除指定位置的值。 参数:链表,位置
void RemoveByPos_LinkLIst(LinkList* list,int pos){
// 判断检查参数
if(list==NULL){
return;
}
if(pos<0 || pos >= list->size){
//pos = list->size; // 这里就不能友好判断了,
return; // 指定位置不存在,直接返回。
} // 删除
// 找结点
LinkNode* pCurrent = list->head; // 辅助指针,用于找当前节点(删除节点的前一个节点)
int i;
for(i=0;i<pos;i++){ // 通过循环找到要删除结点的前一个节点
pCurrent = pCurrent->next;
}
// 删除(先缓存要删除的节点)
//pCurrent->next = pCurrent->next->next;
//free(pCurrent->next);
LinkNode* pDel = pCurrent->next;
pCurrent->next = pDel->next;
free(pDel);
list->size--; // 更新链表节点数量 } // 获得链表的长度(结点数量)
int Size_LinkList(LinkList* list){ return -1;
} // 根据地址,查找位置,void* data 是地址(指针),不是值。
int Find_LinkList(LinkList* list,void* data){
// 判断检查参数
if(list==NULL){
return -1;
}
if(data==NULL){
return -1;
} // 遍列查找节点,从头节点的下一个节点开始找
LinkNode* pCurrent = list->head->next;
int i = 0;
while(pCurrent){
if(pCurrent->data==data){
break;
}
pCurrent = pCurrent->next;
i++;
} return i;
} // 返回第一个节点
void* Front_LinkList(LinkList* list){
return list->head->next->data;
} // 打印链表结点
void Print_LinkList(LinkList* list,PRINTLINKNODE print){
if(list==NULL){
return;
}
// 辅助指针变量
LinkNode* pCurrent = list->head->next;
while(pCurrent){
print(pCurrent->data); // 调用用户函数,传入数据参数
pCurrent = pCurrent->next;
} } // 释放内存
void FreeSpace_LinkList(LinkList* list){
if(list==NULL){
return;
}
// 辅助指针变量
LinkNode* pCurrent = list->head;
while(pCurrent){ // 循环释放节点内存。
LinkNode* pNext = pCurrent->next; // 用指针先记录下一个节点,如果不记录的话,释放内存后就没有了,
free(pCurrent);
pCurrent = pNext;
}
free(list); // 节点内存释放完毕后,再释放链表内存
}

C语言 - 基础数据结构和算法 - 单向链表的更多相关文章

  1. C语言 - 基础数据结构和算法 - 企业链表

    听黑马程序员教程<基础数据结构和算法 (C版本)>,照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友可 ...

  2. C语言- 基础数据结构和算法 - 循环链表

    听黑马程序员教程<基础数据结构和算法 (C版本)>,照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友可 ...

  3. C语言- 基础数据结构和算法 - 栈的顺序存储

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  4. C语言- 基础数据结构和算法 - 09 栈的应用_中缀表达式转后缀表达式20220611

    09 栈的应用_中缀表达式转后缀表达式20220611 听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/ ...

  5. C语言- 基础数据结构和算法 - 08 栈的应用_就近匹配20220611

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  6. C语言- 基础数据结构和算法 - 队列的顺序存储

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  7. C语言- 基础数据结构和算法 - 栈的链式存储

    听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友 ...

  8. C语言- 基础数据结构和算法 - 动态数组

    听黑马程序员教程<基础数据结构和算法 (C版本)>,照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友可 ...

  9. JS数据结构与算法--单向链表

    链表结构:链表中每个元素由一个存储元素本身的节点和一个指向下一元素的引用组成.如下所示(手画的,比较丑,懒得用工具画了,嘻嘻) 1.append方法,向链表末尾插入一个节点 2.insert(posi ...

随机推荐

  1. Javascript中数组的判断方法

    摘要: 1.数组检测的方法: 1) typeof . 2) instanceof . 3) constructor . 4) Object.prototype.toString. 5) Array.i ...

  2. Struts2-day2总结

    一.结果页面配置 1.全局结果页面 2.局部结果页面 ****注:如果同时配置了全局页面和局部页面配置,那么最终将以局部为准 result标签当中的type属性 默认值:dispatcher做转发 r ...

  3. LC-202

    编写一个算法来判断一个数 n 是不是快乐数. 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和. 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 ...

  4. Java核心知识1:泛型机制详解

    1 理解泛型的本质 JDK 1.5开始引入Java泛型(generics)这个特性,该特性提供了编译时类型安全检测机制,允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,即给类型指定一个参 ...

  5. Codeforces Round #754 (Div. 2), problem: (A) A.M. Deviation泪目 万万没想到狂wa是因为这

    Problem - A - Codeforces 题目 题意很简单每次操作可以使得a1 a2  a3任意两个数分别+1  -1 求最后使得a+c-2b绝对值的最小值 BUG就是最后忽略了-2和2这一点 ...

  6. 算法基础⑨搜索与图论--存在负权边的最短路--bellman_ford算法

    bellman-ford算法 给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环, 边权可能为负数. 请你求出从 1 号点到 n 号点的最多经过 k 条边的最短距离,如果无法从 1 号点走到 ...

  7. JavaScript学习基础2

    ##JavaScript基本对象 1 .function:函数(方法)对象 * 创建: 1.var fun =new Function(形式参数,方法体): 2.function 方法名(参数){ 方 ...

  8. 【阿里巴巴Java开发手册1.7.0(嵩山版)】编程规约&MySQL 数据库规约

    阿里巴巴Java开发手册1.7.0(嵩山版) 一.编程规约 (一)命名风格 所有命名不得以下划线和$开始和结束. 所有命名不得以拼音或拼音英文混合. 类名使用UpperCamelCase风格. 方法名 ...

  9. 条件表达式和switch语句

    一,条件表达式相当于(相当于if-else) 1.条件表达式 ? : 由条件运算符组成条件表达式的一般情况为: 表达式1?表达式2:表达式3: 求值规则:如果表达式的值为真,则以表达式2的值作为条件的 ...

  10. 睡前聊一聊"spring bean 生命周期"

    spring bean 生命周期=实属初销+2个常见接口+3个Aware型接口+2个生命周期接口 实属初销:spring bean生命周期只有四个阶段,即实例化->属性赋值->初始化-&g ...