Data structure - sequence table (text + code + detailed explanation with pictures)

insert image description here

In C language, sequential tables can be implemented using arrays. A sequence table is a linear table in which the elements are physically contiguously stored, and any element can be accessed through a subscript.
The basic operations of sequence table include insertion, deletion, search, traversal and initialization, etc.
insert image description here

This code defines a sequence table structure, which includes three member variables:
SLDataType* array: Points to the dynamically opened array, that is, the storage space of the sequence table.
size_t size: the number of valid data, that is, the number of elements actually stored in the current sequence table.
size_t capacity: the size of the space capacity, that is, the size of the storage space of the current sequence table.

typedef int SLDataType;
//定义了一个顺序表的结构体
typedef struct SeqList
{
    
    
	SLDataType* array;//指向动态开辟的数组
	size_t size;	//有效数据个数
	size_t capicity;	//空间容量的大小
}SeqList;

This code implements the initialization operation of the sequence table. This function accepts a pointer psl pointing to the sequence table structure, and dynamically allocates an array with a size of 4 in memory to store elements.

Specifically, this function completes the following operations:
use the assert() macro to judge that the pointer psl is not empty, and if it is empty, the program will abort.
Use the malloc() function to dynamically allocate an array of size 4 to store elements, and assign it to psl->array, which is the storage space of the sequence table.
Determine whether the allocation of the array is successful, if the allocation fails, output an error message and return.
Initialize psl->size and psl->capacity to 0 and 4, which respectively represent the number of elements actually stored in the current sequence table and the capacity of the storage space.

//顺序表初始化
void SeqListInit(SeqList* psl)
{
    
    
	assert(psl);
	psl->array= (SLDataType*)malloc(sizeof(SLDataType) * 4);
	if (psl->array == NULL)
	{
    
    
		perror("malloc fail");
		return;
	}
	psl->size = 0;
	psl->capicity = 4;
}

insert image description here

This code realizes the dynamic expansion operation of the sequence table. This function accepts a pointer psl pointing to the sequence table structure, and expands the capacity when the number of elements in the sequence table is equal to the capacity.
Specifically, the function does the following:

Use the assert() macro to judge that the pointer psl is not empty, and if it is empty, the program will abort.
Determine whether the number of elements psl->size actually stored in the current sequence table is equal to the capacity psl->capacity of the storage space. If they are equal, it means that the sequence table is full and needs to be expanded.
Use the realloc() function to expand the storage space of the sequence table, double the original space size psl-capacity, that is, psl->capacity * 2, and assign the expanded space size to psl->capacity.
Judging whether the expansion is successful, if the expansion fails, output an error message and return.
Assign the expanded new space address to psl->array, which is the storage space of the sequence table.

// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl)
{
    
    
	assert(psl);
	if (psl->size == psl->capicity)
	{
    
    
		SLDataType* tmp = (SLDataType*)realloc(psl->array, sizeof(SLDataType) * psl->capicity * 2);
		if (tmp == NULL)
		{
    
    
			perror("realloc fail");
			return;
		}
		psl->array = tmp;
		psl->capicity *= 2;
	}
}

insert image description here
insert image description here

This code implements the sequence table tail insertion operation. This function accepts a pointer psl pointing to the sequence table structure and the element value x to be inserted, and inserts the element at the end of the sequence table.

Specifically, this function completes the following operations:
use the assert() macro to judge that the pointer psl is not empty, and if it is empty, the program will abort.
Call CheckCapacity(), the function checks whether the storage space of the sequence table is full, and if it is full, it will perform dynamic capacity increase operation.
Assign the element value x to be inserted to the next available position in the storage space of the sequence table, ie
psl->array[psl->size]. Add 1 to the number of elements actually stored in the sequence table psl->size, indicating that another element is inserted into the sequence table.

// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x)
{
    
    
	assert(psl);
	CheckCapacity(psl);
	psl->array[psl->size] = x;
	psl->size++;
}

insert image description here

This code implements the tail delete operation of the sequence table. This function accepts a pointer psl pointing to the sequence table structure, and deletes the last element in the sequence table.

Specifically, the function does the following:

Use the assert() macro to judge that the pointer psl is not empty, and if it is empty, the program will abort.
Use the assert() macro to judge whether the number of elements psl->size actually stored in the sequence table is greater than 0. If it is not greater than 0, it means that the sequence table is empty and cannot be deleted.
Clear the value of the last element position psl->array[psl->size-1] in the sequence table storage space, that is, set it to 0.
Subtract 1 from the number of elements actually stored in the sequence table psl->size, indicating that another element has been deleted from the sequence table.

// 顺序表尾删
void SeqListPopBack(SeqList* psl)
{
    
    
	assert(psl);
	assert(psl->size > 0);
	psl->array[psl->size-1] = 0;
	psl->size--;
}

insert image description here
insert image description here

This code implements the header insertion operation of the sequence table. This function accepts a pointer psl pointing to the sequence table structure and the element value x to be inserted, and inserts the element into the head of the sequence table.

Specifically, the function does the following:

