Explanation and realization of sequence table

1. Linear table

A linear list is a finite sequence of n data elements with the same characteristics . Linear table is a data structure widely used in practice. Common linear tables: sequence table, linked list, stack, queue, string...

A linear table is logically a linear structure, that is, a continuous straight line. However, the physical structure is not necessarily continuous. When a linear table is physically stored, it is usually stored in the form of an array and a chain structure.

2. Sequence table

The sequence table is a linear structure in which a section of storage units with continuous physical addresses store data elements in sequence. Generally, array storage is used. Complete data addition, deletion, checking and modification on the array.

The sequence table can generally be divided into:

(1) Static sequence table: use fixed-length array storage.

// 顺序表的静态存储
#define N 100
typedef int SLDataType;
typedef struct SeqList
{
    
    
 	SLDataType array[N]; // 定长数组
	size_t size; // 有效数据的个数 
}SeqList;

However, the use of static storage has such disadvantages:

The static sequence table is only suitable for scenarios where you know how much data you need to store. The fixed-length array of the static sequence table causes N to be larger, and the space is too much wasted, and the less is not enough. Therefore, we basically use dynamic sequence tables, and dynamically allocate space according to our actual needs.

(2) Dynamic sequence table: use dynamically developed array storage. (The realization adopts the form of sub-file writing)

First, give the function declaration of the function we want to implement in the .h file

// 顺序表的动态存储
typedef int SLDataType;
typedef struct SeqList
{
    
    
	 SLDataType* array; // 指向动态开辟的数组
 	 size_t size ; // 有效数据个数
 	 size_t capicity ; // 容量空间的大小
}SeqList;
// 基本增删查改接口
// 顺序表初始化
void SeqListInit(SeqList* ps, size_t capacity);
// 顺序表打印
void SeqListPrint(SeqList* ps);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* ps);
// 顺序表尾插
void SeqListPushBack(SeqList* ps, SLDataType x);
// 顺序表尾删
void SeqListPopBack(SeqList* ps);
// 顺序表头插
void SeqListPushFront(SeqList* ps, SLDataType x);
// 顺序表头删
void SeqListPopFront(SeqList* ps);
// 顺序表查找
int SeqListFind(SeqList* ps, SLDataType x); 
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, size_t pos);

Function realization:
(1) Sequence table initialization

The pointer array in the structure points to the dynamically developed array, the number of valid data size is initialized to 0, and the maximum capacity of the array is capacity

ps is a pointer to the structure, capacity is the maximum capacity of the array

void SeqListInit(SeqList* ps, size_t capacity)
{
    
    
	assert(ps);
	// array 指向动态开辟的数组
	ps->array = (SLDataType*)malloc(sizeof(SLDataType) * capacity);
	if (ps->array == NULL)
	{
    
    
		printf("初始化失败\n");
		exit(-1);
	}
	// 有效数据个数 size 初始化为 0 
	ps->size = 0;
	// 数组最大容量为capacity
	ps->capacity = capacity;
}

(2) Sequence table printing

Print out every element in the array

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

(3) Sequence table expansion

If the number of effective data size is greater than or equal to the maximum capacity of the array, the realloc function needs to be used to expand the array.

// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* ps)
{
    
    
	assert(ps);
	// 进行扩容操作
	if (ps->size >= ps->capacity)
	{
    
    
		ps->capacity *= 2;
		ps->array = (SLDataType*)realloc(ps->array, sizeof(SLDataType) * ps->capacity);
		if (ps->array == NULL)
		{
    
    
			printf("扩容失败\n");
			exit(-1);
		}
	}
}

(4) Insert at the end of the sequence table

When inserting, you must first determine whether the number of valid data size in the array is full, and you can call the CheckCapacity function. Because the number of size is the subscript of the last element of the array, execute ps-> array[ps->size] = x; then size++ is fine

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

(5) Delete the end of the sequence table

To delete the end of the sequence table, you only need to size- -. Although the end element is not actually deleted in the array, we will not print the end element when printing, so that the purpose of deleting the end element is achieved.

// 顺序表尾删
void SeqListPopBack(SeqList* ps)
{
    
    
	assert(ps);
	ps->size--;
}

(6) Sequence header insert

During the insertion operation, first determine whether the number of effective data size in the array is full, call the CheckCapacity function, and then move the elements in the array backward, and insert the element to be inserted into the first position of the array. size++

// 顺序表头插
void SeqListPushFront(SeqList* ps, SLDataType x)
{
    
    
	assert(ps);
	// 检查有效数据个数是否已满
	CheckCapacity(ps);
	int i = ps->size - 1;
	// 移动数组元素
	for (i = ps->size - 1; i >= 0; i--)
	{
    
    
		ps->array[i + 1] = ps->array[i];
	}
	// 插入元素
	ps->array[0] = x;
	// 有效个数++
	ps->size++;
}

(7) Deletion of sequence header

Move the elements in the array forward, and then size--will do

