我正在试图弄清楚如何用双链表来编写下面的代码。
将要求用户输入一个号码。如果数字为负数,则应在开头添加,如果最终为正数。当用户输入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
答案 0 :(得分:0)
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 */
};