如何创建按多种数据类型排序的链接列表

时间:2017-04-28 19:27:36

标签: c pointers linked-list

我正在尝试创建一个链表,该链表按存储在指向树的指针中的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

2 个答案:

答案 0 :(得分:0)

首先,遍历列表,直到找到一个不小于count的节点,然后在node->count等于newNode->countnode->labelnew->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);
}