// 顺序表头删
void SeqListPopFront(SeqList* ps)
{
    
    
	assert(ps);
	int i = 0;
	// 将数组的元素向前移动
	for (i = 0; i < ps->size - 1; i++)
	{
    
    
		ps->array[i] = ps->array[i + 1];
	}
	// size--
	ps->size--;
}

(8) Sequence table lookup

Traverse the elements in the array and return the index of the element to be searched after finding the element to be searched.

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

(9) The sequence table inserts x at position pos

The specific idea is the same as that of the first and last inserts

// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, size_t pos, SLDataType x)
{
    
    
	assert(ps);
	CheckCapacity(ps);
	int i = ps->size - 1;
	for (i = ps->size - 1; i >= pos - 1; i--)
	{
    
    
		ps->array[i + 1] = ps->array[i];
	}
	ps->array[i + 1] = x;
	ps->size++;
}

(10) The sequence table deletes the value of the pos position

The specific idea is the same as the first deletion and the end deletion

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

Three. Complete code implementation

SeqList.h file

#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* ps, size_t capacity);
// 顺序表打印
void SeqListPrint(SeqList* ps);
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* ps);
// 顺序表尾插
void SeqListPushBack(SeqList* ps, SLDataType x);
// 顺序表尾删
void SeqListPopBack(SeqList* ps);
// 顺序表头插
void SeqListPushFront(SeqList* ps, SLDataType x);
// 顺序表头删
void SeqListPopFront(SeqList* ps);
// 顺序表查找
int SeqListFind(SeqList* ps, SLDataType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, size_t pos);

SeqList.c file

#include"SeqList.h"
#include<stdio.h>
// 顺序表初始化
void SeqListInit(SeqList* ps, size_t capicity)
{
    
    
	assert(ps);
	ps->array = (SLDataType*)malloc(sizeof(SLDataType) * capicity);
	if (ps->array == NULL)
	{
    
    
		printf("初始化失败\n");
		exit(-1);
	}
	ps->size = 0;
	ps->capicity = capicity;
}
// 顺序表打印
void SeqListPrint(SeqList* ps)
{
    
    
	assert(ps);
	size_t i = 0;
	for (i = 0; i < ps->size; i++)
	{
    
    
		printf("%d ", ps->array[i]);
	}
	printf("\n");
}
// 检查空间,如果满了,进行增容
void CheckCapacity(SeqList* ps)
{
    
    
	assert(ps);
	if (ps->size >= ps->capicity)
	{
    
    
		ps->capicity *= 2;
		ps->array = (SLDataType*)realloc(ps->array, sizeof(SLDataType) * ps->capicity);
		if (ps->array == NULL)
		{
    
    
			printf("扩容失败\n");
			exit(-1);
		}
	}
}
// 顺序表尾插
void SeqListPushBack(SeqList* ps, SLDataType x)
{
    
    
	CheckCapacity(ps);
	ps->array[ps->size] = x;
	ps->size++;
}
// 顺序表尾删
void SeqListPopBack(SeqList* ps)
{
    
    
	assert(ps);
	ps->size--;
}
// 顺序表头插
void SeqListPushFront(SeqList* ps, SLDataType x)
{
    
    
	assert(ps);
	CheckCapacity(ps);
	int  i = ps->size - 1;
	for (i = ps->size - 1; i >= 0; i--)
	{
    
    
		ps->array[i + 1] = ps->array[i];
	}
	ps->array[0] = x;
	ps->size++;
}
// 顺序表头删
void SeqListPopFront(SeqList* ps)
{
    
    
	assert(ps);
	int i = 0;
	for (i = 0; i < ps->size - 1; i++)
	{
    
    
		ps->array[i] = ps->array[i + 1];
	}
	ps->size--;
}
// 顺序表查找
int SeqListFind(SeqList* ps, SLDataType x)
{
    
    
	assert(ps);
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
    
    
		if (ps->array[i] == x)
		{
    
    
			return i;
		}
	}
}
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, size_t pos, SLDataType x)
{
    
    
	assert(ps);
	CheckCapacity(ps);
	int i = ps->size - 1;
	for (i = ps->size - 1; i >= pos - 1; i--)
	{
    
    
		ps->array[i + 1] = ps->array[i];
	}
	ps->array[i + 1] = x;
	ps->size++;
}
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, size_t pos)
{
    
    
	assert(ps);
	int i = pos - 1;
	for (i = pos - 1; i < ps->size - 1; i++)
	{
    
    
		ps->array[i] = ps->array[i + 1];
	}
	ps->size--;
}

test.c file

#include"SeqList.h"
#include<stdio.h>
// 测试头尾插入删除
void TestSeqList()
{
    
    
	SeqList s;
	SeqListInit(&s, 3);
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPrint(&s);
	SeqListPopBack(&s);
	SeqListPrint(&s);
	SeqListPushFront(&s, -1);
	SeqListPrint(&s);
	SeqListPopFront(&s);
	SeqListPrint(&s);
	SeqListInsert(&s, 2, 5);
	SeqListPrint(&s);
	SeqListErase(&s, 2);
	SeqListPrint(&s);

}
int main()
{
    
    
	TestSeqList();

}

Guess you like

Origin blog.csdn.net/DR5200/article/details/113817924