函数形参 LNode* L和LNode* &L的区别

最近有人问我LNode* L和LNode* &L的区别
很简单 这种区别很微小 要联系到具体运用上
废话不说 上代码

#include<stdio.h> 
#include<malloc.h>
typedef int ElemType;
typedef struct LNode{
	ElemType data;
	struct LNode* next;
}LNode,*Linklist;
int pr(Linklist &L);
int main() {
	LNode* L=NULL; 
	printf("传入前指针存储地址%p\n",L);
	pr(L);//传入指针存储的地址
	printf("传入后指针存贮地址%p\n",L);
}

int pr(LNode* &L){
	L=(LNode*)malloc(sizeof(LNode));
	L->data=10;
	printf("函数内分配内存后----指针存储地址%p\n",L);
	printf("%d\n",L->data);
	return 0;
}

在这里插入图片描述

加了&符号 函数操作后 函数内指针L存储的地址变化 会自动更新到主函数的L身上
所以一般加&符号是为了生成无头结点链表
或者 初始化链表;

再来看看不加&符号的代码

#include<stdio.h> 
#include<malloc.h>
typedef int ElemType;
typedef struct LNode{
	ElemType data;
	struct LNode* next;
}LNode,*Linklist;
int pr(Linklist L);
int main() {
	LNode* L=NULL; 
	printf("传入前指针存储地址%p\n",L);
	pr(L);//传入指针存储的地址
	printf("传入后指针存贮地址%p\n",L);
}

int pr(LNode* L){
	L=(LNode*)malloc(sizeof(LNode));
	L->data=10;
	printf("函数内分配内存后----指针存储地址%p\n",L);
	printf("该结构体值%d\n",L->data);
	return 0;
}

在这里插入图片描述
很显然 LNode 无法做到自动更新 这个时候主函数的地址依旧我行我素

有人问我要是这种情况怎么解决 相当简单 除了加&外 就是将函数修改成这样
没错就是再赋一遍值 简单粗暴 人类的脑瓜永远为简单粗暴而生

#include<stdio.h>
#include<malloc.h>
typedef int ElemType;
typedef struct LNode{
	ElemType data;
	struct LNode* next;
}LNode,*Linklist;
LNode* pr(Linklist L);
int main() {
	LNode* L=NULL; 
	printf("传入前指针存储地址%p\n",L);
	L=pr(L);//传入指针存储的地址
	printf("传入后指针存贮地址%p\n",L);
}