Use the assert() macro to judge that the pointer psl is not empty, and if it is empty, the program will abort.
Call the CheckCapacity() function to check whether the storage space of the sequence table is full, and if it is full, perform a dynamic capacity increase operation.
Starting from the last element position in the sequence table storage space, each element is moved backward one by one until all elements in the sequence table storage space are moved backward by one position.
Assign the element value x to be inserted to the first position in the sequence table storage space, ie psl->array[0]. Add 1 to the number of elements psl->size actually stored in the sequence table, indicating that another element is inserted in the sequence table.

// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x)
{
    
    
	assert(psl);
	CheckCapacity(psl);
	int end = psl->size - 1;
	while (end >= 0)
	{
    
    
		psl->array[end + 1] = psl->array[end];
		--end;
	}
	psl->array[0] = x;
	psl->size++;
}

insert image description here
insert image description here
insert image description here

This code implements the sequence table header deletion operation. This function accepts a pointer psl pointing to the sequence table structure, and deletes the first element in the sequence table.

Specifically, the function does the following:

Use the assert() macro to judge that the pointer psl is not empty, and if it is empty, the program will abort.
Use the assert() macro to judge whether the number of elements psl->size actually stored in the sequence table is greater than 0. If it is not greater than 0, it means that the sequence table is empty and cannot be deleted.
Starting from the second element position in the sequence table storage space, each element is moved forward one by one until all the elements in the sequence table storage space are moved forward by one position.
Subtract 1 from the number of elements actually stored in the sequence table psl->size, indicating that another element has been deleted from the sequence table.

// 顺序表头删
void SeqListPopFront(SeqList* psl)
{
    
    
	assert(psl);
	assert(psl->size > 0);
	int begin = 1;
	while (begin < psl->size)
	{
    
    
		psl->array[begin - 1] = psl->array[begin];
		++begin;
	}
	psl->size--;
}

insert image description here
insert image description here

This code implements the lookup operation of the sequence table. This function accepts a pointer psl pointing to the sequence table structure and the value x of the element to be found, and searches for the element in the sequence table.

Specifically, the function does the following:

Use the assert() macro to judge that the pointer psl is not empty, and if it is empty, the program will abort.
Search elements one by one in the storage space of the sequence table, and if an element whose element value is equal to x is found, return the subscript of the element in the sequence table.
If no element with element value equal to x is found in the ordered list, -1 is returned, indicating that the search failed.

// 顺序表查找
int SeqListFind(SeqList* psl, SLDataType x)
{
    
    
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
    
    
		if (psl->array[i] == x)
		{
    
    
			return i;
		}
	}
	return -1;
}

This code realizes the operation of inserting elements in the specified position of the sequence table. This function accepts a pointer psl pointing to the sequence table structure, the position pos to be inserted, and the element value x to be inserted.

Specifically, the function does the following:

Use the assert() macro to judge that the pointer psl is not empty, and if it is empty, the program will abort.
Use the assert() macro to judge whether the position pos to be inserted is legal, that is, within the range of the sequence table.
Call the CheckCapacity() function to check whether the storage space of the sequence table is full, and if it is full, perform a dynamic capacity increase operation.
Starting from the last element position in the storage space of the sequence table, move each element backward one by one until the element position of the position pos to be inserted in the storage space of the sequence table.
Assign the element value x to be inserted to the element position of pos in the storage space of the sequence table, that is, psl->array[pos].
Add 1 to the number of elements actually stored in the sequence table psl->size, indicating that another element is inserted in the sequence table.

// 顺序表在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)
{
    
    
	assert(psl);
	assert(pos >= 0 && pos <= psl->size);
	CheckCapacity(psl);
	int end = psl->size - 1;
	while (end >= pos)
	{
    
    
		psl->array[end + 1] = psl->array[end];
		--end;
	}
	psl->array[pos] = x;
	psl->size++;
}

insert image description here

insert image description here

This code implements the operation of deleting the element at the specified position in the sequence table. This function accepts a pointer psl pointing to the sequence table structure and the position pos to be deleted.

Specifically, the function does the following:

Use the assert() macro to judge that the pointer psl is not empty, and if it is empty, the program will abort.
Use the assert() macro to judge whether the position pos to be deleted is legal, that is, within the range of the sequence table.
Starting from the position of the next element at the position pos to be deleted in the storage space of the sequence table, move each element forward one by one until all the elements in the storage space of the sequence table are moved forward by one position.
Subtract 1 from the number of elements actually stored in the sequence table psl->size, indicating that another element has been deleted from the sequence table.

// 顺序表删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos)
{
    
    
assert(psl);
assert(pos >= 0 && pos <= psl->size);
int begin = pos + 1;
while (begin < psl->size)
{
    
    
psl->array[begin - 1] = psl->array[begin];
++begin;
}
psl->size--;
}

insert image description here

insert image description here

insert image description here

This code implements the destruction operation of the sequence table. This function accepts a pointer psl pointing to the sequence table structure, and releases the memory space occupied by the sequence table.

Specifically, the function does the following:

