我对链表感到困惑。解决方案是什么?

时间:2017-08-04 08:19:23

标签: c

特别是我觉得在功能上传递头部很困惑。任何人都可以解释一下吗?

#include<stdio.h>

struct node    
{    
    int data;

    struct node *next;    
};   

struct node *makeNode(int item)    
{    
    struct node *newNode = (struct node *)malloc(sizeof(struct node));

    newNode->data = item;

    newNode->next = NULL;

    return newNode;
}    

void traverse(struct node *head)    
{    
    struct node *ptr = head;

    while(ptr != NULL)    
    {    
        printf("%d ",ptr->data);

        ptr = ptr->next;
   }

    printf("\n");
}

void push(struct node **headRef, int data)    
{    
    struct node *newNode = makeNode(data);

    newNode->next = *headRef;

    *headRef = newNode;    
}

void append(struct node **headRef, int data)    
{

    struct node *newNode = makeNode(data);

    struct node *ptr = *headRef, *temp;

    if( ptr == NULL )    
    {    
        *headRef = newNode;

        return;
    }

    while(ptr != NULL)    
    {   

        temp = ptr;

        ptr = ptr->next;    
    }

    temp->next = newNode;    
}


void deleteData(struct node **headRef, int key)    
{    
    struct node *ptr = *headRef, *prevNode;

    //If key is in head node

    if( (ptr->data == key) && (ptr != NULL) )    
    {    
        *headRef = ptr->next;

        free(ptr);

        return;    
    }


    while( (ptr != NULL) && (ptr->data!=key) )    
    {    
        prevNode = ptr;

        ptr = ptr->next;    
    }


    if(ptr == NULL)    
        printf("Underflow or Key not found.\n");    
    else    
    {    
        prevNode->next = ptr->next;    
        free(ptr);    
    }    
}

int main()    
{    
    struct node *head = NULL;

    int data;

    printf("Enter Positive Data:\n");

    scanf("%d",&data);

    while( data>=0 )    
    {    
        append(&head,data);

in this function , pass the address of head.

        scanf("%d",&data);    
    }

    printf("\nTraversing...\n");

    traverse(head);

but in this function why i only pass the head?

    printf("\n\nEnter a data to delete:\n");

    scanf("%d",&data);

    deleteData(&head,data);

    printf("\nTraversing...\n");

    traverse(head);    
}

3 个答案:

答案 0 :(得分:1)

在函数遍历

void traverse(struct node *head) {
    ......
    ......
}

遍历函数有一个参数head,它是struct node pointer的类型 因此,要调用traverse函数,必须传递类型为struct node pointer的参数 在主要功能中,您将头部定义为struct node *head = NULL;
这就是你调用像traverse(head)这样的函数的原因。

在功能追加

void append(struct node **headRef, int data)    
{
    ....
    ....

}

参数headref的类型为'指向指针'。

  

Pointer指针变量存储指针的地址

因此,您必须将指针的地址作为参数传递,并调用将函数追加为append(&head,data)

在追加函数

中使用指针作为参数

将函数的返回类型从void更改为struct node*并返回headRef指针。

struct node* append(struct node *headRef, int data)    
{
    struct node *newNode = makeNode(data);
    struct node *ptr = headRef, *temp;
    if( ptr == NULL )    
    {    
        headRef = newNode;
        return headRef;
    }
    while(ptr != NULL)    
    {   
        temp = ptr;
        ptr = ptr->next;    
    }
    temp->next = newNode;
    return headref;
}

在main函数中,你应该像这样调用append函数。

head = append(head,data); //since append function is now returning a pointer

使用单指针附加节点的完整代码

#include<stdio.h>
struct node

{

  int data;

  struct node * next;
};

struct node * makeNode(int item)

{

  struct node * newNode = (struct node * ) malloc(sizeof(struct node));

  newNode -> data = item;

  newNode -> next = NULL;

  return newNode;
}


void traverse(struct node * head)

{

  struct node * ptr = head;

  while (ptr != NULL)

  {

    printf("%d ", ptr -> data);

    ptr = ptr -> next;

  }

  printf("\n");
}

struct node * append(struct node * headRef, int data)

{

  struct node * newNode = makeNode(data);

  struct node * ptr = headRef, * temp;

  if (ptr == NULL)

  {

    headRef = newNode;

    return headRef;

  }

  while (ptr != NULL)

  {

    temp = ptr;

    ptr = ptr -> next;

  }

  temp -> next = newNode;

  return headRef;
}

int main()

{

  struct node * head = NULL;

  int data;

  printf("Enter Positive Data:\n");

  scanf("%d", & data);

  while (data >= 0)

  {

    head = append(head, data);

    scanf("%d", & data);

  }

  printf("\nTraversing...\n");

  traverse(head);
  return 0;
}

答案 1 :(得分:0)

函数append可能会改变head的值(这是一个指针)。因此签名是void append(struct node **headRef, int data);请注意**,它表示指针的指针。所以你必须传递指针的地址才能允许append更改指针,即调用append(&head,data)

相反,函数traverse不需要改变head的值,因此它直接使用指针(而不是指向该指针的指针)。因此签名是void traverse(struct node *head);请注意单*。因此,请将其称为traverse(head)

答案 2 :(得分:0)

包括

struct node

{

int data;




struct node *next;

};

struct node * makeNode(int item)

{

struct node *newNode = (struct node *)malloc(sizeof(struct node));

newNode->data = item;




newNode->next = NULL;




return newNode;

}

我在上面的行中遇到了错误

void traverse(struct node * head)

{

struct node *ptr = head;





while(ptr != NULL)




{




    printf("%d ",ptr->data);




    ptr = ptr->next;




}




printf("\n");

}

我知道没有必要返回指针。这是真的吗?如果是真的,为什么需要在以下函数中给出一个返回类型?

struct node * append(struct node * headRef,int data)

{

struct node *newNode = makeNode(data);




struct node *ptr = headRef, *temp;




if( ptr == NULL )




{




    headRef = newNode;




    return headRef;




}




while(ptr != NULL)




{




    temp = ptr;




    ptr = ptr->next;





}





temp->next = newNode;






return headref;

}

int main()

{

struct node *head = NULL;





int data;





printf("Enter Positive Data:\n");





scanf("%d",&data);





while( data>=0 )





{





   head=append(head,data);





    scanf("%d",&data);





}





printf("\nTraversing...\n");





traverse(head);

}