Aommm 发表于 2023-7-19 16:42:39

单链表头插法相关问题求教,谢谢

#include <stdio.h>
#include <stdlib.h>

typedef int Elemtype ;
typedef struct LNode {
        Elemtype data;
        struct LNode* next;
}LNode, * LinkList;

//头插法建新链表
LinkList CreatList1(LinkList &L)
{
        LNode* s;
        int x;
        L = (LinkList)malloc(sizeof(LNode));
        L->next = NULL;
        scanf("%d",&x);
        while (x != 9999)
        {
                s = (LNode*)malloc(sizeof(LNode));
                s->data = x;
                s->next = L->next;
                L->next = s;
                scanf("%d",&x);
        }
        return L;
}

int main()
{
        LinkList L;
        CreatList1(L);
}


以上代码是单链表头插法,问题如下:

1.
typedef struct LNode {
        Elemtype data;
        struct LNode* next;
}LNode, * LinkList;

这声明结构体这段代码中,大括号后的LNode是在给大括号前的struct LNode别名加定义吗?*LinkList是在给括号内的struct LNode* next;起别名加定义吗?这段代码是否等同于下面这个代码?

struct LNode {
        Elemtype data;
        struct LNode* next;
};
int main()
{
        struct LNode LNode;
        struct LNode *LinkList;
}

2.主函数中LinkList L;是什么含义?是在定义头指针还是头结点?LinkList类型是结构体指针变量,感觉L是一个指针,但是子函数中 L = (LinkList)malloc(sizeof(LNode));在给L分配内存空间,感觉L又应该是一个结点。s是一个结点定义了LNode类型,L却定义了LinkList类型。且指针存储的是内存地址,那么结构体指针又是什么含义呢?
(反正就是结构体指针这里很迷糊……虚心向大佬求教,谢谢)

陶远航 发表于 2023-7-19 16:43:02

1. 在这段代码中,typedef struct LNode {Elemtype data; struct LNode* next;} LNode, * LinkList;的作用是为结构体LNode创建一个别名LinkList,并定义了一个指向LNode类型的指针变量。

其中,大括号后的LNode是为大括号前的struct LNode起了一个别名LinkList,并定义了一个结构体指针变量。*LinkList则是为括号内的struct LNode* next;(也就是结构体中的指针成员)起了一个别名LinkList。

这段代码等同于下面这个代码:
struct LNode {
Elemtype data;
struct LNode* next;
};
typedef struct LNode LNode, * LinkList;


2. 主函数中的LinkList L;定义的是头指针。LinkList类型是一个结构体指针变量,L是一个指针。在子函数中,L = (LinkList)malloc(sizeof(LNode));为L分配了内存空间,将其指向新创建的头节点。

在链表操作中,头指针是指向链表第一个节点的指针,而头结点是在链表头部额外添加的一个节点,在本代码中没有显式定义头结点。

结构体指针的含义是指该指针变量指向一个结构体类型的实例或者指向结构体类型的第一个成员的地址。在这里,LinkList是指向LNode类型的结构体指针变量,即指向链表的节点。

希望这能解答您的问题,如果还有疑问,请随时提问。

isdkz 发表于 2023-7-19 17:04:57

非常好的问题,我尽量解答:

1.typedef 关键字用于为现有的类型定义一个新的别名。在你的代码中, LNode 是 struct LNode 的别名, LinkList 是 struct LNode* (LNode的指针)的别名。所以,你的理解是正确的。

   所以,这段代码:

        typedef struct LNode {
            Elemtype data;
            struct LNode* next;
    }LNode, * LinkList;
   
   是等同于下面这段代码:

        struct LNode {
            Elemtype data;
            struct LNode* next;
    };
    typedef struct LNode LNode;
    typedef struct LNode *LinkList;
   
   注意,这并不等同于你给出的示例:

        int main()
    {
            struct LNode LNode;
            struct LNode *LinkList;
    }
   
    在这段代码中, LNode 和 LinkList 是变量,而不是类型别名。

2.LinkList L; 在这里, L 是一个 LinkList 类型的变量,即 LNode 结构的指针。当你调用 malloc(sizeof(LNode)) 时,你正在请求足够的内存来存储一个 LNode 类型的结构,并返回该内存区域的地址。然后,你将此地址存储在 L 中,使 L 指向你创建的新节点。

   结构体指针是指向结构体的指针。因此, L 实际上是一个指向 LNode 结构的指针。由于 LNode 本身包含一个指针,用于指向链表中的下一个节点,所以 L 可以被用作链表的头指针,其指向的第一个节点即链表的头节点。

   可能的混淆源于 LinkList 类型的声明:实际上, LinkList 是 struct LNode* 的别名,所以 LinkList 类型的变量是指向 LNode 结构的指针,即它是一个地址,这个地址存储的是 LNode 结构的位置。所以当你说“L是一个指针”时,你是正确的。当你说“L是一个节点”时,应该更准确地说“L指向一个节点”。

希望这个答案对你有所帮助!如果你还有其他关于链表或指针的问题,欢迎随时向我提问。

Aommm 发表于 2023-7-19 17:34:19

isdkz 发表于 2023-7-19 17:04
非常好的问题,我尽量解答:

1.typedef 关键字用于为现有的类型定义一个新的别名。在你的代码中, LNo ...

太厉害啦!讲得好清楚易懂!超级感谢!
页: [1]
查看完整版本: 单链表头插法相关问题求教,谢谢