Data Structure linked list _ single-chain table implementation and analysis, single-chain Data Structure

Source: Internet
Author: User

Data Structure linked list _ single-chain table implementation and analysis, single-chain Data Structure
Single-chain table implementation and analysis

The ListElmt struct represents a single element in the linked list (see example 1). This struct has two members: the data member and the pointer member.

The struct List indicates the data structure of the linked List (see example 1 ). This structure consists of five members: size indicates the number of elements in the linked list. match is not used by the linked list itself, but is used by a new type derived from the Linked List data structure; destroy is the Destructor that is encapsulated and passed to list_init; head is the pointer to the header node element in the linked list; tail is the pointer to the End Node element in the linked list.

Example 1: the header file of the abstract data type in the linked list

    /*list.h*/      #ifndef LIST_H      #define LIST_H            #include <stdio.h>      /*Define a structure for linked list elements.*/      typedef struct ListElmt_      {          void *data;          struct ListElmt_ *next;      } ListElmt;            /*Define a structure for linked lists.*/      typedef struct List_      {          int size;          int (*match)(const void *key1,const void *key2);          void (*destroy)(void *data);          ListElmt *head;          ListElmt *tail;      } List;            /*Public Interface*/      void list_init(List *list,void(*destroy)(void *data));      void list_destroy(List *list);      int list_ins_next(List *list,ListElmt *element,const void *data);      int list_rem_next(List *list,listElmt *element,void **data);      #define list_size(list)((list)->size)            #define list_head(list)((list)->head)      #define list_tail(list)((list)->tail)      #define list_is_head(list,element)(element==(list)->head ? 1 : 0)      #define list_is_tail(element)((element)->next==NULL ? 1 : 0)      #define list_data(element)((element)->data)      #define list_next(element)((element)->next)            #endif // LIST_H  

 

List_init

List_init is used to initialize a linked list for other operations (see example 2 ).

Initializing a linked list is a simple operation. As long as the size Member of the linked list is set to 0, the function pointer member destroy is set to the defined destructor, set all head and tail pointers to NULL.

The complexity of list_init is O (1), because all steps during initialization can be completed within a constant period of time.

Example 2: Implementation of abstract data types in linked lists

    /*list.c*/      #include <stdio.h>      #include <string.h>            #include "lish.h"            /*list_init*/      void list_init(List *list,void(*destroy)(void *data))      {          list->size = 0;          list->destroy = destroy;          list->head = NULL;          list->tail = NULL;                return;      }            /*list_destroy*/      void list_destroy(List *list)      {          void *data;          /*Remove each element*/          while(list_size(list)>0)          {              if(list_rem_next(list,NULL,(void **)&data)==0 && list->destroy!=NULL)              {                  /*Call a user-defined function to free dynamically allocated data.*/                  list->destroy(data);              }          }          memset(list,0,sizeof(list));          return;      }            /*list_ins_next*/      int list_ins_next(List *list,ListElmt *element,const void *data)      {          ListElmt *new_element;                    /*Allocate storage for the element*/          if((new_element=(ListElmt *)malloc(sizeof(ListElmt)))==NULL)              return -1;          /*insert the element into the list*/          new_element->data=(void *)data;          if(element == NULL)          {              /*Handle insertion at the head of the list. */              if(list_size(list)==0)                  list_tail = new_element;                                new_element->next = list->head;              list->head = new_element          }          else           {              /*Handle insertion somewhere other than at the head*/              if(element->next==NULL)                  list->tail = new_element;                            new_element->next = element->next;              element->next = new_element;          }          /*Adjust the size of the list of account for the inserted element. */          list->size++;                    return 0;      }            /*list_rem_next*/      int list_rem_next(List *list,ListElmt *element,void **data)      {          ListElmt *old_element;                    /*Do not allow removal from an empty list. */          if(list_size(list) == 0)              return -1;                    /*Remove the element from the list. */          if(element == NULL)          {              /*Handle removal from the head of the list. */              *data = list->head->data;              old_element = list->head;              list->head = list->head->next;                            if(list_size(list) == 1)                  list->tail = NULL;          }          else           {              /*Handle removal from somewhere other than the head. */              if(element->next == NULL)                  return -1;                            *data = element->next->data;              old_element = element->next;              element->next = element->next->next;                            if(element->next == NULL)                  list->tail = element;          }          /*Free the storage allocated by the abstract datatype.*/          free(old_element);          /*Adjust the size of the list account for the removed element. */          list->size--;          return 0;      }  

 

List_destroy

List_destroy is used to destroy the linked list (see example 2). It means to remove all elements in the linked list.

If the destroy parameter is not NULL when list_init is called, list_destroy is called once when each element is removed.

The runtime complexity of list_destroy is O (n), and n represents the number of elements in the linked list. This is because the complexity of list_rem_next is O, and list_rem_next is called once when each element is removed.

List_ins_next

List_ins_next insert an element after the element specified by the element parameter (see example 2 ). This call points the data of the new element to the data transmitted by the user. The process for inserting new elements into a linked list is simple, but you need to be careful. There are two situations to consider: insert the head of the linked list and insert other locations.

In general, to insert an element into the linked list, you need to point the next pointer of the new element to the element after it, then, point the node next pointer before the new element position to the newly inserted element (see figure 3 ). However, when inserted from the head of the linked list, there are no other nodes before the new elements. In this case, point the next pointer of the new element to the head of the linked list, and reset the header node pointer to point it to the new element. Looking back at the previous interface design, when the input element is null, the new elements of the table will be inserted into the head of the linked list. In addition, whenever the inserted element is at the end of the linked list, you must reset the tail Member of the linked list data structure to point it to a new node. Finally, the size Member of the number of nodes in the statistics linked list is updated.


Li St_rem_next

List_rem_next removes the node after the element specified by the element from the linked list (see example 2 ). Remove the node after the element instead of the element itself. This call also takes two factors into account: removing the header node and removing the node from other locations.

The removal operation is simple, but you also need to pay attention to some details (see figure 4 ). In general, to remove an element from the linked list, you need to point the next node pointer of the element before the removed target node to the next element of the target node. However, when the removed target node is a header pointer, there are no other elements in the target node. Therefore, in this case, you only need to point the head Member of the chain table to the next element of the target node. Like the insert operation, when the input element is NULL, it indicates that the head node of the linked list needs to be removed. In addition, whenever the removed target node is the end point of the linked list, you must update the tail member in the Linked List Data Structure to point it to the new end node, or when the removal operation makes the entire linked list empty, you need to set tail to NULL. Finally, update the size Member of the linked list to reduce it by 1. When this call returns, data points to the data domain of the removed node.


The complexity of list_rem_next is O (1), because all the removal steps are completed at a constant time.

List_size, list_head, list_tail, list_is_tail, list_data, and list_next

These macros implement some simple operations in some linked lists (see example 1 ). In general, they provide the ability to quickly access and detect members in the List and ListElmt struct.

The complexity of these operations is O (1), because access and detection of struct members can be completed at a constant time.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.