C-如何模块化链接列表



我有以下链接列表:

#include <stdio.h>
#include <stdlib.h>
struct Node
{
    int data; // Linked List type of data.
    struct Node *next; // Pointer to the next Node.
};
void printfList(struct Node *head)
{
    while(head != NULL)
    {
        printf(" %dn", head -> data);
        head = head -> next;
    }
}

int main()
{
    struct Node *head   = NULL;
    struct Node *second = NULL;
    struct Node *third  = NULL;
    head   = (struct Node*) malloc(sizeof(struct Node));
    second = (struct Node*) malloc(sizeof(struct Node));
    third  = (struct Node*) malloc(sizeof(struct Node));
    head -> data = 1;
    head -> next = second;
    second -> data = 2;
    second -> next = third;
    third -> data = 3;
    third -> next = NULL;
    printfList(head);
    return 0;
}

我如何模块化这个示例以使一些更专业的东西?节点类型并与其他分开并分别函数?

我认为"模块化"在这里您是指更专业,看上去很干净的代码,我想到了以下内容:

#include <stdio.h>
#include <stdlib.h>
struct Node
{
    int data; // Linked List type of data.
    struct Node *next; // Pointer to the next Node.
};
struct Node * makeNode(int data){
    struct Node *temp = (struct Node*)malloc(sizeof(struct Node));
    temp->data = data;
    temp->next = NULL;
    return temp;
}
void printfList(struct Node *head)
{
    while(head != NULL)
    {
        printf(" %dn", head -> data);
        head = head -> next;
    }
}

int main()
{
    struct Node *head, *prev;
    int i, n;
    printf("How many values you want to insert ?");
    scanf("%d", &n);
    printf("nNow enter values :n");
    for(i = 0; i < n; i++){
        int val;
        scanf("%d", &val);
        if(i == 0){
            head = makeNode(val);
            prev = head;
        }
        else{
            struct Node *temp = makeNode(val);
            prev->next = temp;
            prev = temp;
        }
    }
    printfList(head);
    return 0;
}

希望它有帮助。

我不确定您要做什么,但是我认为您应该首先查看问题:"node"是否应该是对象的属性(struct数据类型)或"node"应该是数据类型的登录器...?

既有工作又有两者。

当我需要将现有对象链接在一起时,节点将包含参考数据类型...但是与您的列表不同,数据始终使用指针访问(不包含实际数据类型,但仅使用参考)。

这允许一个(对象)到许多(列表)关系。

但是,很多时候,数据类型本身将需要"链接"(在单个列表中 - 一对一),在这种情况下,"节点"是数据类型的属性,可以重新使用在许多不同类型的类型中。

链接现有类型的列表

这是我使用链接列表使用void指针链接现有对象的示例代码。

我不确定此实现是否将任何内容添加到您的最初概念中,但是它确实显示了"一个(objet))到许多(列表)"方法的"模块化"。

/* *****************************************************************************
Simple List
***************************************************************************** */
typedef struct fio_ls_s {
  struct fio_ls_s *prev;
  struct fio_ls_s *next;
  void *obj;
} fio_ls_s;
#define FIO_LS_INIT(name)                                                      
  { .next = &(name), .prev = &(name) }
/** Adds an object to the list's head. */
static inline __attribute__((unused)) void fio_ls_push(fio_ls_s *pos,
                                                       void *obj) {
  /* prepare item */
  fio_ls_s *item = (fio_ls_s *)malloc(sizeof(*item));
  if (!item)
    perror("ERROR: fiobj list couldn't allocate memory"), exit(errno);
  *item = (fio_ls_s){.prev = pos, .next = pos->next, .obj = obj};
  /* inject item */
  pos->next->prev = item;
  pos->next = item;
}
/** Adds an object to the list's tail. */
static inline __attribute__((unused)) void fio_ls_unshift(fio_ls_s *pos,
                                                          void *obj) {
  pos = pos->prev;
  fio_ls_push(pos, obj);
}
/** Removes an object from the list's head. */
static inline __attribute__((unused)) void *fio_ls_pop(fio_ls_s *list) {
  if (list->next == list)
    return NULL;
  fio_ls_s *item = list->next;
  void *ret = item->obj;
  list->next = item->next;
  list->next->prev = list;
  free(item);
  return ret;
}
/** Removes an object from the list's tail. */
static inline __attribute__((unused)) void *fio_ls_shift(fio_ls_s *list) {
  if (list->prev == list)
    return NULL;
  fio_ls_s *item = list->prev;
  void *ret = item->obj;
  list->prev = item->prev;
  list->prev->next = list;
  free(item);
  return ret;
}
/** Removes an object from the containing node. */
static inline __attribute__((unused)) void *fio_ls_remove(fio_ls_s *node) {
  void *ret = node->obj;
  node->next->prev = node->prev->next;
  node->prev->next = node->next->prev;
  free(node);
  return ret;
}

集成在数据类型中的列表

我经常有我知道我会链接在一起的对象,而且本质上只属于一个列表("一对一")。

在这些情况下,将node结构数据放置在数据类型中可以通过单个数据和节点信息进行单个分配,可以更好地进行局部性和改进的性能。

可以检查这种情况的一个很好的例子就是这样答案。

最新更新