我试图弄清楚如何用双向链接列表编写以下代码。
将要求用户输入一个数字。如果数字为负,则应在开头添加数字,如果数字为负,则应在结尾添加数字。当用户输入0时,程序将停止。
我必须使用以下预定义的结构。
由于使用“ typedef struct Node * NodePtr;”,我有点困惑然后是两个结构中的NodePtr。有人可以给我解释一下这里的正确思维方式是什么?
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct Node* NodePtr; /* Pointer to a node */
typedef struct Node /* Node contains a read number */
{
int n; /* Stored number */
NodePtr prev;
NodePtr next;
} Knoten;
typedef struct
{ /* Structure for double linked lists: start + end */
NodePtr start; /* Pointer to the beginning of the doubly linked list */
NodePtr end; /* Pointer to the end of the doubly linked list */
} DVListe;
到目前为止,这就是我所拥有的。当然,还有很多错误和细分错误:)
我仍然不明白在哪里定义起点和终点,应该将newNode或NodePtr或与之完全不同的东西分配给谁? :/
// continue
DVList *h = NULL;
Knoten *newNode;
void negative_start(int n)
{
if (newNode == NULL)
{
newNode = malloc(sizeof(Knoten));
if (newNode == NULL)
{
printf("ERROR! Could not allocate memory");
exit(EXIT_FAILURE);
}
newNode->n = n;
newNode->prev = NULL;
newNode->next = NULL;
newNode = h->start;
h->start = h->end;
}
else
{
newNode = malloc (sizeof(Knoten));
if (newNode == NULL)
{
printf("ERROR! Could not allocate memory");
exit(EXIT_FAILURE);
}
newNode->n = n;
newNode->next = h->start;
newNode->prev = NULL;
h->start = newNode;
}
}
void positive_end(int n)
{
// I didn't write it because it will be wrong like the negative_start function.
}
int main ()
{
int x;
newNode = NULL;
printf("\n Enter a number ");
scanf("%d", &x);
while ( x != 0)
{
if ( x < 0 ){ negative_start(x);
}
else{ positive_end(x);
}
scanf("%d", &x);
}
return 0;
}
我尝试使用@ChrisTurner结构从新编写代码。
它仅适用于负数。如果我仅输入任何正数,它们将被丢弃。有人可以帮我这个吗?
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct Node Knoten;
typedef struct DVListe_s DVList;
struct Node
{
int n;
Knoten *next;
Knoten *prev;
};
struct DVListe_s
{
Knoten *start;
Knoten *end;
};
DVList *construct()
{
DVList *list;
list = malloc (sizeof(DVList));
list->start = NULL;
list->end = NULL;
return list;
}
void add_negative_start (DVList *list, int n)
{
if (list->start != NULL)
{
Knoten *newNode = malloc(sizeof(Knoten));
newNode->prev = NULL;
newNode->next = NULL;
newNode->n = n;
newNode->next = list->start;
list->start = newNode;
}
else
{
Knoten *newNode = malloc(sizeof(Knoten));
newNode->prev = NULL;
newNode->next = NULL;
newNode->n = n;
list->start = newNode;
list->end = list->start;
}
}
void add_positive_end(DVList *list, int n)
{
if (list->end != NULL)
{
Knoten *newNode = malloc(sizeof(Knoten));
newNode->prev = NULL;
newNode->next = NULL;
newNode->n = n;
newNode->prev = list->end;
list->end = newNode;
}
else
{
Knoten *newNode = malloc(sizeof(Knoten));
newNode->prev = NULL;
newNode->next = NULL;
newNode->n = n;
list->end = newNode;
list->start = list->end;
}
}
void print(DVList *list)
{
Knoten *temp = list->start;
printf ("Entered Numbers\n");
while (temp != NULL)
{
printf("%d\n", temp->n);
temp = temp->next;
}
}
int main()
{
DVList *list = construct();
int x = 1;
printf("Enter a number\n");
while (x)
{
scanf ("%d", &x);
if (x < 0)
{
add_negative_start(list, x);
}
else
{
add_positive_end(list, x);
}
}
print(list);
return 0;
}
R
最佳答案
typedef
在NodePtr
和struct Node *
之间创建可以被视为别名的名称,这样,每当您放置NodePtr
时,编译器就会知道您的实际意思是struct Node *
。
您不能在struct NodePtr
内使用struct NodePtr
,因为那时候它不知道struct NodePtr
有多大,因此,无论您是否使用typedef
,都需要在此时使用指针。
在您的DVListe
中,因为列表将从一开始就为空,所以在此处使用指针,以便可以将start
和end
设置为NULL
来指示或如果您有一个节点,它们都可以指向同一个地方。
我个人认为创建typedef
指向某个对象的指针并不是一个好主意,尽管您至少清楚地表明它是带有名称的指针。您可能会丢失该typedef
并且也要这样做。
typedef struct Node Knoten;
typedef struct DVListe_s DVListe;
struct Node /* Node contains a read number */
{
int n; /* Stored number */
Node *prev;
Node *next;
};
struct DVListe_s
{ /* Structure for double linked lists: start + end */
Node *start; /* Pointer to the beginning of the doubly linked list */
Node *end; /* Pointer to the end of the doubly linked list */
};