Data structure budgeting method-sequence table

1. Sequence table


1.1 Concept and structure

        A sequence table is a linear structure that uses a storage unit with a continuous physical address to store data elements in sequence. Generally, array storage is used. Complete the addition, deletion, checking and modification of data on the array.
Sequence lists can generally be divided into:
1. Static sequence list: Use fixed-length arrays to store elements.

2. Dynamic sequence table: Use dynamically opened array storage.


1.2 Interface functions

        ​ ​ ​ Static sequence tables are only suitable for scenarios where you know how much data needs to be stored. The fixed-length array of the static sequence table causes N to be too large. If the space is too much, it is wasted, and if it is too little, it will not be enough. Therefore, in reality, dynamic sequence tables are basically used to dynamically allocate space according to needs, so below we implement dynamic sequence tables.

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);

 1.3 Implementation of interface functions

// 顺序表初始化
void SeqListInit(SeqList* psl)
{
	psl->array = NULL;
	psl->capicity = 0;
	psl->size = 0;
}
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl)
{
	if (psl->size == psl->capicity)
	{
		int new = psl->capicity == 0 ? 4 : 2 * (psl->capicity);
		SLDataType* temp = (SLDataType*)realloc(psl->array, sizeof(SLDataType) * new);
		if (temp == NULL)
		{
			perror("realloc");
			return;
		}
		psl->array = temp;
		psl->capicity = new;
	}
}
// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x)
{
	CheckCapacity(psl);
	psl->array[psl->size] = x;
	psl->size++;
}
// 顺序表尾删
void SeqListPopBack(SeqList* psl)
{
	//检查是否为空
	assert(psl->size > 0);
	psl->size--;
}
// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x)
{
	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)
{
	//数据往前挪动覆盖,size--
	assert(psl->size > 0);
	int begin = 1;
	while (begin < psl->size)
	{
		psl->array[begin - 1] = psl->array[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
//注意pos在这里是下标,从0开始
//而size是数据个数
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 >= psl->size)
	{
		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;
	while (begin < psl->size)
	{
		psl->array[begin] = psl->array[begin + 1];
		++begin;
	}
	psl->size--;
}
// 顺序表销毁
void SeqListDestory(SeqList* psl)
{
	if (psl->array != NULL)
	{
		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");
}

1.4 Implementation details: 

1. Capacity expansion problem

        ​​​​Here we directly use the realloc function, which is more convenient than the malloc function. When the space is 0, the space is directly opened. When the space is insufficient, the capacity will be increased.

int new = psl->capicity == 0 ? 4 : 2 * (psl->capicity);

The meaning of this statement is that when the space is 0, open up a space the size of 4 structures.


2.Print

        It is very simple to implement the printing operation. You only need to print valid data (size).


3.Tail plug

        Implementing tail insertion is very simple. You only need to store data at the size position and then ++size the data.


4.Tail deletion

        To delete, we must first assert whether the sequence table is empty. If it is empty, the deletion operation will not be performed. Then, just --size can complete the deletion operation.


5.Head plug

        To insert the head of the sequence table, you only need to move the data after the first element backward, and then write the data of the first element.

At this time, we use the end pointer to receive and move the data.


6. Header deletion

        To delete the head, you just need to overwrite the first element. This time, use begin to move the data forward.


7. Insert anywhere

        There is not much difference between inserting at any position and inserting at the beginning. Just move the data backward from the node you want to insert, but be careful not to access out of bounds.


8. Delete anywhere

        This is also very similar to head deletion. If you delete a piece of data, the data will be moved forward.


9. Destruction sequence table

        Finally, of course, we must not forget to destroy the sequence list.

2. Complete code of sequence table.​ 

list.h

#pragma once
#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);

list.c

#include"list.h"
// 顺序表初始化
void SeqListInit(SeqList* psl)
{
	psl->array = NULL;
	psl->capicity = 0;
	psl->size = 0;
}
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* psl)
{
	if (psl->size == psl->capicity)
	{
		int new = psl->capicity == 0 ? 4 : 2 * (psl->capicity);
		SLDataType* temp = (SLDataType*)realloc(psl->array, sizeof(SLDataType) * new);
		if (temp == NULL)
		{
			perror("realloc");
			return;
		}
		psl->array = temp;
		psl->capicity = new;
	}
}
// 顺序表尾插
void SeqListPushBack(SeqList* psl, SLDataType x)
{
	CheckCapacity(psl);
	psl->array[psl->size] = x;
	psl->size++;
}
// 顺序表尾删
void SeqListPopBack(SeqList* psl)
{
	//检查是否为空
	assert(psl->size > 0);
	psl->size--;
}
// 顺序表头插
void SeqListPushFront(SeqList* psl, SLDataType x)
{
	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)
{
	//数据往前挪动覆盖,size--
	assert(psl->size > 0);
	int begin = 1;
	while (begin < psl->size)
	{
		psl->array[begin - 1] = psl->array[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
//注意pos在这里是下标,从0开始
//而size是数据个数
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 >= psl->size)
	{
		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;
	while (begin < psl->size)
	{
		psl->array[begin] = psl->array[begin + 1];
		++begin;
	}
	psl->size--;
}
// 顺序表销毁
void SeqListDestory(SeqList* psl)
{
	if (psl->array != NULL)
	{
		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");
}

 

おすすめ

転載: blog.csdn.net/2301_76618602/article/details/134161409