【问题标题】:How to create a node, and then add it to a link list?如何创建节点,然后将其添加到链接列表中?
【发布时间】:2015-09-24 16:20:06
【问题描述】:

这是我目前所拥有的!我很困惑,因为我不知道在哪里添加它们。我们在课堂上研究节点已经有一段时间了,但我的教授即使你问问题也不喜欢解释。这是我们的家庭作业。所以我想知道如何创建一个将节点添加到链接列表的函数?

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

struct Node 
{ 
    double nodeData;
    int nodeLink;
};

void main(void)
{

    struct Node  List[15];
    int Begin, current;

    Begin = 0;

    for (current = Begin; current < 15; current++)
        List[current].nodeLink = 0;

    List[0].nodeData = 3.141593;
    List[0].nodeLink = -1;

    List[1].nodeData = 25.992;
    List[1].nodeLink = -1;

    List[0].nodeLink = 1;

    for (int i = Begin; i != -1; i = List[i].nodeLink)
        printf("%f\n", List[i].nodeData);



}

【问题讨论】:

  • 为什么你的nodeLinkint?它应该引用下一个Node
  • 不管你的教授是好是坏,做链表作业的正确方法是先把它画在纸上,说明每个操作是如何完成的。绘制方框、线条等。不要尝试“从头开始”编写程序。一旦您在纸上看到它是如何完成的,那么将其转换为代码或多或少是容易的部分。
  • 我们的教授说nodeLink应该是一个int。
  • 当您使用调试器时,是哪一行导致了问题?
  • @Michael:作业是用数组实现链表。因此,链接字段是包含下一个节点的数组槽的索引。

标签: c linked-list nodes


【解决方案1】:

节点.h

#ifndef NODE_H
#define NODE_H

struct Node {
    double nodeData;
    int nodeLink;
};

extern struct Node *new_Node(double value);
extern void free_Node(struct Node *node);
extern struct Node *next_Node(struct Node *node);
extern void add_to_last_Node(struct Node *list, struct Node *node);

#endif

节点.c

#include <stddef.h>
#include "Node.h"

#define NUM_OF_NODES 15
#define END_OF_NODE  -1
#define UNUSED       -2

static int initialized = 0;
static int current = 0;
static struct Node Node_pool[NUM_OF_NODES];

static void init(void){
    for(int i=0; i < NUM_OF_NODES; i++){
        Node_pool[i].nodeLink = UNUSED;
    }
    initialized = 1;
}

struct Node *new_Node(double value){
    if(!initialized)
        init();
    if(current < NUM_OF_NODES){
        Node_pool[current].nodeData = value;
        Node_pool[current].nodeLink = END_OF_NODE;
        return &Node_pool[current++];
    } else {
        for(int i=0; i < NUM_OF_NODES; ++i){
            if(Node_pool[i].nodeLink == UNUSED){
                Node_pool[i].nodeData = value;
                Node_pool[i].nodeLink = END_OF_NODE;
                return &Node_pool[i];
            }
        }
        return NULL;
    }
}

void free_Node(struct Node *node){
    node->nodeLink = UNUSED;
}

struct Node *next_Node(struct Node *node){
    return node->nodeLink < 0 ? NULL : Node_pool + node->nodeLink;
}

void add_to_last_Node(struct Node *list, struct Node *node){
    if(!list || !node)
        return ;

    struct Node *temp = list, *prev = NULL;

    while(temp = next_Node(prev = temp))
        ;
    prev->nodeLink = node - Node_pool;
}

main.c

#include <stdio.h>
#include "Node.h"

int main(void){
    struct Node *begin, *aNode, *temp;

    begin = new_Node(3.141593);
    aNode = new_Node(25.992);
    add_to_last_Node(begin, aNode);
    aNode = new_Node(2.2360679);
    add_to_last_Node(begin, aNode);

    for(temp = begin; temp != NULL; temp = next_Node(temp))
        printf("%f\n", temp->nodeData);

    temp = begin;
    while(temp){
        struct Node *save = temp;
        temp = next_Node(temp);
        free_Node(save);
    }
    return 0;
}

>gcc main.c Node.c -std=c99 -o sample

>sample
3.141593
25.992000
2.236068

【讨论】:

    【解决方案2】:

    链表的字面意思是:它是一个节点列表,所有节点都指向下一个节点(顺便说一下,nodeLink 应该是 Node* 类型,而不是 int 类型)以形成彼此之间的链接。一个基本的单向链表将跟踪一个头指针(它也只是一个 Node*)并使用它向下递归(从头开始,获取下一个指针,然后从中获取下一个指针,然后下一个...),直到找到要影响的位置或直到下一个 nodeLink 为 NULL。从那里它只是创建一个新节点并相应地分配 nodeLink 值:

    Node* newNode = new Node();
    newNode->nodeData = 3.14d;
    currentNode->nodeLink = newNode;
    

    如果您出于某种原因需要将其设为 int,则可以使用 reinterpret cast:

    Node* currentNode = reinterpret_cast<Node*>(currentNode->nodeLink); // Grab the next link
    currentNode->nodeLink = reinterpret_cast<int>(newNode); // Do the assignment
    

    但这会在 sizeof(void*) != sizeof(int) 像 x86_64 系统的系统上中断,所以这就是为什么 cmets 中的@Michael 说它应该是一个实际的指针值,不是一个整数。无缘无故地做这样的事情通常也是不好的编程习惯。

    【讨论】:

    • 您的实现不适用于数组。作业要求是使用数组实现链表。您不能假设所有链表都使用堆或指针。在基于数组的链表中,链接是包含节点的数组槽的索引。这种技术也适用于文件,其中链接是文件位置(偏移量)。
    • @ThomasMatthews 他没有指定它必须是一个数组。他提供了使用数组的代码,但没有指出这是一项要求。至少在我写答案的时候没有这样的迹象。
    • 看结构。链接字段是一个整数。看list的声明,是一个结构体数组
    • 哦。现在更有意义了!
    • 除了 Op 没有这么说。他需要帮助,唯一明显的限制是下一个节点是 int。我从来没有说过它在所有情况下都毫无意义。甚至 Op 在 cmets 中也说没有提到数组。所以我认为投反对票有点不合适。
    【解决方案3】:

    这是一个可能的函数签名:

    #define MAXIMUM_NODES 15
    
    void Add_To_List(double value, Node singly_list[MAXIMUM_NODES])
    {
    }
    

    您可以从您的 main 函数中调用它:

      Add_To_List(3.14159, list);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-16
      • 2023-01-12
      • 1970-01-01
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      • 2017-03-19
      • 2022-08-17
      相关资源
      最近更新 更多