链表

链表详解(单链表、双向链表、链表逆序) 单链表 想了解单链表的一些概念可以看我另一篇博客: 链表基础 单链表结构体定义 //单链表的结构定义 typedef struct LNode { int data; //data存放结点数据域 struct LNode *next; //指向后继结点的指针 }LNode; 单链表的建立 (1)定义单链表的数据结构; (2)读取数据; (3)生成新结点; (4)将数据存入结点的成员变量中; (5)将新结点连接到表头或表尾。 重复(2)~(5)直到输入结束。 //头插法建立单链表 void c 阅读详情

C语言数组中,不允许使用动态数组类型,为此,在C语言中推出了链表这个概念。

一、动态内存分配与静态内存分配。

所谓动态内存分配就是指在程序执行过程中动态地分配或者回收存储空间的分配内存的方法。与之相对,静态分配内存,预先分配存储空间,像数组。

动态内存的分配方法相对于静态内存的分配方法有如下两个特点:

1、不需预先分配存储空间。

2、分配的空间可以根据程序的需要扩大和缩小。

二、实现动态分配内存的函数。

1、malloc函数 void *malloc(unsigned int size)

函数malloc的作用是在内存的动态存储区中分配一个长度为size的连续空间。

值得注意的是:当函数未能成功分配存储空间(如内存不足)就会返回一个NULL指针,所以在调用函数时应该检测返回值是否是NULL,并添加相应的处理语句。

下面是一个malloc的例子:

#include <stdio.h>

#include <stdlib.h>

void main()

{

int count ,*array;

if((array=(int*)malloc(10*sizeof(int)))==NULL)

{

printf("Assgin failed");

exit(1);

}

for(count=0;count<10;count++)

 array[count]=count;

for(count=0;count<10;count++)

printf("%2d",array[count]);


}

2.calloc函数

(类型说明符*)calloc(n,size)

函数功能为:在内存动态存储区中分配n块长度为“size“字节的连续区域,函数的返回值为该区域的首地址,其中 (类型说明符*)用于强制类型转换。

calloc与malloc的区别仅在于前者一次可以分配n块区域,例如

p=(struct stu*)calloc(2,sizeof(struct stu));

其中:按stu的长度分配两个连续区域,强制转换为stu类型,并把其首地址赋予指针变量ps。

3、释放函数free

void free(void *p)

其功能是释放指针p所指向的内存区。其中”p"必须是先前调用malloc函数或calloc函数时返回的指针。

在此重要的是指针的值,而不是用来申请动态内存的指针本身。例如:

int *p1,*p2;

p1=malloc(10*sizeo(int));

p2=p1;

....

free(p2);//或者free(p1),此时p1、p2都可作为free函数的参数。

4、realloc函数

void *realloc(void *mem_address, unsigned int newsize);

指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小)。//新的大小一定要大于原来的大小不然的话会导致数据丢失!

功能:先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域,同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。

三、链表

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接秩序实现的。链表由一系列的结点组成,结点可以再运行时动态生成,每个结点包括两部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

如果在矩阵中,多数的元素为0,称此矩阵为稀疏矩阵(sparse matrix)。

1、简单线性链表的模型 老鹰捉小鸡

#include <stdio.h>

struct Chicken

{

char Name [20];

struct Chicken *next;

};

void main()

{

struct Chicken No4={"Chicken No4",NULL};

struct Chicken No3={"Chicken No3",NULL};

struct Chicken No2={"Chicken No2",NULL};

struct Chicken No1={"Chicken No1",NULL};

struct Chicken Hen={"Hen",NULL};

struct Chicken *pChicken=NULL;

/*建立链表*/

Hen.next=&No1;

No1.next=&No2;

No2.next=&No3;

No3.next=&No4;

/*遍历链表*/

pChicken=&Hen;

while(pChicken!=NULL)

{

printf("%s \n",pChicken->Name);

pChicken=pChicken->next;

}

}

