p->link和p->next的区别
时间: 2023-06-11 16:07:26 浏览: 66
在 C 语言中,通常我们使用指针来操作链表。假设我们有一个链表节点的结构体定义如下:
```
struct ListNode {
int val;
struct ListNode *next;
};
```
其中,`val` 是节点的值,`next` 是指向下一个节点的指针。
现在,假设我们有一个指向链表节点的指针 `p`,那么 `p->next` 和 `p->link` 都可以用来访问下一个节点。但是,这两者的命名可能有所不同,取决于程序员自己定义的结构体中指向下一个节点的指针的名称是什么。
通常来说,`p->next` 更为常见,因为在 C 语言中,我们习惯将指向下一个节点的指针命名为 `next`。而 `p->link` 更多地出现在一些自定义结构体中,表示节点之间的连接关系。但是,这两者并没有本质的区别,可以根据个人喜好来使用。
相关问题
改良代码struct link * liu(struct link *head) { struct link *pr=head,*p=head; if(head==NULL) { printf("链表为空\n"); exit(0); } char b[10]={'\0'}; printf("请输入要删除的书名\n"); scanf("%s",b);fflush(stdin); while(p!=NULL) { if(strcmp(p->book,b)==0) { if(p==head) {printf("登录号 分类号 出版时间 价格 书名 作者名 出版单位\n"); printf("%-8d%-8d%-10d%-8d%-25s%-15s%-s\n",p->data,p->kindofnumber,p->time,p->price,p->book,p->writer,p->publisher); head=p->next; free(p);break; } else { pr->next=p->next;free(p);break; } } pr=p; p=p->next; } return (head); }
这段代码是一个删除链表节点的函数,根据输入的书名b进行匹配,如果匹配到则删除对应节点。但是有几个需要改进的地方:
1. 输入的书名b的长度最好不要超过9个字符,否则会导致数组越界。
2. fflush(stdin)不是标准的写法,不同的编译器可能会有不同的实现。可以考虑用getchar()来清空输入缓冲区。
3. 在删除节点之前最好先判断一下链表是否为空,否则会出现访问空指针的情况。
改进后的代码如下:
```
struct link * liu(struct link *head) {
if(head == NULL) {
printf("链表为空\n");
return head;
}
char b[100] = {'\0'}; // 改为100,避免数组越界
printf("请输入要删除的书名\n");
scanf("%s", b);
getchar(); // 清空输入缓冲区
struct link *pr = head, *p = head;
while(p != NULL) {
if(strcmp(p->book, b) == 0) {
printf("登录号 分类号 出版时间 价格 书名 作者名 出版单位\n");
printf("%-8d%-8d%-10d%-8d%-25s%-15s%-s\n", p->data, p->kindofnumber, p->time, p->price, p->book, p->writer, p->publisher);
if(p == head) {
head = p->next;
free(p);
} else {
pr->next = p->next;
free(p);
}
break;
}
pr = p;
p = p->next;
}
return head;
}
```
void eDFS(int v, int level){ struct edge *p; if(v == V1) {printPath(level); return;} for(p=Graph[v].link; p!= NULL; p=p->next) if( !Visited[p->adjvex]){ Paths[level] = p->eno; Visited[p->adjvex] = 1; eDFS(p->adjvex,level+1); Visited[p->adjvex] = 0; } }
这段代码实现了一个无向图的欧拉路径搜索,其中参数v表示搜索起点,level表示当前搜索的深度。函数eDFS中使用了深度优先搜索算法,遍历图中的所有可能路径,并记录已经访问过的节点。
具体实现过程如下:
1. 首先判断起点v是否为欧拉路径的起点V1,如果是则输出当前的路径(即Paths数组中的元素),并返回。
2. 遍历起点v的所有邻居节点,对于每个未被访问过的邻居节点p->adjvex,进行以下操作:
- 将边p->eno的编号记录到Paths数组的第level个位置上。
- 将邻居节点p->adjvex标记为已访问。
- 递归调用eDFS函数,以邻居节点p->adjvex作为新的起点,继续搜索。
- 在递归调用结束后,将邻居节点p->adjvex标记为未访问,以便后续搜索。
3. 当所有邻居节点都被遍历完后,函数返回。
下面是这段代码的完整实现:
```c
#define MAX_VERTICES 100
#define MAX_EDGES 1000
struct edge {
int adjvex;
int eno;
struct edge *next;
};
struct graph {
int nvertices;
int nedges;
struct edge *link[MAX_VERTICES];
} Graph;
int Visited[MAX_VERTICES];
int Paths[MAX_EDGES];
int V1;
void printPath(int level) {
int i;
for (i = 0; i < level; i++) {
printf("%d ", Paths[i]);
}
printf("\n");
}
void eDFS(int v, int level) {
struct edge *p;
if (v == V1) {
printPath(level);
return;
}
for (p = Graph[v].link; p != NULL; p = p->next) {
if (!Visited[p->adjvex]) {
Paths[level] = p->eno;
Visited[p->adjvex] = 1;
eDFS(p->adjvex, level + 1);
Visited[p->adjvex] = 0;
}
}
}
int main() {
int i, V2, E, v, w;
struct edge *p;
scanf("%d %d", &V1, &E);
Graph.nvertices = V1;
Graph.nedges = 0;
for (i = 0; i < V1; i++) {
Graph.link[i] = NULL;
}
for (i = 0; i < E; i++) {
scanf("%d %d", &v, &w);
p = (struct edge *)malloc(sizeof(struct edge));
p->adjvex = w;
p->eno = i + 1;
p->next = Graph.link[v];
Graph.link[v] = p;
p = (struct edge *)malloc(sizeof(struct edge));
p->adjvex = v;
p->eno = i + 1;
p->next = Graph.link[w];
Graph.link[w] = p;
Graph.nedges++;
}
Visited[V1] = 1;
eDFS(0, 0);
return 0;
}
```