2016-03-23 72 views
1

我需要在列表的開頭插入一個節點,我該怎麼做?在列表的開頭插入節點

與此代碼:

while(tmp!=NULL){ 
    printf("__________"); 
    printf("\nCodigo: %d\n",tmp->code); 
    printf("Nombre: %s\n",tmp->name); 
    printf("Apellido: %s\n",tmp->last); 
    tmp = tmp->next; 

}; 

我打印的清單,這是我所看到的:


Codigo:3
農佈雷:第三
Apellido:節點


Codigo:2
農佈雷:SECC
Apellido:節點


Codigo:1
農佈雷:第一
Apellido:節點

所以,如果我插入在beginnig東西我應該看到


Codigo:3
農佈雷:第三
Apellido:節點


Codigo:2
農佈雷:SECC
Apellido:節點


Codigo:1
農佈雷:第一
Apellido:節點


Codigo:4
農佈雷:第四
Apellido:節點

如何做呢?我試着用這樣的:

tmp_aux = lista;// creating an aux list 
    while(tmp_aux->next!=NULL){ 
     tmp_aux->next = tmp_aux; 
    }; // i used this becouse the last printed (up) is the first node 
    new_aux = (struct nodo*) malloc(1*sizeof(struct nodo)); 
    printf("ingrese el codigo: "); 
    scanf("%d",&(*new_aux).code); 
    printf("ingrese el nombre: "); 
    scanf("%s",&(*new_aux).name); 
    printf("ingrese el apellido: "); 
    scanf("%s",&(*new_aux).last); 



    new_aux->next = tmp_aux;// then i put the aux on the next of my new node 
    lista = new_aux;// and make my list the new one 
+0

假設'tmp_aux'在循環開始時非空,它永遠不會終止; 'tmp_aux-> next = tmp_aux'不會遍歷列表,只是不斷重新賦值。也許你想做'tmp_aux = tmp_aux-> next'? –

+0

我試過,但仍然在列表底部打印第一個節點;我認爲我掃描的最後一個節點應該在底部......是嗎? –

+1

你的例子顯示在列表的末尾插入的不是開頭。如果是在開始時,新節點會首先打印不最後的權利?那麼你真的想要哪個 - 列表的開始還是結束? – kaylum

回答

1

我個人認爲,第一個節點應該先印刷(參照註釋),但是這只是語義我想。

我用鏈表的所有時間,我用headtail指針。 head指針指向列表中的第一個項目,tail指向列表中的最後一個項目。每次添加和刪除列表中的項目時,都需要一些額外的簿記來保持這些更新,但我認爲這是非常值得的。任何要求您遍歷列表的操作(搜索特定節點,打印所有項目等)的操作更簡單,因爲您從head開始並轉到tail。像下面這樣的東西應該讓你開始,,這並不意味着是一個包容各方的程序:

static struct nodo *head = NULL, *tail = NULL; 

struct nodo* insert_at_head(struct nodo* new_aux) 
{ 
    if (head == NULL && tail == NULL) 
    { 
    // our list is empty; any item inserted is both the beginning and end 
    head = new_aux; 
    tail = new_aux; 
    new_aux->next = NULL; // only 1 item in the list, there is no next element 
    } 
    else 
    { 
    // if maintained properly, this should be the only other possibility 
    new_aux->next = head; // new_aux is the new head of the list, so the previous head is now the 2nd item 
    head = new_aux; // make new_aux the new head of the list 
    } 

    // in fact, since head = new_aux happens in both branches, that should just go here 

    return head; // this could be a void function, but returning head and checking that it equals new_aux shows that new_aux is now the head of the list 
} 

struct nodo* remove_head() 
{ 
    if (head != NULL) // our list is not empty, so it does in fact have a head 
    { 
    struct nodo* temp = head 
    head = head->next; // even if there is one item in the list, head->next should be NULL, so now head is NULL 
    free(temp); 
    } 
    else 
    { 
    // this means our list is empty, optionally print an error message or warning "Trying to delete head from empty list!" 
    return NULL; 
    } 

    return head; 
} 

// now iterating over all the nodes is easy, you just have to go from head to tail. 
void print_list() 
{ 
    struct nodo* cur_aux; 
    for (cur_aux=head; cur_aux!=NULL; cur_aux=cur_aux->next) 
    { 
    // print whatever you want here 
    } 
} 

// you can have several other functions, for manipulating the list. Their prototypes *might* look like the following: 
// do not forget to maintain head and tail pointers for all of these! 
struct nodo* insert_at_tail(stuct nodo* new_aux); // similar to insert_at_head(), except now you want to make the current last node the 2nd to last node 
struct nodo* locate_aux(const struct nodo* aux); // iterate head to tail and return the node that matches all fields of struct nodo, return NULL if not found 
void delete_aux(struct nodo* aux); // iterate through the list and delete aux if found 
void clean_up_list(); // iterate from head to tail and delete all items 
struct nodo* insert_aux_after(struct nodo* insert_after, struct nodo* new_aux); // this will insert new_aux after insert_after 

int main(int argc, char* argv[]) 
{ 
    // something like this 
    struct nodo* new_aux = malloc(sizeof(struct nodo)); 
    struct nodo* new_aux2 = malloc(sizeof(struct nodo)); 
    struct nodo* new_aux3 = malloc(sizeof(struct nodo)); 

    // fill in the fields for each new_aux 
    if (insert_at_head(new_aux) != new_aux) 
    { 
    // some error happened on insertion,, handle it 
    } 
    insert_at_head(new_aux2); 
    insert_at_head(new_aux3); 

    print_list(); 
    // the output should print new_aux3, then new_aux2, and finally new_aux 

    clean_up_list(); 
    return 0; 
} 

您可以調整headtail是第一個或最後的名單,但一般慣例標籤head爲列表中的第一項。我可以爲其他原型填充一些代碼。實際上,您可以在沒有tail指針的情況下實現上述所有內容,只需在列表中開始所有迭代,即head,然後轉至->next == NULL。您也可以考慮維護一個static size_t num_aux,以保持列表中的項目數的運行計數。這對於在嘗試從列表中刪除項目時確定成功或失敗特別有幫助。我懷疑,如果你在鏈接列表上的谷歌教程,你會得到比我提供的代碼好得多的代碼,但是我展示的應該是至少一種合理的方法來處理鏈接列表。