问卷调查问题:
#include <stdio.h>
#include <stdlib.h>
struct mm
{
char mingzi[20];
char xingbie;
char daan;
struct mm *next;
};
void main()
{
struct mm *pHead=NULL;
struct mm *pOne=NULL;
struct mm *pPrevOne=NULL;
/*在内存中动态创建一个struct mm 对象*/


pOne=malloc(sizeof(struct mm));
pPrevOne=pHead=pOne;
/*strcpy(pOne->mingzi,"mingzi");*/
/*打印提示信息*/
printf("\nmingzi\txingbie(M/F)\tdaan(Y/N)");
printf("\n-------------------\n");
pHead->next=NULL;


while(1)
{
/*读入当前的调查结果*/
scanf("%s %c %c",pOne->mingzi,&(pOne->xingbie),&(pOne->daan));
if(strcmp(pOne->mingzi,"Q")==0)
{
/*结束输入,对最后读入的对象进行处理*/
strcmp(pOne->mingzi," ");
pOne->xingbie=' ';
pOne->daan=' ';
pOne->next=NULL;
        break;
}
pPrevOne=pOne;/*保存当前对象的地址*/
pOne=(struct mm*)malloc(sizeof(struct mm));
/*新对象的地址存储到当前对象的next成员变量*/
pPrevOne->next=pOne;


}
      printf("\n mingzi\txingbie(M\F)\tdaan(Y\N)\t\n");
 printf("\n----------\n");
 pOne=pHead;
 while(pOne->next!=NULL)
 {
 /*打印当前对象的信息*/
 
printf("\n%s\t%c\t%c \n",pOne->mingzi,pOne->xingbie,pOne->daan);
pOne=pOne->next;/*指向链表的下一个对象*/


 }
 /*删除链表*/
 pOne=pHead;
 while(pOne->next!=NULL)
 {
 pPrevOne=pOne;
 pOne=pOne->next;
 free(pPrevOne);
 }

}

2、单向链表

链表结构中包含指针类型的结构成员,其类型为指向相同结构类型的指针。根据C语言的语法要求,结构成员不能是结构自身类型,即结构不能自己定义自己,因为这样将导致一个无穷的递归定义,但结构的成员可以是结构自身的指针类型,通过指针引用自身这种类型的结构。

例:

include <stdio.h>
 
typedef struct node
{
	int info;
	struct node *next;
}LINKLIST;
 
void main()
{
LINKLIST *head,*p,x,y,z;
x.info=10;
y.info=20;
z.info=30;
head=&x;
x.next=&y;
y.next=&z;
z.next=NULL;
 
p=head;
while(p!=NULL)
{
	printf("%d \n",p->info);
	p=p->next;
}
 
}
3、对链表的各种操作

/*在结点P后插入一结点*/
void insert(LINKLIST *p,DATATYPE x)
{
   LINKLIST *newp=new(LINKLIST);
   newp->info=x;
   newp->next=p->next;
   p->next=newp;
}
/*删除结点p后面的结点*/
void delete(LINKLIST *p)
{
LINKLIST *temp;
temp=p->next;
p->next=p->next->next;
delete(temp);
}
/*遍历链表*/
void outputlist(LINKLIST *head)
{
  LINKLIST *current=head->next;
  while(current!=NULL)
  {
 printf("%d \n",current->info);
       current=current->next;
  }
  return ;
}
/*创建链表*/
struct node *create(unsigned int size)
{
struct node *phead=NULL;
struct node *pone=NULL;
struct node *pprevone=NULL;
int i;
pone=(struct node *)malloc(sizeof(struct node));
pone->next=NULL;
pprevone=phead=pone;
/*构建循环*/
for(i<0;i<size;i++)
{
pprevone=pone;
pone=(struct node *)malloc(sizeof(struct node));
pprevone->next=pone;


}
return phead;
}
/*删除整个链表*/
void removeall(struct node *list)
{
     struct node *phead=NULL;
struct node *pone=NULL;
pone=list;
while(pone->next!=NULL)
{
pprevone=pone;
pone=pone->next;
free(pprevone);
}
 
}
/*在链表中插入结点*/
int insert(struct node *list,int i,struct node *node)/*list为链表的第一个结点地址,I为第n个元素,如果存在,返回i,否则返回0*/
{
struct node *pone=NULL;
struct node pnewone=NULL;
int j=0;
pone=list
/*顺序查找,直到到达链表的尾部或j=i*/
while((pone!=NULL)&&(j<i-1))
{
pone=pone->next;
j++;
}
if((pone->next==NULL)||(j>i-1))/*第i个元素不存在*/
return 0;
pnewone=(struct node *)malloc(sizeof(struct node));
/*复制参数node信息到新增加的结点pnewone*/
pnewone->next=node->next;


pnewone->next=pone->next;/*将下一结点的地址复制到插入结点的成员变量中*/
pone->next=pnewone;/*将插入结点的地址复制到当前结点的成员变量中*/
return j;
}


 /*在链表中删除结点*/
