C language implementation of linked list (including dynamic memory allocation)

Source: Internet
Author: User

C language implementation of linked list (including dynamic memory allocation)

Dynamic Memory Allocation in C language of the linked list

 

I. Why dynamic memory allocation?

When we do not learn the linked list, we always use an array to store a large number of data of the same type or structure. For example, if we want to store the scores of a certain student in a class, we always define a float type (with 0.5 points) array:

Float score [30];

However, when using arrays, there is always a problem: How big should an array be?

In many cases, you cannot determine the size of the array to be used. For example, if you do not know the number of students in the class, you need to define the array large enough. In this way, your program will apply for a fixed size of memory that you think is large enough. Even if you know the number of students in the class, if the number of students increases or decreases for some special reason, you must modify the program again to expand the storage range of the array. This method of allocating a fixed size of memory is called static memory allocation. However, this memory allocation method has serious defects, especially when dealing with some problems: In most cases, a large amount of memory space is wasted. In a few cases, when the defined array is not large enough, it may cause subscript out-of-bounds errors or even serious consequences.

Is there any other way to solve this problem? Yes, that is, dynamic memory allocation.

The so-called dynamic memory allocation refers to the way in which the allocated memory of the storage space is dynamically allocated or recycled during program execution. Unlike static memory allocation methods such as arrays, dynamic memory allocation requires pre-allocation of storage space. Instead, the system allocates the storage space in real time based on program requirements, and the allocated size is the size required by the program. From the above comparison, we can know the characteristics of dynamic memory allocation compared with Jingtai memory allocation:

  1, No need to pre-allocate storage space;

  2, The allocated space can be expanded or reduced according to the needs of the program.

Ii. How to Implement Dynamic Memory Allocation and Management

To dynamically allocate buckets Based on program needs, the following functions must be used:

  1. malloc Function

The following is a prototype of the malloc function:

Void * malloc (unsigned int size)

The function is to allocate a continuous space with a length of size in the dynamic storage area of the memory. The parameter is an unsigned integer, And the return value is a pointer to the starting address of the allocated continuous storage domain. Note that a null pointer is returned when the function fails to allocate storage space (such as insufficient memory. Therefore, when calling this function, check whether the returned value is null and perform corresponding operations.

The following example shows a program for Dynamic Allocation:

# Include "malloc. H "# include" stdlib. H "Main (void) {/* count is a counter. array is an integer pointer. It can also be understood as pointing to the first address of an integer array */INT count; int * array; array = malloc (10 * sizeof (INT); If (array = NULL) {printf ("out of memory! \ N "); exit (1);}/* assign a value to the array */For (COUNT = 0; count <10; count ++) {array [count] = count;}/* print array element */For (COUNT = 0; count <10; count ++) {printf ("% 2D \ n ", array [count]) ;}}

In the above example, 10 integer storage areas are dynamically allocated, and then assigned and printed. In this example, the IF (Array (int *) malloc (10 * sizeof (INT) = NULL) statement can be divided into the following steps:

1) allocate 10 integer continuous buckets and return an integer pointer pointing to its starting address.

2) Assign this integer pointer address to array

3) check whether the returned value is null.

  2. Free Functions

Because the memory area is always limited, you can allocate it without limits, and a program should save resources as much as possible. Therefore, when the allocated memory area is not used, it should be released, for other variables or programs. Now we need to use the free function.

Its function prototype is:

Void free (void * P)

The function is to release the memory zone pointed to by pointer p.

