Article directory
sequence table
The sequence table is a kind of linear structure----sequential storage structure
This structure occupies a contiguous space in memory (similar to an array)
A sequence table can be implemented in two ways:
- One is to use static array to achieve,
#define NUM 100
typedef struct SeqList{
int a[NUM];
int size;//表长
}SeqList;
NUM is the size of the array, which is the number of elements that can be placed in the sequence table.
We can use size to record how many elements have been placed in the array at a certain moment.
- One is to use dynamic development to achieve
typedef struct SeqList {
SeqListType* list;
int size;//表长
int capacity;
}SeqList;
The use of pointers and dynamic memory development can flexibly control the size of the space
Also use size to record how many elements have been stored
Capacity is similar to NUM in static arrays, the difference is that Capacity can be expanded or reduced as needed.
Comparison of the two: We can't determine how much space we actually need to use before we use it, so we use the method of dynamic development, which can flexibly control the size of the space.
The functions that need to be implemented in the sequence table:
The sequence table can achieve the following functions:
//函数的声明
//顺序表的初始化----SeqListInit
//尾插一个元素----SeqListPushBack
//尾删一个元素----SeqListPopBack
//头插一个元素----SeqListPushFront
//头删一个元素----SeqListPopFront
//任何位置的元素插入----SeqListInsert
//任何位置的元素删除----SeqListErase
//检查容量----SeqListCheckCapacity
//销毁顺序表----SeqListDeStroy
Next, we will implement these functions in turn
Initialization of the sequence table
void SeqListInit(SeqList* psl)
{
assert(psl);
psl->capacity = 0;
psl->size = 0;
psl->list = NULL;
}
We can start with an initial value for capacity, or we can assign the initial value to 0 like this
The capacity of the sequence table
Note: When we operate a sequence table, we need to pay attention to whether the capacity of the sequence table is full. If the capacity of the sequence table is full, we need to expand the capacity so that we can continue to add elements to the sequence table.
void SeqListCheckCapacity(SeqList* psl)
{
assert(psl);//判断psl是否为空指针
if (psl->size == psl->capacity)
{
int newcapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;
//如果capacity的值为0(只有初始化的时候才可能为0),那么就将capacity 的值赋为4。
//如果caoacity的值不为0,那么就让容量翻倍。
SeqListType* tmp = (SeqListType*)realloc(psl->list, sizeof(SeqListType) * newcapacity);
if (tmp == NULL)
{
printf("realloc:fail\n");
exit(-1);
}
else
{
psl->list = tmp;
psl->capacity = newcapacity;
}
}
}
When the value of size and capacity are the same, it means that the capacity of the sequence table is full, and we need to expand the capacity
Note: We need to judge whether the expansion is successful (judging whether tmp is a null pointer).
Add elements to the sequence list
add element at the end of the sequence list
Note: 1. Every time you add an element to the sequence table, you need to check the capacity of the sequence table.
2. Every time you add an element, you need to increase the value of size by 1.
void SeqListPushBack(SeqList* psl, SeqListType x)
{
assert(psl);
SeqListCheckCapacity(psl);
psl->list[psl->size] = x;
psl->size++;
}
When adding elements to the tail, it
psl->list[psl->size]
is the address we want to assign. Since the value of size is easy to get, the operation of adding elements to the tail is very simple.
Add elements to the head of the sequence list
void SeqListPushFront(SeqList* psl, SeqListType x)
{
assert(psl);
SeqListCheckCapacity(psl);
int begin = psl->size;
while (begin > 0)
{
psl->list[begin] = psl->list[begin - 1];
begin--;
}
psl->list[0] = x;
psl->size++;
}
Add an element at the specified position in the sequence table
void SeqListInsert(SeqList* psl, size_t pos, SeqListType x)
{
assert(psl);
if (pos > psl->size)
{
printf("越界");
}
SeqListCheckCapacity(psl);//检查容量
size_t begin = psl->size;
while (begin > pos)
{
psl->list[begin] = psl->list[begin - 1];
begin--;
}
psl->list[pos] = x;
psl->size++;
}
Adding an element at a specified position is very similar to adding an element to the head of a sequence list.
However, before inserting elements, we need to determine whether the passed parameters meet the conditions
Different insertion positions have different results :
delete an element from the sequence list
It should be noted that the value of size needs to be decremented by 1 every time an element is deleted in the sequence table.
delete the element at the end of the sequence list
//尾删一个元素
void SeqListPopBack(SeqList* psl)
{
assert(psl);
if (psl->size > 0)
{
psl->size--;
}
}
To delete the elements at the end, we only need to reduce the table length (size) by 1, because we use size to record how many elements there are in the sequence table. It is equivalent to removing the last element.
delete the element at the head of the sequence list
//头删一个元素
void SeqListPopFront(SeqList* psl)
{
assert(psl);
int begin = 1;
while (begin < psl->size)
{
psl->list[begin-1] = psl->list[begin];
begin++;
}
psl->size--;
}
To delete the element at the head of the element table, you only need to start from the second element in the sequence table, cover it forward in turn, until the value of the last element, cover the position of the penultimate element, and then let the table length (size ) minus 1 to complete the deletion of the head element.
Deletes the element at the specified position in the sequence table
void SeqListErase(SeqList* psl, size_t pos)
{
assert(psl);
assert(pos < psl->size);
size_t begin = pos+1;
while (begin < psl->size)
{
psl->list[begin-1] = psl->list[begin];
begin++;
}
psl->size--;
}
The method of deleting the element at the specified position is similar to the method of deleting the head element:
Destruction order table
Since we are using the sequence table implemented by the method of dynamic memory development, we need to release the dynamically opened space in the end.
void SeqListDeStroy(SeqList* psl)
{
assert(psl);
free(psl->list);
psl->capacity = 0;
psl->size = 0;
psl->list = NULL;
}
Complete implementation of sequence table
head FileSeqList.h
#pragma once
//顺序表
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//结构的声明
//有两种顺寻标的声明,一种是静态的---以数组的形式
//另一种是动态的----动态内存开辟,第一种方式开辟出来的空间可能会不足,,也可能会浪费,所以我们采用动态内存开辟的方式
typedef int SeqListType;
typedef struct SeqList {
SeqListType* list;
int size;
int capacity;
}SeqList;
//一个顺序表要实现的功能有:在任何一个位置插入一个元素,
//在任何一个位置删除一个元素,修改元素,查找元素
//函数的声明
//顺序表的初始化
void SeqListInit(SeqList* psl);
//尾插一个元素
void SeqListPushBack(SeqList* psl, SeqListType x);
//尾删一个元素
void SeqListPopBack(SeqList* psl);
//头插一个元素
void SeqListPushFront(SeqList* psl, SeqListType x);
//头删一个元素
void SeqListPopFront(SeqList* psl);
//任何位置的元素插入
void SeqListInsert(SeqList* psl, size_t pos, SeqListType x);
//任何位置的元素删除
void SeqListErase(SeqList* psl, size_t pos);
//检查容量
void SeqListCheckCapacity(SeqList* psl);
//销毁顺序表
void SeqListDeStroy(SeqList* pal);
//打印顺序表的内容
void SeqListPrint(SeqList* psl);
Source FileSeqList.c
#define _CRT_SECURE_NO_WARNINGS 1
//函数实现
#include"SeqList.h"
//顺序表的初始化
void SeqListInit(SeqList* psl)
{
assert(psl);
psl->capacity = 0;
psl->size = 0;
psl->list = NULL;
}
//检查容量
void SeqListCheckCapacity(SeqList* psl)
{
assert(psl);
if (psl->size == psl->capacity)
{
int newcapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;
SeqListType* tmp = (SeqListType*)realloc(psl->list, sizeof(SeqListType) * newcapacity);
if (tmp == NULL)
{
printf("realloc:fail\n");
exit(-1);
}
else
{
psl->list = tmp;
psl->capacity = newcapacity;
}
}
}
//尾插一个元素
void SeqListPushBack(SeqList* psl, SeqListType x)
{
assert(psl);
SeqListCheckCapacity(psl);
psl->list[psl->size] = x;
psl->size++;
}
//尾删一个元素
void SeqListPopBack(SeqList* psl)
{
assert(psl);
if (psl->size > 0)
{
psl->size--;
}
}
//头插一个元素
void SeqListPushFront(SeqList* psl, SeqListType x)
{
assert(psl);
SeqListCheckCapacity(psl);
int begin = psl->size;
while (begin > 0)
{
psl->list[begin] = psl->list[begin - 1];
begin--;
}
psl->list[0] = x;
psl->size++;
}
//头删一个元素
void SeqListPopFront(SeqList* psl)
{
assert(psl);
int begin = 1;
while (begin < psl->size)
{
psl->list[begin-1] = psl->list[begin];
begin++;
}
psl->size--;
}
//任何位置的元素插入
void SeqListInsert(SeqList* psl, size_t pos, SeqListType x)
{
assert(psl);
if (pos > psl->size)
{
printf("越界");
}
SeqListCheckCapacity(psl);
size_t begin = psl->size;
while (begin > pos)
{
psl->list[begin] = psl->list[begin - 1];
begin--;
}
psl->list[pos] = x;
psl->size++;
}
//任何位置的元素删除
void SeqListErase(SeqList* psl, size_t pos)
{
assert(psl);
assert(pos < psl->size);
size_t begin = pos+1;
while (begin < psl->size)
{
psl->list[begin-1] = psl->list[begin];
begin++;
}
psl->size--;
}
//销毁顺序表
void SeqListDeStroy(SeqList* psl)
{
assert(psl);
free(psl->list);
psl->capacity = 0;
psl->size = 0;
psl->list = NULL;
}
//打印顺序表的内容
void SeqListPrint(SeqList* psl)
{
assert(psl);
int i = 0;
for (i = 0; i < psl->size; i++)
{
printf("%d ", psl->list[i]);
}
printf("\n");
}
Source Filetest.c
void menu()
{
printf("********************************\n");
printf("*** 1.尾插 2.尾删 ***\n");
printf("*** 3.头插 4.头删 ***\n");
printf("*** 5.指定插入 6.指定删除 ***\n");
printf("*** 7.查看 -1.退出 ***\n");
printf("********************************\n");
}
int main()
{
SeqList data;
InitSeqList(&data);
int option = -1;
do {
menu();
printf("请选择您想要进行的操作:>");
scanf("%d", &option);
SeqListType val = 0;
size_t pos = 0;
switch (option)
{
case 1:
printf("请输入您想要插入的数据:>");
scanf("%d", &val);
SeqListPushBack(&data, val);
break;
case 2:
SeqListPopBack(&data);
break;
case 3:
printf("请输入您想要插入的数据:>");
scanf("%d", &val);
SeqListPushFront(&data, val);
break;
case 4:
SeqListPopFront(&data);
break;
case 5:
printf("请输入你想要插入的数据:>");
scanf("%d", &val);
printf("请输入你想要插入的位置:>");
scanf("%d", &pos);
SeqListInsert(&data, pos, val);
break;
case 6:
printf("请输入您想要删除的位置:>");
scanf("%d", &pos);
SeqListErase(&data, pos);
break;
case 7:
SeqListPrint(&data);
break;
case -1:
printf("退出程序\n");
return 0;
break;
default:
printf("请重新选择\n");
break;
}
} while (option);
test2(&data);
return 0;
}
summary
- When operating the sequence table, you need to be clear about these three properties of the sequence table:
- The starting location of the storage space
- Maximum capacity of the sequence table
- the current length of the sequence table
- We can add and delete elements to the sequence table by using the current length and starting position of the sequence table.
However, it should be noted that the table length will increase by 1 after each element is added, and the table length will decrease by 1 after each element is deleted. .