int removeElment(struct node *list,int i)
{
   /*list为链表第一个结点地址,i为第n个元素,如果存在返回i,否则返回0*/
struct node *pone=NULL;
struct node *pdeleteone=NULL;
int j=0;
pone=list;
while((pone!=NULL)&&(j<i-1))
{
       pone=pone->next;
  j++;
}
if((pone->next==NULL)||(j>i-1))
{
return 0;
}
    pdeleteone=pone->next;
pone->next=pdeleteone->next;
free(pdeleteone);
return j;
}

4、双链表

#include <stdio.h>
#define N 3;
typedef struct node
{
char name[20];
struct node *llink,*rlink;
}stud;
stud *creat(int n)
{
stud *p,*h,*s;
int i;
if((h=(stud *)malloc(sizeof(stud)))==NULL)
{
printf("Assign memory failed!\n");
exit(1);
}
h->name[0]='\0';
h->llink=NULL;
h->rlink=NULL;
p=h;
for(i=0;i<n;i++)
{
        if((s=(stud *)malloc(sizeof(stud)))==NULL)
{
printf("不能分配内存空间!\n");
exit(1);
}
p->rlink=s;
printf("Please input the %d th's name \n",i+1);
scanf("%s",s->name);
s->llink=p;
s->rlink=NULL;
p=s;
}
   h->llink=s;
   p->rlink=h;
   return(h);
}
stud *search(stud *h,char *x)
{
stud *p;
char *y;
p=h->rlink;
while(p!=h)
{
y=p->name;
if(strcmp(y,x)==0)
      return (p);
         else
p=p->rlink;



}
printf("NO DATA \n");


}
void print(stud *h)
{
int n;
stud *p;
p=h->rlink;
printf("The result is: \n");
while(p!=h)
{
      printf("%s \n",&*(p->name));
 p=p->rlink;
}
printf("\n");
}
void main()
{
int number;
char studname[20];
stud *head,*searchpoint;
number=N;
//clrscr();/*清除文本模式窗口 清屏的意思*/
head=creat(number);
print(head);
printf("Please input name \n");
scanf("%s",studname);
searchpoint=search(head,studname);
printf("The result is :%s \n",*&searchpoint->name);
}


C++实现单向链表,双向链表,单向环形链表,双向环形链表 本文讲解了链表的四种类型以及数据结构,同时给出了四种链表的C++代码实现。 阅读详情

相关推荐

用C++实现老鹰捉小鸡的小游戏之一

用C++实现老鹰捉小鸡的游戏之一

笔者从事电信媒体开发多年,愿意将多年的开发经验分享给同行 1063

小学生c++趣味编程入门视频教程 少儿C十十信息学奥赛竞赛网课

这是一套符合小学生认知特点的C++编程入门视频教程。以程序为中心,适当地弱化语法,注重算法。利用流程图清思路,激发学习兴趣,培养计算思维。适用人群:小学四年级以上的中小学孩子          C++初学者本课程是基于小学生的认知发展水平开展教学的,浅显易懂。用编程的方式实现小学生日常生活和学习中遇到的例子,能激发孩子学习编程的兴趣。学完本课程后,孩子能编写简单的代码,用程序解决生活及学习中遇到的一些题目,也看懂一般的C++代码,学会编程的方法去思考和解决问题。本课程共83节课时,每节课十几分钟,每节课都有编程实例和课后练习,在讲新的课时之前,老师都会把上节课留的练习进行分析讲解。购买本视频教程后,赠送的资料包括课程配套教学文档和源码,入群有老师提供在线解答学习中遇到的问题。

用C++实现老鹰捉小鸡的小游戏之二

用C++实现老鹰捉小鸡游戏之二

笔者从事电信媒体开发多年,愿意将多年的开发经验分享给同行 693

老鹰捉小鸡 c++编程参考程序(一本通51.2)

#include<bits/stdc++.h> using namespace std; int main(){ int i,j,a[6],n;//定义整形变量 for(i=1;i<6;i++)//循环 a[i]=i; i=1; cout<<i<<":"<<" ";//输出i for(j=1;j<6;j++)//再循环 co

