在列表的开头

时间:2016-03-23 03:24:41

标签: c list pointers insert

我需要在列表的开头插入一个节点,我是怎么做到的?

使用此代码:

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
Nombre:第三个                                                                                                                                                                                                     Apellido:节点

Codigo:2
Nombre:secc
                                                                                                                                                                                                                                                       Apellido:节点

Codigo:1
Nombre:第一个                                                                                                                                                                                                                               Apellido:节点

所以,如果我在beginnig插入一些东西,我应该看到

Codigo:3
Nombre:第三个                                                                                                                                                                                                     Apellido:节点

Codigo:2
Nombre:secc
                                                                                                                                                                                                                                                       Apellido:节点

Codigo:1
Nombre:第一个                                                                                                                                                                                                                               Apellido:节点

Codigo:4
Nombre:第四个                                                                                                                                                                                                                               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

1 个答案:

答案 0 :(得分: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,以保持列表中项目数的运行计数。这对于在尝试从列表中删除项目时确定成功或失败特别有用。我怀疑如果你在链接列表上搜索一个教程,你会获得比我提供的更好的代码,但我展示的应该是至少一种处理链表的合理方法。