【问题标题】:C Issue - Double-Linked List for a List of StudentsC 问题 - 学生列表的双链表
【发布时间】:2021-03-14 21:35:52
【问题描述】:

所以这是我的麻烦,我正在尝试制作C 中的双链表。 但我无法正确添加学生,程序一直在崩溃。 我想做两个函数,一个在头部添加,一个在尾部添加。

希望有人能帮我解决这个问题!准备二叉树,圈出列表考试,所以我想我会从这个开始。 谢谢!

'''

typedef struct student
{
    char *ime;
    char *prezime;
    char *brIndeksa;
    int godStudija;
    float prosek;
    struct student *next;
    struct student *prev;
}Student;

Student *NewStudent ();
void AddOnHead ( Student **p );

int main()
{
    int n, i;   printf("Broj studenata: "); scanf("%d", &n);
    
    Student *studenti = NULL;
    
    for ( i = 0; i < n; i++ )
        AddOnHead(&studenti);
        
    Print(studenti);
    PrintFloat(studenti,7.5);
         
    return 0;
}

Student *NewStudent ()
{
    Student *newStudent;
    newStudent = (Student*)malloc(sizeof(Student));
    if ( newStudent == NULL )
    {
        printf("ERROR: Greska u alokaciji memorije. \n");
        exit(1);
    }
    
    char txt[50];
    printf("PODACI: \n");
    
    printf("IME: ");
    scanf("%s", txt);
    newStudent->ime = (char*)malloc(strlen(txt)+1);
    if ( newStudent->ime == NULL )
    {
        printf("ERROR: Greska u alokaciji memorije. \n");
        exit(1);
    }
    strcpy(newStudent->ime,txt);
    
    printf("PREZIME: ");
    scanf("%s", txt);
    newStudent->prezime = (char*)malloc(strlen(txt)+1);
    if ( newStudent->prezime == NULL )
    {
        printf("ERROR: Greska u alokaciji memorije. \n");
        exit(1);
    }
    strcpy(newStudent->prezime,txt);
    
    printf("BROJ INDEKSA: "); 
    scanf("%s", txt);
    newStudent->brIndeksa = (char*)malloc(strlen(txt)+1);
    if ( newStudent->brIndeksa == NULL )
    {
        printf("ERROR: Greska u alokaciji memorije. \n");
        exit(1);
    }
    strcpy(newStudent->brIndeksa,txt);

    printf("GODINA STUDIJA: ");
    scanf("%d", newStudent->godStudija);
    
    printf("PROSEK: ");
    scanf("%f", newStudent->prosek);
    
    newStudent->next = NULL;
    newStudent->prev = NULL;
    
    putchar('\n');
    
    return newStudent;
}

void AddOnHead ( Student **p )
{
    Student *novi = NewStudent();
    
    if ( *p == NULL )
        *p = novi;
    else
    {
        Student *tmp = *p;
        tmp->prev = novi;
        novi->next = tmp;
        tmp = novi;
    }
}

'''

【问题讨论】:

  • 在这样的 scanf 调用中 scanf("%d", newStudent->godStudija);你必须使用像 scanf("%d", &newStudent->godStudija); 这样的指针
  • 在函数 AddOnHead 你必须写 *p = novi;而不是 tmp = novi;
  • 哦!太感谢了。我忽略了那一点,它现在有效。万事如意!
  • 注意如果你有一个双向链表,那么你应该再声明一个包含至少两个指针的结构:指向头节点和尾节点。
  • 你的意思是这样的吗? ``` structstudenti{ 字符 *ime,*prezime,*br_ind;诠释戈迪纳;浮动散文; }; structlista{` structstudenti *glava;结构列表 *rep; }; ```

标签: c struct linked-list doubly-linked-list function-definition


【解决方案1】:

在 scanf 的这些调用中

scanf("%d", newStudent->godStudija);

scanf("%f", newStudent->prosek);

第二个参数必须是指向类似对象的指针

scanf("%d", &newStudent->godStudija);

scanf("%f", &newStudent->prosek);

在函数AddOnHead而不是这个语句中

tmp = novi;

你必须写

*p = novi;

函数可以定义得更简单。例如

void AddOnHead ( Student **p )
{
    Student *novi = NewStudent();
    
    novi->next = *p;

    if ( *p != NULL ) ( *p )->prev = novi;

    *p = novi;
}

另外,如果你有一个双向链表,那么你应该再声明一个结构,例如

struct List
{
    struct student *head;
    struct student *tail;
};

在这种情况下,将节点附加到列表尾部的函数将有效。您无需遍历整个列表即可获取最后一个节点。

例如

struct List list = { .head = NULL, .tail = NULL };

对于这样的列表,函数 AddOnHead 看起来像

void AddOnHead( struct List *list )
{
    Student *novi = NewStudent();
    
    novi->next = list->head;

    if ( list->head != NULL )
    {
        list->head->prev = novi;
    }
    else
    {
        list->tail = novi;
    }

    list->head = novi;
}

并且函数可以像这样调用

AddOnHead( &list );

【讨论】:

  • 非常感谢!这是荒谬的惊人。我花了好几个小时才明白这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多