liunian_curry的博客 1257

老鹰抓小鸡;日历问题; 恺撒Caesar密码

在我们现在使用的日历中, 闰年被定义为能被4整除的年份,但是能被100整除而不能被400整除的年是例外,它们不是闰年。例如:1700, 1800, 1900 和 2100 不是闰年,而 1600, 2000 和 2400是闰年。 给定从公元2000年1月1日开始逝去的天数,你的任务是给出这一天是哪年哪月哪日星期几。 小时候每个人都玩过老鹰抓小鸡的游戏,在游戏中,如果小鸡按照从大到小的顺序排列,老鹰则很难抓着小鸡,可是小鸡们该如何排列呢?小鸡们让你给他们排一下顺序。  输入数据 输入若干个测试例子,当输入0则结束。每个测试例子包括两行,第一行是小鸡的个数n,第二行有n个数,分别代表从1号至n号小鸡的个头,假设每个小鸡个头都不一样。  输出要求 对于每个测试例子,请输出按照个头从大到小的小鸡序号。

猫抓老鼠游戏(C++实现)

猫抓老鼠游戏,下面是部分代码 #include using namespace std; const int length=22; //a[0]将不使用,故如果要测试21只老鼠,此处应填22 bool a[length]; //用来记录对应某只老鼠是否已经排列进去 int b[length]; //储存老鼠排列顺序 void range(int n); //递归,直到走到了递归的底部,检查是否能完成抓捕 void check(); //检查当前排列顺序是否能通过 int maxno(bool* d); //返回当前没有被抓住的老鼠的最大编号

o.boj 1096 老鹰抓小鸡

注:最近这一系列ACM的内容,都是2年多之前的代码,自己回顾一下。     老鹰抓小鸡   Submit: 1978 Accepted:447 Time Limit: 2000MS Memory Limit: 65536K Description 小学一年级912班的N个小朋友(编号0到N-1)在和F老师玩老鹰抓小鸡的游戏,F老师扮演的是老鹰,一个小朋友扮演母鸡,其余N-1个小朋

wenlele的专栏 2823

循环位移算法C++代码实现

循环位移算法C++代码实现

【Leetcode】反转链表 合并链表 相交链表 链表的回文结构

【Leetcode】反转链表 合并链表 相交链表 链表的回文结构

旋律 | 话语 | 色彩 | 情景 2381

Blender入门教程-3D视图界面介绍

3D视图用于与3D场景交互,可用于各种目的,例如建模、动画、纹理绘制等。在关闭 启动画面 后,启动场景会显示在3D视口中(如果没有加载其他blend文件)。01 标题栏标题栏包含了基于当前 模式 的各种菜单和控制。

weixin_52345129的博客 2287

避坑指南:Qwen2.5-VL图片预处理中常见的5个尺寸错误

本文深入解析了Qwen2.5-VL模型在图片预处理环节中开发者最常遇到的五个尺寸错误,包括动态分辨率对齐、宽高比超标、像素数限制等问题。文章结合源码解读,详细剖析了`process_vision_info`函数和`resize`逻辑,并提供了具体的排查流程图与参数设置建议,旨在帮助开发者构建健壮的预处理流水线,有效规避显存溢出与推理失败的风险。

weixin_29290379的博客 175

数据结构 —— java 单链表、双端链表、双向链表、无序链表、有序链表

文章目录链表不同链表的特点单链表(单端链表)双端链表双向链表 链表 上面是一个单链表的存储原理图,head为头节点,它不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用,而每个节点中都有一个next引用,指向下一个节点,就这样一节一节往下面记录,直到最后一个节点,其中的next指向null。 不同链表的特点 普通链表: 节点类保留下一节点的引用。链表类只保留头节点的引用,只能...

猎人在吃肉 4536

RoboMaster新手必看:用STM32 HAL库搞定大疆M3508电机正反转(附完整代码)

本文详细介绍了如何使用STM32 HAL库驱动大疆M3508电机实现正反转控制,包括硬件准备、PWM配置、电机校准及完整代码实现。特别针对RoboMaster新手常见问题提供了解决方案,如电机抖动、不转等故障排查,并分享了缓启动、DMA更新等进阶技巧,帮助开发者快速掌握电机控制核心技术。

weixin_42519985的博客 226

