我正在尝试创建一个链表,该链表按存储在指向树的指针中的2种不同数据类型排序。结构是:
typedef struct TreeNode {
int label;
long count;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
typedef struct ListNode {
TreeNode *ptr;
struct ListNode *next;
struct ListNode *prev;
} ListNode;
我正在使用一个名为addNode的函数,它使用以下规则对链接列表节点进行排序:
1. Smallest Count First
2. Smallest Label First
如果不满足这两个条件,如何正确更新标题?
ListNode * prev = NULL;
while( (*head) != NULL && (*head) -> ptr -> count < new -> ptr -> count){
prev = (*head);
(*head) = (*head) -> next;
}
while( (*head) != NULL && (*head) -> ptr -> label < new -> ptr -> label){
prev = (*head);
(*head) = (*head) -> next;
}
new -> next = (*head);
prev -> next = new;
return;
}
GDB错误:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400d6e in addNode (head=0x602010, new=0x602030) at list.c:84
84 prev -> next = new;
示例:每个label
包含一个ASCII字符,每个count
包含前面读过的字符串中该字符的频率。
对于字符串test
,所需的列表如下所示:
(键:|标签:计数|)
| 10:1 | - &GT; | E:1 | - &GT; | S:1 | - &GT; | T:2 | - &GT; NULL
答案 0 :(得分:0)
首先,遍历列表,直到找到一个不小于count
的节点,然后在node->count
等于newNode->count
且node->label
为new->label
的情况下再次从那里遍历小于void addNode(ListNode ** head, ListNode * newNode){
ListNode *node = *head;
if(*head != NULL) {
while(node && node->ptr->count < newNode->ptr->count) {
node = node->next;
}
while(node && node->ptr->count == newNode->ptr->count &&
node->ptr->label < newNode->ptr->label) {
node = node->next;
}
}
if(node != NULL && node->prev != NULL) {
node->prev->next = newNode;
newNode->next = node;
newNode->prev = node->prev;
node->prev = newNode;
}
else if(*head == NULL){
newNode->next = *head;
newNode->prev = NULL;
*head = newNode;
}
else {
node = *head;
while(node->next) node = node->next;
node->next = newNode;
newNode->next = NULL;
newNode->prev = node;
}
}
。将节点插入到达的位置。
以下是addNode函数的实现
SELECT
a.Employee_ID,
ev_last.Evaluation_ID,
ev_last.Scores,
ev_prev.Evaluation_ID,
ev_prev.Scores,
Career.Career_year
FROM Employee a
JOIN (
SELECT
b.Career_Year as `last_eval_year`,
b.Employee_ID,
b.Scores
FROM Evaluation b
ORDER BY b.Career_Year DESC
WHERE b.Employee_ID = a.Employee_ID
LIMIT 1) ev_last
ON ev_last.Employee_ID = a.Employee_ID
JOIN (
SELECT
c.Career_Year as `last_eval_year`,
c.Employee_ID,
c.Scores
FROM Evaluation b
ORDER BY b.Career_Year DESC
WHERE c.Employee_ID = a.Employee_ID
LIMIT 1,1) ev_prev
ON ev_prev.Employee_ID = a.Employee_ID
WHERE ev_prev.Scores > ev_last.Scores
答案 1 :(得分:0)
使用指向节点的指针简化了代码:
void AddNode(ListNode **head, ListNode *new)
{
ListNode **ppCurr = head;
ListNode *prev = NULL;
while( (*ppCurr) != NULL &&
((*ppCurr)->ptr->count < new->ptr->count ||
((*ppCurr)->ptr->count == new->ptr->count &&
(*ppCurr)->ptr->label < new->ptr->label))){
prev = *ppCurr;
ppCurr = &((*ppCurr)->next);
}
new->next = *ppCurr;
new->prev = prev;
if((*ppCurr) != NULL)
(*ppCurr)->prev = new;
*ppCurr = new;
}
这是我使用的测试代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct TreeNode {
int label;
long count;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
typedef struct ListNode {
TreeNode *ptr;
struct ListNode *next;
struct ListNode *prev;
} ListNode;
void AddNode(ListNode **head, ListNode *new)
{
ListNode **ppCurr = head;
ListNode *prev = NULL;
while( (*ppCurr) != NULL &&
((*ppCurr)->ptr->count < new->ptr->count ||
((*ppCurr)->ptr->count == new->ptr->count &&
(*ppCurr)->ptr->label < new->ptr->label))){
prev = *ppCurr;
ppCurr = &((*ppCurr)->next);
}
new->next = *ppCurr;
new->prev = prev;
if((*ppCurr) != NULL)
(*ppCurr)->prev = new;
*ppCurr = new;
}
int main(void)
{
TreeNode at[8] = {{'e',3, NULL, NULL},{'g',1, NULL, NULL},
{'h',3, NULL, NULL},{'b',3, NULL, NULL},
{'c',1, NULL, NULL},{'d',2, NULL, NULL},
{'a',2, NULL, NULL},{'f',1, NULL, NULL}};
ListNode an[8] = {{at+0, NULL, an+1},{at+1, an+0, an+2},
{at+2, an+1, an+3},{at+3, an+2, an+4},
{at+4, an+3, an+5},{at+5, an+4, an+6},
{at+6, an+5, an+7},{at+7, an+6, NULL}};
ListNode *head = NULL;
ListNode *node;
ListNode *prev;
size_t i;
for(i = 0; i < sizeof(an)/sizeof(an[0]) ; i++)
AddNode(&head, an+i);
node = head; /* print list forwards */
while(node){
printf("%c %u\n", node->ptr->label, node->ptr->count);
prev = node;
node = node->next;
}
printf("\n"); /* print list backwards */
while(prev){
printf("%c %u\n", prev->ptr->label, prev->ptr->count);
prev = prev->prev;
}
return(0);
}