Data structure: Hand-tear sequence table --- Realization of the function of adding, deleting, checking, modifying and searching the sequence table


Sequence Table Preface

Sequence table is an introductory knowledge of data structure, the overall knowledge is relatively simple, mainly for dynamic memory development structure pointers, and the rest are less difficult


The functions to be realized by the sequence table

The sequence table mainly needs to implement the addition, deletion, modification, and directional search and destruction of the sequence table. The specific implementation functions are as follows

// 对数据的管理:增删查改 
void SeqListInit(SeqList* ps);
void SeqListDestroy(SeqList* ps);

void SeqListPrint(SeqList* ps);
void SeqListPushBack(SeqList* ps, SLDateType x);
void SeqListPushFront(SeqList* ps, SLDateType x);
void SeqListPopFront(SeqList* ps);
void SeqListPopBack(SeqList* ps);

// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);

Definition Sequence Table

To realize the sequence table, it is necessary to define the sequence table, which is usually written in a structure in C language, including the capacity of the sequence table, the number of elements in the sequence table, and the main body of the sequence table

There are two types of definitions for the sequence table. If you do not use dynamic memory development, you can directly define an array to implement the sequence table. However, since the capacity of the array is fixed, the entire sequence table will be fixed in size, so dynamic memory development is used here. Method Implementation Sequence List

First define the sequence table

typedef int SLDateType;
typedef struct SeqList
{
    
    
	SLDateType* a;
	int size;
	int capacity;
}SeqList;

Next, we will implement the functions of the sequence table in turn.


Sequence table initialization

After defining the structure of the sequence table, you can create a sequence table. After creating the initial value, you must initialize the sequence table to a certain extent.

The code is implemented as follows

void SeqListInit(SeqList* ps)
{
    
    
	assert(ps);
	ps->a = (SLDateType*)malloc(sizeof(SLDateType) * 4);
	if (ps->a == NULL)
	{
    
    
		perror("malloc fail");
		return;
	}
	ps->size = 0;
	ps->capacity = 4;
}

About the assert function

The function of assert is assertion, which is mainly used for conditional judgment. For example, detecting ps here means detecting whether ps is a null pointer. If ps is a null pointer, subsequent operations are unnecessary, which is conducive to checking error messages. When When running until the conclusion of the statement is false, the code will be terminated directly, which is a method of brute force checking


Sequence table destruction

After the sequence table is created, the sequence table must be destroyed. What is destroyed is to release its corresponding space, nullify the pointer, and return to the initial value.

The code is implemented as follows

void SeqListDestroy(SeqList* ps)
{
    
    
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

About Nulling Pointers

Generally speaking, after releasing the relevant space, in order to avoid the occurrence of wild pointers, the pointer should be emptied, but it is also possible to not empty the pointer in some cases. Generally, the vacant pointer will be followed immediately after the space is released.


print sequence table

Print the information in the sequence table to the screen to visually observe whether there is any error message

The code is implemented as follows

void SeqListPrint(SeqList* ps)
{
    
    
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
    
    
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

end of sequence table

Inserting a piece of data into the sequence table involves tail insertion of the sequence table

The idea is also very simple. First, check whether the capacity of the original sequence table meets the requirements. If not, expand the capacity to a certain extent, and then put the data to be inserted at the end of the sequence table.

How to achieve inspection capacity?

If the size and capacity of the sequence table are consistent, it means it is full and the upper limit is reached

So the function is implemented as follows

void SLCheckCapacity(SeqList* ps)
{
    
    
	assert(ps);
	SLDateType* tmp = NULL;
	if (ps->capacity == ps->size)
	{
    
    
		tmp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * ps->capacity * 2);
		if (tmp == NULL)
		{
    
    
			perror("realloc fail");
			return;
		}
		ps->a = tmp;
		ps->capacity *= 2;
		printf("扩容成功 当前容量%d\n", ps->capacity);
	}
}

However, since there will be cases where elements are inserted at specified positions in the future, we can directly write the case of inserting elements at position x

Therefore, the function implementation becomes the implementation of inserting elements at the x position

The function is implemented as follows

void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{
    
    
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);
	int end = ps->size - 1;
	while (pos <= end)
	{
    
    
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[pos] = x;
	ps->size ++ ;
}

With the implementation of the function of inserting elements at the x position, for the function of inserting at the end, only need to replace x with size

void SeqListPushBack(SeqList* ps, SLDateType x)
{
    
    
	assert(ps);
	SeqListInsert(ps,ps->size,x);
}

sequence table plug

Similar to the tail insertion of the sequence table, when we have a function to insert elements at position x, these requirements are easy to write

void SeqListPushFront(SeqList* ps, SLDateType x)
{
    
    
	assert(ps);
	SeqListInsert(ps, 0, x);
}

sequence header

With the previous idea, we also encapsulate the deletion of the element at the x position into a function

The function is implemented as follows

void SeqListErase(SeqList* ps, int pos)
{
    
    
	assert(pos >= 0 && pos < ps->size);
	int end = ps->size-1;
	while (pos <= end)
	{
    
    
		ps->a[pos] = ps->a[pos + 1];
		pos++;
	}
	ps->size--;
}

Then head deletion is to delete the element labeled 0

The specific function is implemented as follows

void SeqListPopFront(SeqList* ps)
{
    
    
	assert(ps);
	SeqListErase(ps, 0);
}

tail deletion

With the idea of ​​head deletion, tail deletion and head deletion are basically the same

void SeqListPopBack(SeqList* ps)
{
    
    
	assert(ps);
	int end = ps->size - 1;
	SeqListErase(ps, end);
}

Sequence table directed position lookup

The simplest function, just need to traverse the sequence table

int SeqListFind(SeqList* ps, SLDateType x)
{
    
    
	assert(ps);
	for(int i=0;i<ps->size;i++)
	{
    
    
		if (ps->a[i] == x)
			return i;
	}
	return -1;
}

On the whole, the sequence table is the part of getting started with data structure, and the difficulty is low

Guess you like

Origin blog.csdn.net/qq_73899585/article/details/131548070