2017-05-07 57 views
0

我必須創建一個按人數順序排列的人員列表(對於我的程序爲「no」)。我試圖通過修改addNode函數來實現,但我沒有得到任何結果(人們不按他們的編號排列)。這是我的代碼:按遞減順序在鏈表中插入節點 - C

頁眉代碼:

#ifndef __EX__ 
#define __EX__ 

typedef struct Person{ 
    char name[10]; 
    float no; 
    struct Person *pNext; 
} NODE, *pNODE, **ppNODE; 

void addNode(ppNODE, pNODE); 

void travers(pNODE, unsigned int*); 


#endif 

功能的文件夾:

#include <stdio.h> 
#include <stdlib.h> 
#include <assert.h> 
#include <math.h> 
#include <string.h> 

#include "EX.h" 

void addNode (ppNODE ppPrim, pNODE p){ 
    pNODE q = (pNODE)malloc(sizeof(NODE)); 
    assert(q!=NULL); 

    printf("Add name: \n"); 
    scanf("%s", &q->name); 


    printf("\nAdd no: "); 
    scanf("%f", &q->no); 


    if (p == NULL || q->no < p->no) { 
     q->pNext = *ppPrim; 
     *ppPrim = q; 
    } else { 
      q->pNext = p->pNext; 
      p->pNext = q; 

    } 
    return; 
} 


void travers(pNODE pPrim, unsigned int *pLen){ 
    *pLen = 0; 
    pNODE tmp = pPrim; 


    while (tmp != NULL){ 
     puts (tmp->name); 
     fprintf(stdout, " no %.2f\n", tmp->no); 
     tmp = tmp->pNext; 
     (*pLen)++; 
    } 

    return; 
} 

主要文件夾:

#include <stdio.h> 
#include <stdlib.h> 
#include <assert.h> 
#include <math.h> 
#include <string.h> 

#include "EX.h" 

int main(){ 
    unsigned int len; 
    pNODE prim = NULL; 
    int i; 

    for (i=0; i<=1; i++){ 
     addNode(&prim, prim); 
     addNode(&prim, prim->pNext); 
    } 

    travers(prim, &len); 

    return 0; 
} 
+0

你已經在調試器中一步一步地執行了代碼嗎? 'main()'中的for循環看起來有點奇怪 - 我假設你在搜索錯誤時執行了這個操作... – Scheff

+0

所有你需要的就是使用Insertion Sort來將你列爲優先級隊列。檢查[this](http://stackoverflow.com/questions/25437682/use-a-linked-list-to-implement-a-priority-queue) –

回答

2

當你插入一個新節點添加到列表中,你必須遍歷列表直到找到一個合適的地方插入它。你的代碼需要第二個參數,這並不是真正需要的,會引起混淆,只會看到這個參數。

在列表的末尾由其head定義插入代碼q的代碼是:

Node *prev = NULL; 
Node *p = *head; 

while (p) { 
    prev = p; 
    p = p->pNext; 
} 

q->pNext = p; 
if (prev == NULL) { 
    *head = q;   
} else { 
    prev->pNext = q; 
} 

你可以擺脫保持在插入之間的軌道前一節點和區別頭和通過遍歷該列表的指針節點指針後,在插入:

Node **p = &head; 

while (*p && (*p)->no < q->no) { 
    p = &(*p)->pNext; 
} 

q->pNext = *p; 
*p = q; 

在這種簡潔的代碼,p保持頭中的第一地址和的地址前一個節點的指針。兩者都可以通過*p更新。

現在,您只能在與每個節點關聯的編號小於要插入的節點的編號的情況下使用此代碼來遍歷。這裏有一個完整的程序:

#include <stdio.h> 
#include <stdlib.h> 
#include <assert.h> 

typedef struct Node Node; 
void addNode(Node **p, const char *name, float no); 
void travers(Node *pPrim, unsigned int *pLen); 

struct Node { 
    char name[10]; 
    float no; 
    Node *pNext; 
}; 

void addNode(Node **p, const char *name, float no) 
{ 
    Node *q = malloc(sizeof(*q)); 
    assert(q != NULL); 

    snprintf(q->name, sizeof(q->name), "%s", name); 
    q->no = no; 

    while (*p && (*p)->no < q->no) { 
     p = &(*p)->pNext; 
    } 

    q->pNext = *p; 
    *p = q; 
} 

void traverse(const Node *pPrim, unsigned int *pLen) 
{ 
    *pLen = 0; 

    while (pPrim != NULL) { 
     fprintf(stdout, "%-12s%.2f\n", pPrim->name, pPrim->no); 
     pPrim = pPrim->pNext; 
     (*pLen)++; 
    } 
} 

int main() 
{ 
    unsigned int len; 
    Node *prim = NULL; 

    addNode(&prim, "Alice", 0.23); 
    addNode(&prim, "Bob",  0.08); 
    addNode(&prim, "Charlie", 0.64); 
    addNode(&prim, "Dora", 0.82); 

    traverse(prim, &len); 
    printf("\n%u entries.\n", len); 

    return 0; 
} 

觀光節點:

  • 我用Node *Node **代替typedeffed pNODEppNODE的。在我看來,使用C指針語法更清晰。
  • 您應該單獨從添加節點中獲取用戶輸入。
  • 在你的代碼中,當掃描一個字符串時,不應該傳遞char數組的地址,而只能是char數組。 (它正常工作,但它不正確,編譯器應該會提醒你)