Detailed explanation of sequence table operation


insert image description here

1. Linear table

A linear list is a finite sequence of n data elements with the same properties.
A 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 to say, a continuous straight
line. However, the physical structure is not necessarily continuous. When the linear table is physically stored, it is usually stored in the form of an array and a chain structure.

2. Sequence table

1. Concept

The sequence table is a linear structure in which data elements are sequentially stored in a storage unit with continuous physical addresses, and is generally stored in an array. Add, delete, check and modify data on the array.

The sequence table can be divided into:

  1. Static sequence table: use a fixed-length array to store elements.
//顺序表静态存储
#define N 5
//这样写方便后期将int改为其他数据类型
typedef int SLDataType;

typedef struct SeqList
{
    
    
	SLDataType arr[N];//定长数组
	int size;      //有效数据的个数
}SeqList;
  1. Dynamic sequence table: use dynamically opened array storage.
//顺序表动态存储
typedef int SLDataType;

typedef struct SeqList
{
    
    
	SLDataType* a;//指向动态开辟的数组
	int size;    //有效数据个数
	int capicity;//空间的容量
}SeqList;

2. Interface implementation

The static sequence table is 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 fixed, and the space is wasted if it is opened too much, and it is not enough if it is opened too little. Therefore, in reality, it is basically usedDynamic Sequence Table, according to the need to dynamically allocate the space size , so below we implement the dynamic sequence table.

#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

//这样写方便后期将int改为其他数据类型
typedef int SLDateType;
//用一个结构体存放顺序表
typedef struct SeqList
{
    
    
	SLDateType* a;//指向动态开辟的数组
	int size;    //有效数据个数
	int capicity;//空间的容量
}SeqList;

// 对数据的管理:增删查改 

//初始化顺序表
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);

1>Initialization sequence table

void SeqListInit(SeqList* ps)
{
    
    
	//动态开辟内存
	ps->a = (SLDateType*)malloc(sizeof(SLDateType) * 5);
	if (ps->a == NULL)
	{
    
    
		perror("malloc failed");
		exit(-1);
	}
	ps->size = 0;
	ps->capacity = 5;
}

2> Free up space after the operation

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

3>Print sequence table

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

4> tail plug

When inserting data into the sequence table, you need to judge whether the sequence table is full. If it is full, you need to expand the capacity. We encapsulate the operation of checking the expansion in a function

//检查是否已满
void SeqListCheck(SeqList* ps)
{
    
    
	//当数据个数与容量相等时代表顺序表满了
	if (ps->size == ps->capacity)
	{
    
    
		//因为可能会异地扩容,先用另一个指针接收
		//这里扩容到原来的2倍
		SLDateType* tmp = (SLDateType*)realloc(ps->a, ps->capacity * 2 * (sizeof(SLDateType)));
		if (tmp == NULL)
		{
    
    
			perror("realloc failed");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
}

Tail insertion only needs to add a data at the end of the sequence table, and then add 1 to the size

//尾插
void SeqListPushBack(SeqList* ps, SLDateType x)
{
    
    
	SeqListCheck(ps);
	ps->a[ps->size] = x;
	ps->size++;
}

insert image description here

5> plug

Head insertion needs to check whether the sequence table is full first, then move all elements to the right by one, and then put the element to be inserted in the first place, here you need to start from the last element to move to the right, otherwise the data will be overwritten and changed

void SeqListPushFront(SeqList* ps, SLDateType x)
{
    
    
	SeqListCheck(ps);
	for (int i = ps->size - 1; i >= 0; i--)
	{
    
    
		ps->a[i + 1] = ps->a[i];
	}
	ps->a[0] = x;
	ps->size++;
}

insert image description here

6> head delete

To delete the head, just move all the elements to the left by one bit to cover the first element, size-1, to move to the left, you need to move the leftmost element first to prevent the element from being overwritten

void SeqListPopFront(SeqList* ps)
{
    
    
	//判断顺序表是否为空
	assert(ps->size>0);
	for (int i = 0; i < ps->size - 1; i++)
	{
    
    
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

insert image description here

7> tail delete

Tail deletion only needs to size-1 to make it inaccessible

void SeqListPopBack(SeqList* ps)
{
    
    
    //判断顺序表是否为空
	assert(ps->size>0);
	ps->size--;
}

insert image description here

8> Sequence table lookup

Find x in the sequence table, return its subscript, if not found, return -1

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

9>Insert x at position pos in the sequence table

Move the pos subscript and subsequent elements to the right (need to move right from the last element to prevent overwriting), and then insert x into the subscript pos position

void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{
    
    
	//检查下标pos是否合法
	assert(pos >= 0 && pos <= ps->size);
	SeqListCheck(ps);
	
	for (int i = ps->size - 1; i >= pos; i--)
	{
    
    
		ps->a[i + 1] = ps->a[i];
	}
	ps->a[pos] = x;
	ps->size++;
}

insert image description here

10>Delete the value of the pos position in the sequence table

Move the elements behind the pos subscript to the left by one bit (starting from the leftmost element to prevent being overwritten), and delete the elements on the pos subscript

void SeqListErase(SeqList* ps, int pos)
{
    
    
	//检查pos的合法性
	assert(pos >= 0 && pos < ps->size);

	for (int i = pos; i < ps->size - 1; i++)
	{
    
    
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

insert image description here

Guess you like

Origin blog.csdn.net/zcxyywd/article/details/131925606