LeetCode链表(链表操作,反转链表,奇偶链表,排序链表)

本篇文章更注重于链表自身的特点。链表是一种通过指针串联在一起的线性结构。链表中的每个元素实际上是一个单独的对象,而所有对象都通过每个元素中的引用字段链接在一起。链表的入口节点称为链表的头结点也就是head。(1)单链表每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。(2)双链表每一个节点有两个指针域。

ji_meng的博客 1820

AWS S3文件上传性能优化:Java SDK多线程与分段上传实战指南

本文详细介绍了如何通过Java SDK优化AWS S3文件上传性能,重点讲解多线程并发上传与分段上传(Multipart Upload)技术的实战应用。通过动态调整分段策略、线程池配置及内存优化技巧,可显著提升大文件上传效率,实测显示组合方案比单线程上传提速近5倍。文章还涵盖加密上传、断点续传等高级场景解决方案,并提供了完整的性能对比测试数据。

d6e7f8的博客 1016

Oracle Primavera P6实战手册:从入门到精通的企业项目管理秘籍

本文详细介绍了Oracle Primavera P6在企业项目管理中的实战应用,从环境配置到高级进度控制技巧,帮助用户从入门到精通。通过WBS设计、资源优化和情景模拟等核心功能,提升项目管理效率。特别适合需要处理复杂项目和多团队协作的企业用户。

weixin_29235923的博客 252

数据结构01- 单链表、双端链表、双向链表、无序链表、有序链表

数据结构01- 单链表、双端链表、双向链表、无序链表、有序链表 0、节点 节点 是数据结构中的基础,是 构成复杂数据结构的基本组成单位。 public class Node { public long data; public Node next; public Node(long value) { this.data = value; } } 1、链表的定义 链表: 通常由一连串 节点 组成,每个节点包含任意的实例数据(data fields)和一或两个用来指向 上一个 或 下一个

琦彦 7072

下载MNIST数据集并使用python将数据转换成NumPy数组(源码解析)

下载MNIST数据集并使用python将数据转换成NumPy数组首先来分析init_mnist函数接下来继续分析load_mnist函数实现数据集转换的python脚本的代码显示MNIST图像并确认数据 下载MNIST数据集并将数据转换成NumPy数组的Python脚本里面最重要的就是load_mnist函数,其他项目想要调用数据集的话,就可以调用load_mnist函数,得到一个字典类型的数据,字典的值是一个Numpy数组。 这些过程是如何实现的,现在开始逐字逐句分析源码: 在load_mnist函数中第

及时总结 4266

详解链表oJ<反转链表,链表的中间节点及链表的回文>

链表OJ

qq_75270497的博客 1039

电磁场仿真软件:Sonnet_(3).Sonnet用户界面与操作

Sonnet支持用户通过二次开发自定义工具,例如:编写Python脚本,实现自定义功能。将脚本保存为工具插件。在Sonnet中加载并使用自定义工具。# 示例:自定义工具 import sonnet def custom_tool(design , object , parameter , value) : """自定义工具示例,设置对象的指定参数。

kkchenjj的博客 1523

信息安全管理与评估赛题解析-单机取证(含环境)

链接:https://pan.baidu.com/s/1OMzIq884dW2vAiUp0k2Ppg。链接:https://pan.baidu.com/s/1i5daMqhD53wYeQ6hYzRK6Q。链接:https://pan.baidu.com/s/1QFAjdQZK4sJ-gGRP42XPKA。链接:https://pan.baidu.com/s/1BSXvqN2ZGCQXewgFULoeyQ。链接:https://pan.baidu.com/s/1g9zu5ngBz_KMjW1eBMkJAw。

Brucye 1834

Python与链表(含链表概念、链表定义、链表操作、链表相关例题)

Python与链表、链表基础概念、链表与数组区别、链表分类、链表增删改查、链表相关例题

Bala_lala的博客 1402

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

链表小总结

/ 结点的值int val;// 下一个结点// 节点的构造函数(无参)// 节点的构造函数(有一个参数)// 节点的构造函数(有两个参数)

m0_58257626的博客 1660

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

反转链表、旋转链表算法总结

1. 反转链表(力扣:206) 2. 反转链表 II(力扣:92) 3. 旋转链表(力扣:61)

卜大爷的博客 2万+
上一篇: C语言基础(二)
下一篇: 一道是死循环的题目
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值