我正在尝试在链接列表中添加一个简单的程序,并在开始之间添加。
#include<stdio.h>
#include<malloc.h>
struct node{
int data;
struct node* link;
};
/* Count the no of items in the list */
int count(struct node* q){
int c = 0;
while(q != NULL){
q = q->link;
c++;
}
return c;
}
/* Add a list at the last */
void append(struct node **q,int num){
struct node *temp,*r;
temp = *q;
/* List is empty */
if(temp == NULL){
temp = malloc(sizeof(struct node));
temp->data = num;
temp->link = NULL;
*q = temp;
}
else{
/* go to the last node */
while(temp->link != NULL){
temp = temp->link;
}
/* add node at the end */
r = malloc(sizeof(struct node));
r->data = num;
r->link = NULL;
temp->link = r;
}
}
/* add a node after the specific node */
void addafter(struct node *q,int loc,int num){
struct node *temp,*r;
int i;
temp = q;
/* Skip to the desired portion */
for(i = 0; i < loc; i++){
temp = temp->link;
if(temp == NULL){
printf("\n Few nodes - less nodes %d elements in list \n",loc);
return;
}
}
/* insert new node */
r = malloc(sizeof(struct node));
r->data = num;
r->link = temp->link;
temp->link = r;
}
/* add a node at the beginning */
void addatbeg(struct node **q, int num){
struct node *temp;
/* add a new node */
temp = malloc(sizeof(struct node));
temp->data = num;
temp->link = *q;
*q = temp;
}
/* Delete a linked list */
void delete(struct node **q,int num){
struct node *temp,*old;
temp = *q;
while(temp != NULL){
if(temp->data == num){
/* Node to be deleted is the first node */
if(temp == *q){
*q = temp->link;
free(temp);
return;
}
else{
/* Delete the Intermdediate nodes */
old->link = temp->link;
free(temp);
return;
}
}
else{
/* Traverse the linked list */
old = temp;
temp = temp->link;
}
}
}
/* Display the data in the list */
void display(struct node *q){
printf("\n");
while(q != NULL){
printf("\n Data : %d \n",q->data);
q = q->link;
}
}
int main(){
struct node *p;
p = NULL; /* Empty linked list */
printf("\n No of items in linked list : %d\n",count(p));
append(&p,100);
append(&p,200);
append(&p,300);
append(&p,400);
append(&p,500);
append(&p,600);
append(&p,700);
append(&p,800);
display(p);
addatbeg(&p,10);
addatbeg(&p,20);
addatbeg(&p,30);
display(p);
addafter(p,0,1000);
addafter(p,6,2000);
addafter(p,9,3000);
display(p);
printf("\n No of items in the linked list : %d\n",count(p));
delete(&p,800);
delete(&p,500);
display(p);
printf("\n No of items in the linked list : %d\n",count(p));
return 0;
}
我在addafter()
遇到问题,
在函数中,我们创建指向堆的指针的另一个副本,并且指针所做的更改将影响在main中声明的指针,因为它指向堆的相同收件人。
所以我认为我会对addatbeg()
做同样的事情,当我将**
更改为*
时,更改没有反映出来。为什么会这样?无论如何,如果addatbeg(struct node *,int num)
,那么指针也指向同一堆。
答案 0 :(得分:2)
这里的问题是p在main()
中被定义为
struct node *p;
现在,当您将其传递给addatbeg()
时,您希望更改存储在p的地址,因为它将指向已在列表开头添加的另一个节点。但是,当您使用像
addatbeg(struct node *,int num)
p实际上是按值传递的。要修改main中的p
,您需要传递其地址
addatbeg(struct node **,int num)
在addafter
中,您不会传递p
的地址,因为您不希望您的头指针发生变化。
您可以将情况与更简单的情况进行比较。当您按值传递整数时,使用foo(int)
,但是当您想要修改原始整数时,您将传递其地址,如foo(int *)
。同样的事情是在这里进行额外的解除引用。
答案 1 :(得分:1)
您需要**
根据需要包含头指针所包含的值,该指针将包含链接列表第一个节点的地址。您正在传递地址的地址,因此您需要一个双指针