Use the assert() macro to judge that the pointer psl is not empty, and if it is empty, the program will abort. Call the free() function to release the memory space occupied by the sequence table storage space.
Set the sequence table storage space pointer psl->array to NULL, indicating that the storage space has been released.
Set the capacity psl->capacity of the sequence table and the number of elements psl->size actually stored to 0, indicating that the sequence table has been destroyed.
It should be noted that after using the sequence table, this function needs to be called in time to release the memory space occupied by the sequence table to avoid memory leaks.

// 顺序表销毁
void SeqListDestory(SeqList* psl)
{
    
    
	assert(psl);
	free(psl->array);
	psl->array == NULL;
	psl->capicity = 0;
	psl->size = 0;
}

This code implements the printing operation of the sequential table. This function accepts a pointer psl pointing to the sequence table structure, and prints out all the elements stored in the sequence table.

Specifically, the function does the following:

Use the assert() macro to judge that the pointer psl is not empty, and if it is empty, the program will abort. Use a for loop to traverse the elements actually stored in the sequence table one by one, and print out each element.
After printing all elements, use the printf() function to output a newline so that the next line of output can be displayed.

// 顺序表打印
void SeqListPrint(SeqList* psl)
{
    
    
assert(psl);
for (int i = 0; i < psl->size; i++)
{
    
    
printf("%d ", psl->array[i]);
}
printf("\n");

}

complete program

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLDataType;
//定义了一个顺序表的结构体
typedef struct SeqList
{
    
    
	SLDataType* array;//指向动态开辟的数组
	size_t size;	//有效数据个数
	size_t capicity;	//空间容量的大小
}SeqList;

//顺序表初始化
void SeqListInit(SeqList* psl);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl);
// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x);
// 顺序表尾删
void SeqListPopBack(SeqList* psl);
// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x);
// 顺序表头删
void SeqListPopFront(SeqList* psl);
// 顺序表查找
int SeqListFind(SeqList* psl, SLDataType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos);
// 顺序表销毁
void SeqListDestory(SeqList* psl);
// 顺序表打印
void SeqListPrint(SeqList* psl);

//顺序表初始化
void SeqListInit(SeqList* psl)
{
    
    
	assert(psl);
	psl->array= (SLDataType*)malloc(sizeof(SLDataType) * 4);
	if (psl->array == NULL)
	{
    
    
		perror("malloc fail");
		return;
	}
	psl->size = 0;
	psl->capicity = 4;
}

// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl)
{
    
    
	assert(psl);
	if (psl->size == psl->capicity)
	{
    
    
		SLDataType* tmp = (SLDataType*)realloc(psl->array, sizeof(SLDataType) * psl->capicity * 2);
		if (tmp == NULL)
		{
    
    
			perror("realloc fail");
			return;
		}
		psl->array = tmp;
		psl->capicity *= 2;
	}
}

// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x)
{
    
    
	assert(psl);
	CheckCapacity(psl);
	psl->array[psl->size] = x;
	psl->size++;
}

// 顺序表尾删
void SeqListPopBack(SeqList* psl)
{
    
    
	assert(psl);
	assert(psl->size > 0);
	psl->array[psl->size-1] = 0;
	psl->size--;
}

// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x)
{
    
    
	assert(psl);
	CheckCapacity(psl);
	int end = psl->size - 1;
	while (end >= 0)
	{
    
    
		psl->array[end + 1] = psl->array[end];
		--end;
	}
	psl->array[0] = x;
	psl->size++;
}

// 顺序表头删
void SeqListPopFront(SeqList* psl)
{
    
    
	assert(psl);
	assert(psl->size > 0);
	int begin = 1;
	while (begin < psl->size)
	{
    
    
		psl->array[begin - 1] = psl->array[begin];
		++begin;
	}
	psl->size--;
}

// 顺序表查找
int SeqListFind(SeqList* psl, SLDataType x)
{
    
    
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
    
    
		if (psl->array[i] == x)
		{
    
    
			return i;
		}
	}
	return -1;
}

// 顺序表在pos位置插入x
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x)
{
    
    
	assert(psl);
	assert(pos >= 0 && pos <= psl->size);
	CheckCapacity(psl);
	int end = psl->size - 1;
	while (end >= pos)
	{
    
    
		psl->array[end + 1] = psl->array[end];
		--end;
	}
	psl->array[pos] = x;
	psl->size++;
}

// 顺序表删除pos位置的值
void SeqListErase(SeqList* psl, size_t pos)
{
    
    
	assert(psl);
	assert(pos >= 0 && pos <= psl->size);
	int begin = pos + 1;
	while (begin < psl->size)
	{
    
    
		psl->array[begin - 1] = psl->array[begin];
		++begin;
	}
	psl->size--;
}
// 顺序表销毁
void SeqListDestory(SeqList* psl)
{
    
    
	assert(psl);
	free(psl->array);
	psl->array == NULL;
	psl->capicity = 0;
	psl->size = 0;
}

// 顺序表打印
void SeqListPrint(SeqList* psl)
{
    
    
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
    
    
		printf("%d ", psl->array[i]);
	}
	printf("\n");

}

Guess you like

Origin blog.csdn.net/weixin_51799303/article/details/131277126