Note: The main purpose of this article is to record your learning process and facilitate your communication.
Reprinted please indicate from: http://blog.csdn.net/ab198604/
Recently, I suddenly felt that the basic knowledge of IT technology should be supplemented, because not only can the basic knowledge be further consolidated, it is of great benefit both in improving the technical level and in later employment. Therefore, it is necessary to lay a good foundation and make one step at a time. In short, knowledge must be accumulated in time.
I have never systematically learned computer knowledge, and I have never understood the data structure. Since I learned some knowledge about Linux systems, I found that the use of linked lists in linux kernels is everywhere, do not pay attention to it by yourself. Of course, the use of linked lists is very extensive, such as mailing lists, memory management, and polynomial computing. As long as you have mastered the basic knowledge of linked lists, you can do the opposite, and you can naturally master the linked list Code for similar application scenarios.
There are many types of linked lists: one-way linked list, two-way linked list, one-way cyclic linked list, and two-way cyclic linked list. The complex relationship between them is gradually increasing. Here we mainly introduce the data structure of one-way linked list, because it is the most widely used.
What is a one-way linked list?
Literally, it is "one-way" + "linked list", indicating that this data structure has a direction and only one direction. In addition, the "linked list" indicates that this data structure is a chain storage structure, which is different from the sequential storage structure of linear tables. The adjacent elements of the linked list are not consecutive in the physical memory. Therefore, this structure can fully utilize some system memory fragments to complete some transactions, that is, if the linked list structure is used, it can solve the problem when the continuous memory allocation is insufficient. Since it is a one-way linked list, it also means that it is composed of elements connected by a pointer to each other. Each element contains two parts: a data field and a pointer field called next. By using this structure, the next pointer field points to its next element in a certain direction. The next pointer field of the last element points to null, which indicates the end element of the linked list. The first element of the linked list is called the "Header" element. The linked list is as follows:
As shown in, each element is linked together to form a linked list.
One feature of a one-way linked list is that it can only find its subsequent elements in the direction of the next pointer. If you want to find an element in the linked list, you can only traverse the entire linked list from start to end. If we have accessed an element from start to end, but want to access the first few elements of this element, we cannot access it at this time, because a forward link is not maintained in our element, we must traverse the link from the beginning again.
After a brief review of the basic knowledge points of the one-way linked list, we will start to practice it. The following code consists of three parts:
List. h --> mainly Interface Definition of one-way linked list
List. c --> mainly refers to the specific implementation of Interface Definition
Main. c --> mainly displays some simple applications of linked lists.
1. Single-chain table Interface Definition
/* * file name: list.h * author: zhm * date: 2012-12-06 */#ifndef LIST_H#define LIST_H#include <stdlib.h>/* define a struct for list element */typedef struct ListElmt_{ void *data; struct ListElmt_ *next;}ListElmt;/* define a structure for linked list */typedef struct List_{ int size; void (*match)(const void *key1, const void *key2); void (*destroy)(void *data); ListElmt *head; ListElmt *tail;}List;/* define public interface */void list_init(List *list, void(*destroy)(void *data));void list_destroy(List *list);int list_ins_next(List *list, ListElmt *elemet, 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(list, element) ((element) == (list)->tail ? 1 : 0)#define list_data(element) ((element)->data)#define list_next(element) ((element)->next)#endif
One-way linked list operations include insert, delete nodes, initialize and delete linked lists.
2. Implementation Details of the single-chain table Interface
/* * filename: list.c * author: zhm * date: 2012-12-06 */#include <stdlib.h>#include <string.h>#include "list.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; //keep the data in the element of the list /*remove the element */ while( list_size(list) > 0 ) { if(list_rem_next(list, NULL, (void **)&data) == 0 && list->destroy != NULL) { list->destroy(data); } } memset(list, 0, sizeof(list)); return;}/* list_ins_next */int list_ins_next(List *list, ListElmt *element, const void *data){ /* Allocate storage */ ListElmt *new_element = NULL; new_element = (ListElmt *)malloc(sizeof(ListElmt)); if( new_element == NULL ) return -1; new_element->data = (void *)data; /* Insert the element into the list */ if( element == NULL ) //from head position to insert { if( list_size(list) == 0 ) //be care to tail list->tail = new_element; new_element->next = list->head; list->head = new_element; } else { if( element->next == NULL ) //be care to tail list->tail = new_element; new_element->next = element->next; element->next = new_element; } /*Adjust size */ list->size++; return 0;}/* list_rem_next */int list_rem_next(List *list, ListElmt *element, void **data){ ListElmt *old_element; //if the list is empty if( list_size(list) == 0 ) return -1; /* Remove the element from the list */ if( element == NULL ) //from head to remove { *data = list->head->data; //keep the data. old_element = list->head; list->head = list->head->next; if( list_size(list) == 1 ) //be care to the tail list->tail = NULL; } else { //if the element to be removed is NULL if( element->next == NULL ) return -1; *data = element->next->data; old_element = element->next; element->next = element->next->next; if( element->next == NULL ) //be care to the tail list->tail = element; } //free the memory free(old_element); list->size--; return 0;}
3. the test case code is as follows:
/* * filename: main.c * author:zhm * date: 2012-12-06 */#include <string.h>#include <stdlib.h>#include <stdio.h>#include "list.h"/* destroy */void destroy(void *data){ printf("in destroy\n"); free(data); return;}/* main */int main(int argc, char **argv){ ListElmt *elem_ptr = NULL; int i; int ret; int *data = NULL; /* Create a linked list */ List list_exp; /* init the list */ printf("\ninit the list:\n"); list_init(&list_exp, destroy); /* insert the element */ printf("\ncreate a list:\n"); for(i = 0; i < 10; i++ ) { data = (int *)malloc(sizeof(int)); if( data == NULL ) return -1; *data = i; list_ins_next(&list_exp, NULL, (void *)data); } /* now the list has 10 element, then traverse and print every element */ elem_ptr = list_exp.head; for( i = 0; i < 10; i++ ) { printf("%d ", *(int *)list_data(elem_ptr) ); elem_ptr = list_next(elem_ptr); } printf("\n"); /* Remove the element, its value of the data equal 4,then traverse and print again */ elem_ptr = list_exp.head; for( i = 0; i < list_size(&list_exp); i++ ) { if( *(int *)list_data(elem_ptr) == 5 ) { ret = list_rem_next(&list_exp, elem_ptr, (void **)&data); if( ret == 0 ) { destroy(data); } } elem_ptr = list_next(elem_ptr); } printf("after remove the element: value = 4\n"); //traverse and print again elem_ptr = list_exp.head; for( i = 0; i <list_size(&list_exp); i++ ) { printf("%d ", *(int *)list_data(elem_ptr) ); elem_ptr = list_next(elem_ptr); } printf("\n\n"); printf("here begin to destroy the list :\n"); //destroy the linked list list_destroy(&list_exp); return 0;}
4. display the execution result, for example: