Implementation of Universal linked list

Source: Internet
Author: User

I. Limitations of the General list.

When we learn the data structure, the operation of the linked list is much the same, although the data structure uses the abstract type description algorithm, but the implementation of the method itself has caused the basic operation of the list and user-defined data type (ELEMTYPE) produced a high degree of coupling, data types and the operation of the list of such "binding", Downgrade the reusability of the code, each time the linked list is applied to the new situation, the source code to ensure that the linked list and the new data type "binding", a large number of repeated operations, it is inevitable that a variety of errors. We want a list with a universal type that will divide the data type from the list operation, which requires the so-called universal So to name it).

The implementation of the linked list comes from Nginx, but the source code is not read by me personally, but by video, thanks to the video author @ Flying brother (although not able to ...).

There are some minor errors in the video and I will correct them in the text.

Two. What is a universal linked list

The so-called universal linked list, the linked list, has no independence from the user-defined data type (node type). We can write it all at once.

Advantages: Versatility, low overhead,

Cons: not responsible for memory management, large use of macros, no type check

Three. Principle of generality.

Before the use of the general list, there have been this annoyance, have thought, how to do "General", until the understanding of this method, can not help simply astounding, this law step by step, hidden mystery, is the crystallization of wisdom, C language masterpiece ... (10000 words omitted here)

To get to the point, the first thing to note is that to complete this list, you only need a header file.

First, this method defines a struct

struct list_s list, *Plist; struct list_s{    Plist prev, next;};

This structure is the clue that runs through the whole play. Using this list requires defining a list type of data in the structure, like this:

struct {    int  A;    List List;} TEST,*ptest;

The structure of the whole list is connected by the list.

The core idea is that we manipulate the list (the red part) and we can logically delete it from the linked list, inserting an element (so that the implementation of this list is unrelated to memory management)

In fact, we are the equivalent of managing a linked list of elements that are just their predecessor after the successor pointer

It looks good, although the list members can "carry" other data to find the right location in the list, but how do we access that data?

We manage the list members, we can know the information is the address of the list, the blue arrow points to the place is the list member is the address, to access the data, we need to know the entire structure of the first address,

The position of the red triangle is the first address of the entire structure. We might as well give an example

In this case, the size of data can be calculated by 2004h-2000h = 4H, and this is also the offset of the list member

Know the offset, know the first address of the list, you know the structure of the first address, and so on! It seems wrong--! You don't know that 2000H, you know, it's still a yarn!

Well, it's a problem, but the bottom way is really great!

 typedef struct  { int   A; List List;} TEST,  *ptest; TEST t  = {1234  ,{null, NULL}}; Plist l  = &t.list;printf (  " Span style= "color: #800000;" >%d\n  , & ((PTEST) 0 ) list); //  get offset!  printf ( %d  , ((PTEST) ((char  *) L-(char  *) & ((PTEST) 0 )->list))->a); 

The key is to get to the offset, and the rest is yielded,

& ((PTEST)0)->list

It's a magical code, isn't it, let's analyze it.

0 Treat 0 as an address

((PTEST) 0 cast to custom struct type

((PTEST) 0)->list

& ((PTEST) 0)->list Get the address of the list member

Since the address starts at 0, the address of the list is its offset in the struct

Having understood the above principles, we have mastered the core methods of the universal linked list.

Four, to achieve

List.h

#ifndef _list_h_#define_list_h_typedefstructlist_s List, *Plist;structlist_s{Plist prev, next;};//Initialize H: Head node pointer#defineListinit (h) Do{(h)->prev =NULL; (h)->next =NULL; } while(0)//h: Head node pointer l: Pointer to a list type member in a custom struct#defineListheadinsert (h,l) Do{(l)->prev =(h); (l)->next = (h)Next; (h)->next =(l); } while(0)//#defineListtailinsert (h,l) Do{Plist T=h;  while(t->next) T = t->Next; (l)->prev =(t); (l)->next = (t)Next; (t)->next =(l); } while(0)//L: Pointer to the list member of the node to read//Struct_type: The type name of the custom struct body//member name of the Struct_field:list type member (variable name)#defineListgetdata (L,struct_type, Struct_field) \((Struct_type*)((Char*) (L)-offsetof (Struct_type,struct_field)))//Pointer to the list of nodes to delete#defineListdelet (L) Do{                                            if((l)->next = =NULL) {(L)->prev->next = (L)Next; (l)->prev =NULL; }Else{(l)->prev->next = (L)Next; (l)->next->prev = (L)prev; }                                            } while(0)#endif

Code for testing:

#include <stdio.h>#include"list.h"typedefstruct{    intA; List List;} TEST,*PTEST;intMainintargcChar**argv) {    /*TEST t = {1234,{null, NULL}};    Plist L = &t.list;    int n = & ((TEST) 0). List;    & ((PTEST) 0)->list;    printf ("%d\n", & ((PTEST) 0)->list);    printf ("%d", ((PTEST) ((char*) L-(char*) & ((PTEST) 0)->list)),->a);    printf ("%d", ((PTEST) ((char*) L-offsetof (test,list))),->a); */TEST test1= {1234, {null, NULL}}; TEST test2= {2234, {null, NULL}}; TEST test3= {3234, {null, NULL}};    List Head; Listinit (&head); Listtailinsert (&head,&test1.list); Listtailinsert (&head,&test2.list); Listtailinsert (&head,&test3.list); List* Temp =Head.next;  for(temp = head.next; Temp! = NULL; temp = temp->next) {PTEST data_addr=Listgetdata (temp,test,list); printf ("%d\n", data_addr->a); }    //printf ("%p,%p \ n", Test2.list.prev, Test2.list.next);Listdelet (&test3.list);  for(temp = head.next; Temp! = NULL; temp = temp->next) {PTEST data_addr=Listgetdata (temp,test,list); printf ("%d\n", data_addr->a); }    return 0;}

Five. Conclusion

And there's no conclusion.

Implementation of Universal linked list

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.