2016-03-23 75 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,以保持列表中的项目数的运行计数。这对于在尝试从列表中删除项目时确定成功或失败特别有帮助。我怀疑,如果你在链接列表上的谷歌教程,你会得到比我提供的代码好得多的代码,但是我展示的应该是至少一种合理的方法来处理链接列表。