0

我正在尝试在链表上添加一个简单的程序,并在开始之间添加。

#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),那么指针也指向同一个堆。

4

2 回答 2

2

这里的问题是 p 被定义main()

struct node *p;

现在,当您将其传递给 时addatbeg(),您希望更改存储在 p 中的地址,因为它将指向已添加到列表开头的另一个节点。但是,当您使用类似的定义时

addatbeg(struct node *,int num)

p 实际上是按值传递的。为了修改pin main,你需要传递它的地址

addatbeg(struct node **,int num)

addafter中,您不传递 的地址,p因为您不希望头指针发生变化。

您可以将这种情况与更简单的情况进行比较。当您通过值传递一个整数时,您使用foo(int),但是当您想要修改原始整数时,您传递它的地址,如foo(int *). 同样的事情在这里发生了额外的取消引用。

于 2013-10-15T09:41:57.757 回答
1

您需要 **头指针包含的值,该值将包含链表第一个节点的地址。您正在传递地址的地址,因此您需要一个双指针

于 2013-10-15T09:42:12.513 回答