我需要将一个节点插入到已排序的链表中。该列表有一个虚拟节点。
.find('.infoCatcher')
这会在列表末尾插入一个节点。我理解添加排序的逻辑。您向前看下一个节点,如果新节点小于下一个节点,则将新节点指向下一个节点,将前一个节点指向新节点。有人可以帮助我在代码中实现这一点。这是我到目前为止所做的,但不起作用。
void add(Node **nodeArray, int setNumber) {
char userString[5];
Node *head = nodeArray[setNumber]; /* head pointer to first element of array (dummy) */
Node *newNode = malloc(sizeof(Node)); /* new node to be added to array */
Node *tmp = head;
printf("Please enter some data: ");
scanf("%s", userString);
strncpy(newNode->data, userString, DATA_SIZE); /* copies string entered by the user to data field of new node */
newNode->next = NULL; /* initializes next field of new node to NULL */
while (tmp->next)
tmp = tmp->next; /* points head to next element in list */
tmp->next = newNode; /* adds element to list */
}
以下是比较功能:
if (!tmp->next)
tmp->next = newNode;
else {
while (tmp->next) {
if (strcmpa((tmp->next)->data, newNode->data) < 0) {
newNode->next = tmp->next;
tmp->next = newNode;
} //else if (strcmpa((tmp->next)->data, newNode->data) > 0) {
//tmp->next = newNode;
//}
tmp = tmp->next;
}
}
答案 0 :(得分:1)
你几乎就在那里,但tmp->next
应该被重定向到newNode
本身,而不是newNode->next
。实际上,这是一个无操作,因为在该命令发生时,newNode->next
是tmp->next
,而你正在重新分配已存在的值。
你想要的是tmp
,指向X
,而是指向next
,而后者只指向X
。所以,正式来说,
X = tmp->next;
tmp->next = newNode;
newNode->next = X;
可以压缩到
newNode->next = tmp->next; /* using the X where originally stored */
tmp->next = newNode; /* rewriting that memory has to wait till now */
更新:上述代码在newNode
之后链接tmp
(因为我认为这就是您所需要的)。但是在排序列表中,您会发现需要在节点之后显示的第一个tmp
,因此您需要先执行此操作。这带来了两个问题:
您需要修改 tmp
之前的项目,因为新节点会去那里,所以您需要再保留一个变量,
有时您需要将新节点放在最初的节点上,该节点没有上一个节点。
在正面,上面还优雅地处理!tmp->next
(最后插入),这样你就不需要另一个分支。
看起来像
Node* head = (whatever);
Node* prev = NULL;
Node* tmp;
for(tmp = head; tmp && strcmpa(tmp->data, newNode->data) < 0; tmp = tmp->next) {
prev = tmp;
}
/* now tmp points to the first larger node or to NULL and prev is its preceding node.
* If there's none (if the head is already larger) then prev = NULL. */
if(prev == NULL) {
newNode->next = head;
head = newNode; /* Don't forget to update this in the array where you took head from! */
} else {
newNode->next = prev->next;
prev->next = newNode;
}
如果head
为NULL
并且创建包含单个条目的链接列表,则此方法也有效。
这专注于插入。关于其余代码(最初发布为评论):
如果您在无限制userString
%s
上超出scanf
缓冲区,程序将失败。设定限额。
如果有限制,则不需要不安全的strncpy
。使用正常的strcpy
来保证它将终止你的字符串。
您的strcmpa
看起来不错。但请确保tolower()
使用'\0'
的输入执行您期望的操作。这会正确地比较字符串:
char toLower(char in) {
if(in >= 'A' && in <= 'Z')
return in + 'a' - 'A';
else
return in;
}