当前位置:网站首页>C杂讲 动态链表操作 再讲
C杂讲 动态链表操作 再讲
2022-07-06 09:04:00 【Bright-SKY】
目录
知识点1【布局个简单框架】
main.c
#include<stdio.h>
void stu_help(void);
int main(int argc,char *argv[])
{
stu_help();
while(1)
{
char cmd[32]="";
printf("请输入操作指令:");
scanf("%s",cmd);
if(strcmp(cmd,"help") == 0)
{
stu_help();
}
else if(strcmp(cmd,"insert") == 0)
{
printf("-----insert------\n");
}
else if(strcmp(cmd,"print") == 0)
{
printf("-----print------\n");
}
else if(strcmp(cmd,"search") == 0)
{
printf("-----search------\n");
}
else if(strcmp(cmd,"delete") == 0)
{
printf("-----delete------\n");
}
else if(strcmp(cmd,"free") == 0)
{
printf("-----free------\n");
}
else if(strcmp(cmd,"quit") == 0)
{
break;
}
}
return 0;
}
void stu_help(void)
{
printf("################################\n");
printf("#help:打印帮助信息 #\n");
printf("#insert:插入链表节点 #\n");
printf("#print:遍历链表节点信息 #\n");
printf("#search:查询链表节点 #\n");
printf("#delete:删除链表节点 #\n");
printf("#free:释放链表 #\n");
printf("#quit:退出 #\n");
printf("################################\n");
return;
}
链表插入节点 之 头部之前插入
案例:
main.c
#include<stdio.h>
#include<string.h>
#include "link.h"
void stu_help(void);
int main(int argc,char *argv[])
{
//定义一个链表头 注意 一定要赋值为NULL
STU *head=NULL;
stu_help();
while(1)
{
char cmd[32]="";
printf("请输入操作指令:");
scanf("%s",cmd);
if(strcmp(cmd,"help") == 0)
{
stu_help();
}
else if(strcmp(cmd,"insert") == 0)
{
STU tmp;
printf("请输入需要插入的数据:");
scanf("%d %s %f",&tmp.num, tmp.name, &tmp.score);
//将tmp数据 插入到head所指向的链表中
head = insert_link(head, tmp);
}
else if(strcmp(cmd,"print") == 0)
{
print_link(head);
}
else if(strcmp(cmd,"search") == 0)
{
printf("-----search------\n");
}
else if(strcmp(cmd,"delete") == 0)
{
printf("-----delete------\n");
}
else if(strcmp(cmd,"free") == 0)
{
printf("-----free------\n");
}
else if(strcmp(cmd,"quit") == 0)
{
break;
}
}
return 0;
}
void stu_help(void)
{
printf("################################\n");
printf("#help:打印帮助信息 #\n");
printf("#insert:插入链表节点 #\n");
printf("#print:遍历链表节点信息 #\n");
printf("#search:查询链表节点 #\n");
printf("#delete:删除链表节点 #\n");
printf("#free:释放链表 #\n");
printf("#quit:退出 #\n");
printf("################################\n");
return;
}
link.c
#include<stdio.h>
#include<stdlib.h>//calloc
#include"link.h"
STU* insert_link(STU *head, STU tmp)
{
//1、从堆区申请一个待插入的节点空间
STU *pi = (STU *)calloc(1,sizeof(STU));
if(pi == NULL)
{
perror("calloc");
return head;
}
//2、将tmp的值 赋值 给*pi
*pi = tmp;
pi->next = NULL;//注意
//3、将pi插入到链表中
if(head == NULL)//链表不存在
{
head = pi;
//return head;
}
else//链表存在(头部之前插入)
{
//1、让pi 指向就的头
pi->next = head;
//2、head指向新的头节点
head = pi;
//return head;
}
return head;
}
void print_link(STU *head)
{
if(head == NULL)//链表不存在
{
printf("link not find\n");
return;
}
else
{
STU *pb = head;
while(pb != NULL)
{
printf("%d %s %f\n", pb->num, pb->name,pb->score);
//pb指向下一个节点
pb = pb->next;
}
}
return;
}
link.h
//防止头文件重复包含
#ifndef __LINK_H__
#define __LINK_H__
//链表节点类型 定义
typedef struct stu
{
//数据域
int num;
char name[32];
float score;
//指针域
struct stu *next;
}STU;
extern STU* insert_link(STU *head, STU tmp);
extern void print_link(STU *head);
#endif
知识点2【链表的插入】
1、在链表的尾部插入
//链表的尾部插入
STU* insert_link(STU *head, STU tmp)
{
//1、申请待插入的节点
STU *pi = (STU *)calloc(1,sizeof(STU));
if(pi == NULL)
{
perror(calloc);
return head;
}
//2、将tmp的数据 赋值到 *pi
*pi = tmp;
pi->next = NULL;
//3、将节点插入到链表的尾部
if(head == NULL)//链表不存在
{
head = pi;
return head;
}
else//链表存在
{
//a、寻找链表的尾节点
STU *pb = head;
while(pb->next != NULL)//如果不是尾节点
pb = pb->next;//pb就指向下一个节点
//b、用尾结点 pb 链接上 插入的节点pi
pb->next = pi;
return head;
}
return head;
}
2、链表的有序插入(难度)
//链表的有序插入 以num的顺序为准(小--->大)
STU* insert_link(STU *head, STU tmp)
{
//1、给待插入的节点pi 申请 堆区空间
STU *pi = (STU *)calloc(1,sizeof(STU));
if(pi == NULL)
{
perror("calloc");
return head;
}
//2、将tmp的内容 赋值给 *pi
*pi = tmp;
pi->next = NULL;
//3、链表节点pi的插入
if(head == NULL)//链表不存在
{
head = pi;
return head;
}
else//存在
{
//a、寻找插入点
STU *pb = head, *pf = head;
while(pb->num < pi->num && pb->next != NULL)
{
pf = pb;
pb = pb->next;
}
//b、插入点的判断
if(pb->num >= pi->num)//头部 中部插入
{
if(pb == head)//头部之前插入
{
pi->next = head;
head = pi;
return head;
}
else//中部插入
{
pf->next = pi;
pi->next = pb;
return head;
}
}
else//尾部插入
{
pb->next = pi;
return head;
}
}
return head;
}
知识点2【链表查询某个节点】 按姓名 查找
STU* search_link(STU *head, char *name)
{
//1、判断链表是否存在
if(head == NULL)//不存在
{
printf("link not found\n");
return NULL;
}
else//链表存在
{
STU *pb = head;
//逐个将节点中的name 和 name比较 如果不相等 pb=pb->next
while(strcmp(pb->name,name)!=0 && pb->next != NULL)
pb = pb->next;
//判断是否找到
if(strcmp(pb->name,name)==0)//找到
return pb;
else//没找到
return NULL;
}
return NULL;
}
知识点3【删除链表指定节点】
STU* detele_link(STU *head,char *name)
{
//1、判断链表是否存在
if(head == NULL)//不存在
{
printf("link not found\n");
return head;
}
else//存在
{
//2、寻找删除点
STU *pf=head, *pb = head;
while(strcmp(pb->name,name)!=0 && pb->next != NULL)
{
pf = pb;
pb = pb->next;
}
//3、找到删除点
if(strcmp(pb->name,name)==0)//找到删除点
{
//4、判断删除的位置
if(pb == head)//删除头结点
{
head = pb->next;
free(pb);
}
else//中部 或 尾部节点
{
pf->next = pb->next;
free(pb);
}
printf("已成功删除%s的相关节点\n",name);
return head;
}
else//没找到删除点
{
printf("链表中没有%s相关的数据节点信息\n",name);
}
}
return head;
}
知识点4【链表的释放】
STU* free_link(STU *head)
{
//判断链表是否存在
if(head == NULL)
{
printf("link not found\n");
return head;
}
else//链表存在
{
STU *pb = head;
//逐个节点释放
while(pb != NULL)
{
//head保存下一个节点的位置
head = pb->next;
//释放pb指向的节点
free(pb);
//pb 指向 head
pb = head;
}
printf("链表已经释放完毕\n");
return head;
}
return head;
}
知识点5【回顾一下】
链表的插入:头部之前插入 尾部插入 有序插入
1、为插入的节点pi申请空间
2、将tmp的值赋值给*pi *pi = tmp
3、判断链表是否 存在
3-1:不存在 head = pi
3-2: 存在 (尾部插入 有序插入) 寻找插入点 安装具体的位置 插入节点
链表的遍历:
1、判断链表是否存在
1-1:不存在 不执行任何操作
1-2:存在 逐个节点遍历 注意 别越界。
链表的查询:
1、判断链表是否存在
1-1:不存在 不执行任何操作
1-2:存在 逐个节点比较 比较成功返回位置 注意 别越界。
链表节点的删除:
1、判断链表是否存在
1-1:不存在 不执行任何操作
1-2:存在 逐个节点比较 删除指定节点 注意 别越界。
释放链表:
1、判断链表是否存在
1-1:不存在 不执行任何操作
1-2:存在 逐个节点节点释放 注意 别越界
知识点6【链表的逆序】
STU* reverse_link(STU *head)
{
//判断链表是否存在
if(head == NULL)
{
printf("link not founf\n");
return head;
}
else//链表存在
{
//int *p,num;//p为int * , num为int
STU *pb,*pr;//pb为STU * , pr为STU *
//pb保存head->next(原因head->next会置NULL)
pb = head->next;
//将head->next置NULL (原因:头节点变尾节点)
head->next = NULL;
while(pb != NULL)
{
//pr保存pb->next (原因:pb->next会指向head)
pr = pb->next;
//pb->next 指向 head (原因:逆转方向)
pb->next = head;
//保存 逆转方向的代码 可以重复 执行
head = pb;
pb = pr;
}
return head;
}
return head;
}
知识点7【链表的排序】
选择法排序:(以数组实现)
#include<stdio.h>
int main()
{
int arr[10]={0};
int n = sizeof(arr)/sizeof(arr[0]);
int i=0,j=0,min=0;
printf("请输入%d个int数据\n",n);
for(i=0;i<n;i++)
{
scanf("%d",arr+i);
}
//选择法排序
for(i=0;i<n-1; i++)
{
for(min=i,j=min+1; j<n;j++)
{
if(arr[min] > arr[j])
min = j;
}
if(min != i)
{
int tmp = 0;
tmp = arr[i];
arr[i]=arr[min];
arr[min]=tmp;
}
}
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
运行结果:
知识点7【链表的排序(选择法)】
void sort_link(STU *head)
{
//1、判断链表是否存在
if(NULL == head)
{
printf("link not found\n");
return;
}
else
{
STU *p_i = head;//i=0
while(p_i->next != NULL)//i<n-1 外层循环
{
STU *p_min = p_i;//min = i;
STU *p_j = p_min->next;//j = min+1
while(p_j != NULL)//j<n 内层循环
{
//寻找成员num最小值的 节点
if(p_min->num > p_j->num)//if(arr[min] > arr[j])
p_min = p_j;//min = j
p_j = p_j->next;//j++
}
if(p_min != p_i)//min != i
{
//只交换数据域(1、节点内容整体交换 2、只交换指针域)
//1、节点内容整体交换(数据域交换第1次 指针域交换第1次)
STU tmp;
tmp = *p_i;
*p_i = *p_min;
*p_min = tmp;
//2、只交换指针域(指针域交换第2次)
tmp.next = p_i->next;
p_i->next = p_min->next;
p_min->next = tmp.next;
}
p_i = p_i->next;//i++
}
}
}
边栏推荐
- 五月刷题27——图
- Design and implementation of online snack sales system based on b/s (attached: source code paper SQL file)
- max-flow min-cut
- Hard core! One configuration center for 8 classes!
- Meituan Er Mian: why does redis have sentinels?
- 【深度学习】语义分割:论文阅读:(CVPR 2022) MPViT(CNN+Transformer):用于密集预测的多路径视觉Transformer
- 五月刷题02——字符串
- VH6501学习系列文章
- How does the single chip microcomputer execute the main function from power on reset?
- MapReduce instance (x): chainmapreduce
猜你喜欢
Design and implementation of online snack sales system based on b/s (attached: source code paper SQL file)
Mapreduce实例(七):单表join
Solve the problem of too many small files
Detailed explanation of cookies and sessions
DCDC power ripple test
CANoe仿真功能之自动化序列(Automation Sequences )
Control the operation of the test module through the panel in canoe (primary)
Hero League rotation map automatic rotation
Counter attack of noodles: redis asked 52 questions in a series, with detailed pictures and pictures. Now the interview is stable
Some thoughts on the study of 51 single chip microcomputer
随机推荐
CAPL 脚本打印函数 write ,writeEx ,writeLineEx ,writeToLog ,writeToLogEx ,writeDbgLevel 你真的分的清楚什么情况下用哪个吗?
六月刷题01——数组
【深度学习】语义分割:论文阅读:(2021-12)Mask2Former
33岁可以学PLC吗
单片机实现模块化编程:思维+实例+系统教程(实用程度令人发指)
Nc17 longest palindrome substring
MapReduce working mechanism
Segmentation sémantique de l'apprentissage profond - résumé du code source
Canoe CAPL file operation directory collection
机械工程师和电气工程师方向哪个前景比较好?
Hero League rotation chart manual rotation
在CANoe中通过Panel面板控制Test Module 运行(初级)
In order to get an offer, "I believe that hard work will make great achievements
May brush question 27 - figure
Mapreduce实例(九):Reduce端join
零基础学习单片机切记这四点要求,少走弯路
[untitled]
五月刷题27——图
068. Find the insertion position -- binary search
Control the operation of the test module through the panel in canoe (Advanced)