C language—basic and application of linked list

Static storage and dynamic storage

Variables are divided into static storage methods and dynamic storage methods from the point of view of the existence time (ie, lifetime) of the variable value

Static: fixed memory address and memory size are determined at compile time, such as: local variables in functions, global variables, etc.

Dynamic: Controlled by the program, it actively applies to the system for a memory segment of the required size during operation, and the memory address allocated each time is not fixed.
Data is stored in the dynamic storage area:
1. Function formal parameters
2. Automatic variables (not added) static statement)
3. On-site protection and
return address when the function is called
Insert picture description here

Storage category

The storage area in the memory includes the following parts:

①Program code area: store the binary code of the function body

②Static area/global area (static): storage area for global variables and static variables

③Heap: the programmer allocates and releases

④Stack area (stack): automatically allocated and released by the compiler, storing function parameter values ​​and local variable values
Insert picture description here

function

malloc() function

Function description: malloc() is one of the most commonly used functions, it allows memory to be allocated from the free memory pool

Function prototype: void *malloc(size_t bytes)
bytes: the number of bytes to be applied for.
Return value: returns the first address of the memory segment when successful, otherwise it returns NULL

Note: The memory space requested by the malloc function is not automatically initialized

Code example:

#include <stdio.h>
#include <windows.h>
void main()
 {
    
    
	int *p,n,i,j,temp;
	printf("\n Enter number of elements in the array: ");
	scanf("%d",&n);
	p=(int*)malloc(n*sizeof(int));
	if(p == NULL){
    
    
		printf("memory error");
		return;
	}
	for(i = 0;i < n;++i) {
    
    
		printf("\n Enter element no. %d: ",i+1);
		scanf("%d",p+i);
	}
	for(i=0;i<n-1;++i)
	{
    
    
	      for(j=i+1;j<n;++j)
	            if(*(p+i)>*(p+j)) {
    
    
	                  temp=*(p+i);
	                  *(p+i)=*(p+j);
	                  *(p+j)=temp;
	            }
	}
	for(i = 0;i<n;++i){
    
    
		printf("%d\n",*(p+i));
	}
	/*free(p)*/
}
结果示例:
Enter number of elements in the array: 3
Enter element no. 1: 2
Enter element no. 2: 1
Enter element no. 3: 3
1
2
3

free() function

Function description: release the memory pointed to by p, and return the released memory to the system and become free memory.

Function prototype: void free(void *p)
p: must be a pointer (first address) allocated by malloc, calloc or realloc.
Return value: none

Note: The dynamically allocated memory must be released through the free() function, otherwise it will cause memory leaks.

Code example:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    
    
	int number,i;
	int *ptr;
	printf("How many ints?  ");
	scanf("%d", &number);
	printf("\n");
	ptr = (int *) malloc (number*sizeof(int));
	if(ptr == NULL) 
	{
    
    	
		printf("Memory allocation failed.\n");
		return 1;
	}
	for(i=0 ; i<number ; i++)
	{
    
    	
		*(ptr+i) = i;
	}
	for(i=number; i>0 ; i--) 
	{
    
    
		printf("%d\n",*(ptr+(i-1)));
	}
	free(ptr);  //这里记得释放malloc开辟的内存
	return 0;
}


测试结果:
How many ints?  5
4
3
2
1
0

Memory initialization function memset()

Function description: Fill a given value in a section of memory (note that it is filled in byte order, not by element)

Function prototype: void *memset( void *buffer, char ch, size_t n);
Parameters: buffer is the starting address of the memory to be set;
ch is the value
to be filled ; n is the number of bytes to be filled.
Return value: returns the first address of the buffer when successful, otherwise it returns NULL

Code example:

#include <stdio.h>
#include <string.h>
int main( ) 
{
    
     
	char buffer[] = "This is a test of the memset function"; 
	printf( "Before: %s\n", buffer ); 
	memset( buffer, 0, 4 );   //这里的0 意思是将buffer清空
	printf( "After: %s\n", buffer ); 
	return 0;
} 
运行结果:
Before: This is a test of the memset function
After:

calloc() function

Function description: calloc() is similar to malloc(), the main difference is that the value stored in the allocated memory space is zero by default

Function prototype: void *calloc(size_t num,size_t bytes )
Parameter: num: the number of memory units to be allocated
bytes: the byte size of each memory unit
Return value: Return the first address of the memory segment when successful, otherwise it returns NULL

Code example:

#include <stdio.h>
#include <stdlib.h> 
void main() 
{
    
    
	float *calloc1;
  	int i;
  	calloc1 = (float *) calloc(3, sizeof(float));
	if(calloc1!=NULL) 
	{
    
    
		for(i = 0 ; i < 3 ; i++)
			printf("\ncalloc1[%d]holds%05.5f",  i,calloc1[i]);
		free(calloc1);
	}
	else
	{
    
    	printf("Not enough memory \n"); 	
	}
	printf("\n");
}