LNode* pr(LNode* L){
	L=(LNode*)malloc(sizeof(LNode));
	L->data=10;
	printf("函数内分配内存后----指针存储地址%p\n",L);
	printf("该结构体值%d\n",L->data);
	return L;
}
#include&lt;iostream> using namespace std; #define ERROR NULL typedef int ElemType; //ElemType 为可定义的数据类型,此设为int类型 typedef struct LNode { ElemType data; //结点的数据域 struct LNode *next; //结点的指针域 } LNode, *LinkList; //LinkList为指向结构体LNode的指针类型 bool InitList(LinkList &L);//初始化一个为空的带头结点单链表 LNode* Find( LinkList L, ElemType X ); //在带头节点单链表L中查找值为X的节点,如果找到返回该节点的地址,否则返回NULL bool Insert( LinkList &L, ElemType X, LNode* P ); //将X插入在指针P指向的结点之前,返回true。 P==NULL ,表示要插入的位置是表尾。如果参数P指向非法位置,则打印&ldquo;Wrong Position for Insertion\n”,返回false; bool Delete( LinkList &L, LNode* P ); //将指针P所指向的元素删除并返回true。若参数P指向非法位置,则打印&ldquo;Wrong Position for Deletion\n”并返回false。 void DispList(LinkList L); //顺序输出链表每个结点,每个结点元素值以空格符间隔,以换行符结束。 /*在带头节点单链表L中查找值为X的节点,如果找到返回该节点的地址,否则返回NULL */ LNode* Find( LinkList L, ElemType X ) { // 请在这里补充代码,完成本关任务 /********** Begin *********/ /********** End **********/ } /*将X插入在指针P指向的结点之前,返回true。 P==NULL ,表示要插入的位置是表尾。如果参数P指向非法位置,则打印&ldquo;Wrong Position for Insertion\n”,返回false; */ bool I
04-19
本关任务:要求从文件输入顶点边数据,包括顶点信息、边、权值等,编写程序实现以下功能。 1)构造图G的邻接表顶点集,即图的存储结构为邻接表。 2)输出图G的各顶点邻接表。 3)输出图G中某个顶点的所有邻接顶点。 相关知识 对于图来说,邻接矩阵是不错的一种图存储结构,但是对于边数相对顶点较少的图,这种结构对存储空间浪费极大。 因此考虑另外一种存储结构方式:邻接表,即数组与链表相结合的存储结构。 在图的邻接表结构中,用一个连续存储区域来存储图中各顶点的数据,并对图中每个顶点vi建立一个单链表(称为vi的邻接表),把顶点vi的所有相邻顶点(即后继结点)的序号链接起来。 第i个单链表中的每一个结点(也称为表结点)均含有三个域:邻接点域、链域数据域,邻接点域用来存放与顶点vi相邻接的一个顶点的序号,链域用来指向下一个表结点,数据域info存储边的信息(如果边上没有权值,可以省略该info数据域) 另外每个顶点vi设置了表头结点,除了存储本身数据的数据域data外,还设置了一个链域firstarc,作为邻接表的表头指针,指向第一个表结点。n个顶点用一个一维数组表示。如图所示。 邻接表的表结点头结点示意图 表结点的类型定义如下: typedef struct { int adjvex; // 该弧所指向的顶点的位置 int info; // 网的权值 ArcNode *nextarc; // 指向下一条弧的指针 }ArcNode; 头结点的类型定义如下: typedef struct { VertexType data; // 顶点信息 ArcNode *firstarc; // 第一个表结点的地址,指向第一条依附该顶点的弧的指针 }VNode,AdjList[MAX_VERTEX_NUM]; 无向图的邻接表 有向图的邻接表 有向网的邻接表 图的邻接表存储表示,类型定义如下: typedef struct { AdjList vertices; int vexnum,arcnum; // 图的当前顶点数弧数 GraphKind kind; // 图的种类标志 }ALGraph; 邻接表具有如下性质: 图的邻接表表示不是唯一的,它与表结点的链入次序有关,取决于建立邻接表的算法以及边的输入次序; 无向图的邻接表中第i个边表的结点个数即为第i个顶点的度; 有向图的邻接表中第i个出边表的结点个数即为第i个顶点的出度,有向图的逆邻接表中第i个入边表的结点个数即为第i个顶点的入度; 无向图的边数等于邻接表中边表结点数的一半,有向图的弧数等于邻接表的出边表结点的数目,也等于逆邻接表的入边表结点的数目。 编程要求 根据提示,在右侧编辑器补充代码,要求从文件中输入顶点边数据,包括顶点信息、边、权值等,编写函数实现图的基本运算: void CreateGraphF(ALGraph &G); // 采用邻接表存储结构,由文件构造没有相关信息图或网G void Display(ALGraph G); // 输出图的邻接表G int LocateVex(ALGraph G,VertexType u); //若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 int FirstAdjVex(ALGraph G,VertexType v); // 返回v的第一个邻接顶点的序号;否则返回-1 int NextAdjVex(ALGraph G,VertexType v,VertexType w);//v是图G中某个顶点,w是v的邻接顶点,返回v的(相对于w的)下一个邻接顶点的序号 测试说明 平台会对你编写的代码进行测试: 测试输入: 3 lt.txt 徐州 输入说明: 第一行输入3,表示输入图的类型为无向网。 第二行输入文件名,该文件里保存了图的数据信息,内容如下: 图的数据文件 第1行为图的顶点的个数n; 第2行为图的边的条数m; 第3行至第n+2行是n个顶点的数据; 第n+3行至第n+m+2行是m条边的数据; 第三行为一个顶点徐州的数据 预期输出: 无向网 8个顶点: 北京 天津 郑州 徐州 武汉 上海 株洲 南昌 9条弧(边): 北京→郑州 :695 北京→天津 :137 天津→徐州 :674 天津→北京 :137 郑州→武汉 :534 郑州→徐州 :349 郑州→北京 :695 徐州→上海 :651 徐州→郑州 :349 徐州→天津 :674 武汉→株洲 :409 武汉→郑州 :534 上海→徐州 :651 上海→南昌 :825 株洲→南昌 :367 株洲→武汉 :409 南昌→上海 :825 南昌→株洲 :367 上海 郑州 天津 输出说明: 第一行输出图的类型。 第二行起输出图的顶点边的数据信息。 最后一行为徐州的邻接点。根据以上提示完成以下代码#include&lt;stdio.h> #include&lt;stdlib.h> #include&lt;string.h> #include&lt;limits.h> typedef char VertexType[20]; // 顶点类型为字符串 #define MAX_VERTEX_NUM 20 typedef enum{DG,DN,UDG,UDN}GraphKind; // {有向图,有向网,无向图,无向网} typedef struct { int adjvex; // 该弧所指向的顶点的位置 int info; // 网的权值指针 }ElemType; typedef struct ArcNode { ElemType data; // 除指针以外的部分都属于ElemType struct ArcNode *nextarc; // 指向下一条弧的指针 }ArcNode; // 表结点 typedef struct { VertexType data; // 顶点信息 ArcNode *firstarc; // 第一个表结点的地址,指向第一条依附该顶点的弧的指针 }VNode,AdjList[MAX_VERTEX_NUM]; // 头结点 typedef struct { AdjList vertices; int vexnum,arcnum; // 图的当前顶点数弧数 GraphKind kind; // 图的种类标志 }ALGraph; #define LNode ArcNode // 定义单链表的结点类型是图的表结点的类型 #define next nextarc // 定义单链表结点的指针域是表结点指向下一条弧的指针域 typedef ArcNode *LinkList; // 定义指向单链表结点的指针是指向图的表结点的指针 int LocateElem(LinkList L,ElemType e,int (*equal)(ElemType,ElemType)); LinkList Point(LinkList L,ElemType e,int(*equal)(ElemType,ElemType),LinkList &p); int ListInsert(LinkList &L,int i,ElemType e);// 在不带头结点的单链线性表L中第i个位置之前插入元素e int equal(ElemType a,ElemType b); void visit(VertexType i); void CreateGraphF(ALGraph &G); // 采用邻接表存储结构,由文件构造没有相关信息图或网G void Display(ALGraph G); // 输出图的邻接表G int LocateVex(ALGraph G,VertexType u); //若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 int FirstAdjVex(ALGraph G,VertexType v); // 返回v的第一个邻接顶点的序号;否则返回-1 int NextAdjVex(ALGraph G,VertexType v,VertexType w);//v是图G中某个顶点,w是v的邻接顶点,返回v的(相对于w的)下一个邻接顶点的序号 int main() { ALGraph g; VertexType v1,v2; int k; CreateGraphF(g); // 利用数据文件创建图 Display(g); // 输出图 //printf("请输入顶点的值: "); scanf("%s",v1); //printf("输出图G中顶点%s的所有邻接顶点: ",v1); k=FirstAdjVex(g,v1); while(k!=-1) { strcpy(v2,g.vertices[k].data); visit(v2); k=NextAdjVex(g,v1,v2); } printf("\n"); return 0; } int equal(ElemType a,ElemType b) { if(a.adjvex==b.adjvex) return 1; else return 0; } void visit(VertexType i) { printf("%s ",i); } int LocateElem(LinkList L,ElemType e,int (*equal)(ElemType,ElemType)) { // 初始条件: 不带头结点的单链表L已存在,equal()是数据元素判定函数(满足为1,否则为0) // 操作结果: 返回L中第1个与e满足关系equal()的数据元素的位序。 // 若这样的数据元素不存在,则返回值为0 int i=0; LinkList p=L; // L是不带头结点的单链表 while(p) { i++; if(equal(p->data,e)) // 找到这样的数据元素 return i; p=p->next; } return 0; } LinkList Point(LinkList L,ElemType e,int(*equal)(ElemType,ElemType),LinkList &p) { //查找表L中满足条件的结点。如找到,返回指向该结点的指针,p指向该结点的前驱(若该结点是首元结点,则p=NULL)。 //如表L中无满足条件的结点,则返回NULL,p无定义。函数equal()的两形参的关键字相等,返回OK;否则返回ERROR int i,j; i=LocateElem(L,e,equal); if(i) // 找到 { if(i==1) // 是首元结点 { p=NULL; return L; } p=L; for(j=2;j&lt;i;j++) p=p->next; return p->next; } return NULL; // 没找到 } int ListInsert(LinkList &L,int i,ElemType e) { // 在不带头结点的单链线性表L中第i个位置之前插入元素e int j=1; LinkList p=L,s; if(i&lt;1) // i值不合法 return 0; s=(LinkList)malloc(sizeof(struct LNode)); // 生成新结点 s->data=e; // 给s的data域赋值 if(i==1) // 插在表头 { s->next=L; L=s; // 改变L } else { // 插在表的其余处 while(p&&j&lt;i-1) // 寻找第i-1个结点 { p=p->next; j++; } if(!p) // i大于表长+1 return 0; s->next=p->next; p->next=s; } return 1; } int LocateVex(ALGraph G,VertexType u) { // 初始条件:图G存在,uG中顶点有相同特征 // 操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 /********** Begin **********/ /********** End **********/ } int FirstAdjVex(ALGraph G,VertexType v) { // 初始条件:图G存在,v是G中某个顶点 // 操作结果:返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1 /********** Begin **********/ /********** End **********/ } int NextAdjVex(ALGraph G,VertexType v,VertexType w) { // 初始条件:图G存在,v是G中某个顶点,w是v的邻接顶点 // 操作结果:返回v的(相对于w的)下一个邻接顶点的序号。若w是v的最后一个邻接点,则返回-1 /********** Begin **********/ /********** End **********/ } void CreateGraphF(ALGraph &G) { // 采用邻接表 存储结构,由文件构造没有相关信息图或网G(用一个函数构造4种图) /********** Begin **********/ /********** End **********/ } void Display(ALGraph G) { // 输出图的邻接表G /********** Begin **********/ /********** End **********/ } int LocateVex(ALGraph G,VertexType u) { // 初始条件:图G存在,uG中顶点有相同特征 // 操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 /********** Begin **********/ /********** End **********/ } int FirstAdjVex(ALGraph G,VertexType v) { // 初始条件:图G存在,v是G中某个顶点 // 操作结果:返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,则返回-1 /********** Begin **********/ /********** End **********/ } int NextAdjVex(ALGraph G,VertexType v,VertexType w) { // 初始条件:图G存在,v是G中某个顶点,w是v的邻接顶点 // 操作结果:返回v的(相对于w的)下一个邻接顶点的序号。若w是v的最后一个邻接点,则返回-1 /********** Begin **********/ /********** End **********/ }
最新发布
06-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值