The parameter P must be the pointer returned when you call the malloc function or calloc function (another function that dynamically allocates the storage region. Passing other values to the free function may cause crashes or other catastrophic consequences.

Note: What is important here is the pointer value, rather than the pointer itself used to apply for dynamic memory. Example:

Int * P1, * P2;
P1 = malloc (10 * sizeof (INT ));
P2 = p1;
......
Free (P2)/* or free (P2 )*/

The return value of malloc is assigned to P1, and the value of P1 is assigned to P2. Therefore, P1 and P2 can be used as parameters of the free function.

The malloc function allocates storage areas.

The free function is used to release unused memory areas.

Therefore, these two functions can achieve dynamic allocation and simple management of the memory area.

 

Implementation of a single-chain table in C language of the linked list

I. Create a single-chain table

With the foundation of dynamic memory allocation, it is not difficult to implement a linked list.

A linked list is a data structure that stores linear table elements with any storage unit. The linked list can be further divided into single-chain tables, two-way linked lists, and cyclic linked lists. Let's talk about a single-chain table first. A single-chain table is a one-way arrangement of data points. A single-linked table node has two structural types:

1. Data domain: used to store its own data

2. A Chain Domain is also called a pointer domain. It is used to store the next node address or direct the pointer to it.

Example:

typedef struct node{ char name[20]; struct node *link;}stud; 

 

In this way, the structure of a single-chain table is defined. Char name [20] is an array of character types used to store names. The * link pointer is a pointer used to store its direct successor.

After the structure of the linked list is defined, as long as the appropriate data is stored in the data domain when the program is running, if there are successor nodes, the chain domain is directed to its direct successor. If no, set to null.

The following describes a complete procedure for creating a single-chain table with a table header (if not described, the linked list with a table header.

# Include <stdio. h> # include <stdlib. h> # include <malloc. h>/* header file containing the dynamic memory allocation function */# define N 10/* n count */typedef struct node {char name [20]; struct node * link ;} stud; stud * creat (int n)/* create a single-chain table function. The parameter n is the number of people */{stud * P, * H, * s; /** H Save the pointer of the header node. * P points to the previous node of the current node, and * s points to the current node */int I; /* counter */If (H = (stud *) malloc (sizeof (stud) = NULL) /* allocate space and check */{printf ("memory space cannot be allocated! "); Exit (0);} H-> name [0] = '\ 0';/* Leave The data field of the header node blank */h-> link = NULL; /* Leave the chain field of the header node blank */P = H;/* P points to the header node */for (I = 0; I <n; I ++) {If (S = (stud *) malloc (sizeof (stud) = NULL) /* allocate new storage space and check */{printf ("memory space cannot be allocated! "); Exit (0);} p-> link = s;/* assign the address of S to the chain domain of the node pointed to by P, in this way, P and S are connected to the node */printf ("Enter the personal name of % d", I + 1); scanf ("% s ", s-> name);/* store the name in the data field of the current node S */S-> link = NULL; P = s;} return (h);} Main () {int number;/* variable for storing the number of people */stud * head;/* head is the pointer to the header Node Address of the single-link table */number = N; head = creat (number);/* assign the header address of the newly created single-chain table to head */}

In this way, you can create a single-chain table containing N individual names. For programs that write dynamic memory allocation, check whether the allocation is successful.

 

Circular linked list and two-way linked list implemented in C Language

 

I. Circular linked list

Like a single-chain table, a circular linked list is a chained storage structure. The difference is that, the pointer to the last node of the circular linked list points to the first node of the circular linked list or the header node, thus forming a circular chain.

The operation of the cyclic linked list is basically the same as that of the single-linked list. The differences are as follows:

1. When creating a circular linked list, you must point the pointer of the last node to the header node instead of being null as a single-linked table. In this case, a new node is inserted after the last node.

2. When determining whether the end of the table is reached, it is to determine whether the value of the node chain domain is the header node. When the Chain Domain value is equal to the header pointer, it indicates that it has reached the end of the table. Instead of determining whether the Chain Domain value is null like a single-chain table.

  2. Two-way linked list

A two-way linked list is actually an improvement for a single-chain table.

When we operate a single-chain table, sometimes you need to perform operations on the direct precursor of a node, you must start searching from the header. This is restricted by the structure of a single-chain table node. Because each node in a single linked list has only one chain domain that stores the address of the direct successor node, can it define a chain domain that stores the address of the direct successor node, what about the structure of a dual-Chain Domain node in the chain domain that stores the direct frontend node address? This is a two-way linked list.

In a two-way linked list, in addition to data outside the node, there are two chain domains, one storage directly successor Node Address, generally called the right chain domain; one storage directly precursor node address, it is generally called the left Chain Domain. In C, the node type of the two-way linked list can be defined:

Typedef struct node {int data;/* data domain */struct node * llink, * rlink;/* Chain Domain, * llink is the left Chain Domain pointer, * rlink is the right link domain pointer */} JD;

 

Of course, a two-way linked list can also be built into a two-way circular linked list.

Like a one-way linked list, a two-way linked list also has three basic operations: search, insert, and delete.

Basic operations of two-way linked list:

1. Search

If we want to find a knot point with a specific data field in a two-way circular linked list with a table header, we will also compare the values of the data fields of each node from the header node in sequence, if this is the specific value, the pointer pointing to the node is returned. Otherwise, the query continues until the end of the table.

The following example is a program that uses the bidirectional cyclic linked list search algorithm.

# Include <stdio. h> # include <malloc. h> # define N 10 typedef struct node {char name [20]; struct node * llink, * rlink;} stud; stud * creat (int n) {stud * P, * H, * s; int I; If (H = (stud *) malloc (sizeof (stud) = NULL) {printf ("memory space cannot be allocated! "); Exit (0);} H-> name [0] = '\ 0'; H-> llink = NULL; H-> rlink = NULL; P = h; for (I = 0; I <n; I ++) {If (S = (stud *) malloc (sizeof (stud) = NULL) {printf ("memory cannot be allocated! "); Exit (0);} p-> rlink = s; printf (" enter the name of the % d individual ", I + 1 ); scanf ("% s", S-> name); s-> llink = P; s-> rlink = NULL; P = s;} H-> llink = s; p-> rlink = H; Return (h);} stud * search (stud * H, char * X) {stud * P; char * Y; P = H-> rlink; while (P! = H) {Y = p-> name; If (strcmp (Y, x) = 0) Return (p); else P = p-> rlink ;} printf ("this data is not found! ");} Void print (stud * h) {int N; stud * P; P = H-> rlink; printf (" data information: \ n "); while (P! = H) {printf ("% s", & * (p-> name); P = p-> rlink;} printf ("\ n ");} main () {int number; char studname [20]; stud * head, * searchpoint; number = N; clrscr (); Head = creat (number); print (head ); printf ("enter the name of the person you want to search for:"); scanf ("% s", studname); searchpoint = search (Head, studname ); printf ("the name of the person you want to search for is: % s", * & searchpoint-> name );}

 

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.