运行结果:
calloc1[0]holds0.00000
calloc1[1]holds0.00000
calloc1[2]holds0.00000

realloc() function

Function description: Reallocate and copy the content of the allocated memory space; when the new space size is 0, it is equivalent to the free function function.

Function prototype: void *realloc(void *ptr,size_t bytes )
Parameter: ptr: the first address of the allocated memory segment
bytes: the size of newly applied memory bytes
Return value: return the first address of the memory segment when successful, otherwise it returns NULL

Code example:

#include<stdio.h>
#include <stdlib.h>
int main()
{
    
    
	int *ptr , i;
	ptr = (int *)calloc(5, sizeof(int));
	if(ptr ==NULL) return 1;
	*ptr = 1;
	*(ptr+1) = 2;
	ptr[2] = 4;
	ptr[3] = 8;
	ptr[4] = 16;
	ptr = (int *)realloc(ptr,7*sizeof(int));
	if(ptr == NULL)	return 1;
	ptr[5] = 32; 
	ptr[6] = 64;
	for(i = 0;i < 7;i++)
	{
    
    
		printf("ptr[%d]:%d\n", i, ptr[i]);
	}
	realloc(ptr,0); /* free(ptr);*/
	return 0;
}
运行结果:
ptr[0]:1
ptr[1]:2
ptr[2]:4
ptr[3]:8
ptr[4]:16
ptr[5]:32
ptr[6]:64

Linear table

In computer science, linear structures are called linear tables

A linear table is in a non-empty set of data elements:
①There is a unique first element;
②There is a unique tail element;
③Every element except the first element has and only one direct predecessor;
④Every element except the tail element The element has one and only one direct follow-up;

According to the storage method, it is divided into sequential storage and chain storage

The basic operations of the linear table are:
initialization, insertion, deletion, traversal (that is, access to each element, such as printing all information), search, and sort

Sequential storage structure

Sequential storage structure: use a group of storage units with consecutive addresses to store all the data elements of the linear table in sequence

Feature 1: Two adjacent elements in the logical relationship are also adjacent in physical location, therefore, any element in the table can be directly accessed

Feature 2 (Disadvantages): ①The storage space is idle and the storage capacity is difficult to expand; ②When inserting and deleting operations, there are a lot of data elements moving

Chain storage structure

Chain storage structure: ① In the chain storage structure, the storage units of data elements are not continuous. In addition to its own information, each element also needs to store the information of its subsequent elements

②The storage image of each element is called a node, the domain that stores the information of the data element is called the data domain, and the domain that stores the storage location of subsequent nodes is called the pointer domain. Each node is composed of a data domain and a pointer domain.

③The sequence of nodes connected by pointers is called a linked list

Single list

If each node contains only a linked list of pointer domains, it is a linear singly linked list

In the storage structure of the singly linked list, there is a pointer head indicating the storage location of the first node in the linked list. At the same time, since the last element is not directly followed, the pointer field of the last node of the singly linked list is NULL, and when When head is NULL, the singly linked list pointed to by head is an empty table, and its length = 0

State diagram of singly linked list

The logic state diagram of the
Insert picture description here
single-linked empty list is as follows: The general logic state diagram of the singly-linked list is as follows:
Insert picture description here

Data structure definition of singly linked list node

For example, there are two ways to define the data structure of student information:

struct student_t
{
    
    
	char acNO[4];  /*学号*/
	char acName[21];  /*姓名*/
	int iAge;  /*年龄*/
	int aScore[5];  /*五门成绩*/
	/*下一学生指针*/
	struct student_t *next;
};
struct studentData{
    
    
	char acNO[4];  /*学号*/
	char acName[21];  /*姓名*/
	int iAge;  /*年龄*/
	int aScore[5];  /*五门成绩*/
};
struct student
{
    
    	 /*数据域*/
	struct studentData info;
	struct student_t *next;/*指针域*/
};

Singly linked list initialization

When initializing a singly linked list, you must first define a pointer and point it to NULL, such as:struct student *head = NULL;

Note: It is not necessary to define the header node during initialization

State diagram of cyclic singly linked list

The general logic state diagram of the cyclic singly linked list is as follows:
Insert picture description here

State diagram of doubly linked list

The general logic state diagram of a doubly linked list is as follows:
Insert picture description here

State diagram of doubly circular linked list

The general logic state diagram of the two-way circular linked list is as follows:
Insert picture description here

to sum up

  • Storage category and dynamic memory allocation
  • Linear table concept
  • Linear table storage structure and basic operations
  • Sequence table and advantages and disadvantages
  • Concept and structure of singly linked list

Guess you like

Origin blog.csdn.net/qq_46485161/article/details/115187242