我目前正在计算双链表的实现。听起来很奇怪,我 想要 重复的项目添加到我的链接列表中。 我按排序顺序将newNode添加到列表中。
以下功能不会添加重复节点。
struct Node
{
char name[42];
struct Node *next;
struct Node *prev;
};
void addSorted(struct Node **head, struct Node *newNode)
{
struct Node* current;
// Special case for the head end
if ((*head == NULL) || strcmp((*head)->name, newNode->name) >= 0)
{
newNode->next = *head;
*head = newNode;
}
else
{
// Locate the Node before the point of insertion
current = *head;
while (current->next != NULL &&
strcmp(current->next->name, newNode->name) <= 0)
{
current = current->next;
}
newNode->next = current->next;
current->next = newNode;
}
}
struct Node* GetNewNode(char *name)
{
struct Node* newNode = malloc(sizeof (struct Node));
strcpy(newNode->name, name);
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
int main(void)
{
// Some Irrelevant Code
if (strncmp(operator, "a", 1) == 0)
{
temp = GetNewNode(name);
addSorted(&head, temp);
}
}
答案 0 :(得分:1)
我认为主要的一点是你没有处理 prev 指针以及第一个if,应该有两种情况,
if(*head==NULL)
{
*head=newNode;
}
else if(strcmp((*head)->name, newNode->name) >= 0)
{
(*head)->prev=newNode;//ADD THIS LINE
newNode->next = *head;
*head = newNode;
}
在else条件下进行以下更改
newNode->next = current->next;
current->next->prev = newNode;//CHANGE HERE
current->next=newNode;//ADD THIS LINE
newNode->prev=current;//ADD THIS LINE
答案 1 :(得分:0)
除了已经讨论过的prev
指针管理器之外,还有一些其他方面需要您解决问题。首先,明智的做法是使用define
来设置静态name
数组的大小(这将成为验证name
大小的必要条件):
#define MAXN
struct Node
{
char name[MAXN]; /* use a define for static allocation size */
struct Node *next;
struct Node *prev;
};
这会导致GetNewNode
中的两个问题。首先,您需要验证内存分配:
struct Node* newNode = malloc(sizeof (struct Node));
if (!newNode) { /* validate all memory allocations */
fprintf (stderr, "%s() memory allocation failed.\n", __func__);
exit (EXIT_FAILURE);
}
然后,您还必须验证name
的长度,以防止在name > 41 chars
之后写入数组末尾:
size_t namelen = strlen (name);
if ( namelen > MAXN - 1) { /* validate string length */
fprintf (stderr, "%s() name length (%zu) exceeds %d .\n",
__func__, namelen, MAXN);
return NULL;
}
注意:使用define
设置name
的长度,您可以使用定义MAXL
作为长度验证测试。
接下来,在GetNewNode
中验证name
的长度并返回NULL
- 您现在必须处理main()
中的返回并同时为{{提供声明1}}:
head
如果您的目的是创建循环列表,那么您必须测试几个附加条件,并在int main (void)
{
struct Node *head = NULL; /* head must be declared */
if (strncmp(operator, "a", 1) == 0)
{
temp = GetNewNode(name);
if (temp) /* validate return */
addSorted(&head, temp);
}
}
中做出相应的响应。具体来说,您必须(1)在addSorted
时创建列表。
如果您之前的陈述*head = NULL
是正确的,那么您必须(2)在列表自我参照时考虑条件(即只有一个节点存在,指的是自身)。
您还有两个条件需要测试(3)newNode->next = *head; *head = newNode;
是否在当前newNode->name
之前排序,您必须在其中插入(*head)->name
作为新的第一个节点在列表中;最后(4)newNode
在当前newNode->name
之后排序的情况。
即使使用线性头/尾列表,您也需要同时解决(3)&amp; (4)以上。如果您还有其他问题,请与我们联系。
答案 2 :(得分:-2)
使用双向链表,最好先找到需要插入的位置。
// pseudo code
current = head;
while (current)
{
if ( strcmp( name, current -> name) ... ) // your logic for your sort order
{
}
current = current->next;
}
找到要插入的地点后,如果要将项目插入列表中,则需要处理四个案例。您必须处理头部/尾部变化以及向内和向外指向或根据需要处于空值。