Artigo Diretório
1. Tabela linear
Uma lista linear é uma sequência finita de n elementos de dados com as mesmas características . A tabela linear é uma estrutura de dados amplamente utilizada na prática. Tabelas lineares comuns: tabela de sequência, lista encadeada, pilha, fila, string ...
Uma mesa linear é logicamente uma estrutura linear, ou seja, uma linha reta contínua. No entanto, a estrutura física não é necessariamente contínua.Quando uma tabela linear é armazenada fisicamente, geralmente é armazenada na forma de um array e uma estrutura em cadeia.
2. Tabela de sequência
A tabela de sequência é uma estrutura linear na qual uma seção de unidades de armazenamento com endereços físicos contínuos armazena elementos de dados em sequência.Geralmente, o armazenamento em array é usado. Completa adição, exclusão, verificação e modificação de dados na matriz.
A tabela de sequência geralmente pode ser dividida em:
(1) Tabela de sequência estática: use armazenamento de matriz de comprimento fixo.
// 顺序表的静态存储
#define N 100
typedef int SLDataType;
typedef struct SeqList
{
SLDataType array[N]; // 定长数组
size_t size; // 有效数据的个数
}SeqList;
No entanto, o uso de armazenamento estático tem algumas desvantagens:
A tabela de sequência estática só é adequada para cenários em que você sabe quantos dados precisa armazenar. A matriz de comprimento fixo da tabela de sequência estática faz com que N seja maior, e o espaço seja muito desperdiçado, e menos não é suficiente. Portanto, basicamente usamos tabelas de sequência dinâmica e alocamos espaço dinamicamente de acordo com nossas necessidades reais.
(2) Tabela de sequência dinâmica: use armazenamento de array desenvolvido dinamicamente. (A realização adota a forma de gravação de subarquivos)
Primeiro, forneça a declaração da função que queremos implementar no arquivo .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);
Realização da função:
(1) inicialização da tabela de sequência
O array de ponteiros na estrutura aponta para o array desenvolvido dinamicamente, o número de tamanhos de dados válidos é inicializado em 0 e a capacidade máxima do array é a capacidade
ps é um ponteiro para a estrutura, a capacidade é a capacidade máxima da matriz
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) Impressão da tabela de sequência
Imprima todos os elementos da matriz
// 顺序表打印
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) Expansão da tabela de sequência
Se o número do tamanho efetivo dos dados for maior ou igual à capacidade máxima do array, a função realloc precisa ser usada para expandir o 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) Insira no final da tabela de sequência
Ao inserir, você deve primeiro determinar se o número de tamanho de dados efetivo na matriz está cheio, e você pode chamar a função CheckCapacity. Como o número de tamanho é o subscrito do último elemento da matriz, execute ps-> array [ ps-> tamanho] = x; então, tamanho ++ é bom
// 顺序表尾插
void SeqListPushBack(SeqList* ps, SLDataType x)
{
CheckCapacity(ps);
ps->array[ps->size] = x;
ps->size++;
}
(5) Exclua o final da tabela de sequência
Para excluir o final da tabela de sequência, você só precisa dimensionar -. Embora o elemento final não seja realmente excluído da matriz, não imprimiremos o elemento final durante a impressão, para que o objetivo de excluir o elemento final seja alcançado .
// 顺序表尾删
void SeqListPopBack(SeqList* ps)
{
assert(ps);
ps->size--;
}
(6) Inserção do cabeçalho de sequência
Durante a operação de inserção, primeiro determine se o número de tamanho de dados efetivo na matriz está cheio, chame a função CheckCapacity e, em seguida, mova os elementos na matriz para trás e insira o elemento a ser inserido na primeira posição do tamanho da matriz ++
// 顺序表头插
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) Exclusão do cabeçalho da sequência
Mova os elementos da matriz para frente e, em seguida, dimensione - fará
// 顺序表头删
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) Consulta de tabela de sequência
Percorra os elementos na matriz e retorne o índice do elemento a ser pesquisado após encontrar o elemento a ser pesquisado.
// 顺序表查找
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) A tabela de sequência insere x na posição pos
A ideia específica é a mesma da primeira e da última inserções
// 顺序表在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) A tabela de sequência exclui o valor da posição pos
A ideia específica é a mesma que a primeira exclusão e a exclusão final
// 顺序表删除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--;
}
Três. Implementação completa do código
Arquivo SeqList.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* 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);
Arquivo SeqList.c
#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--;
}
arquivo test.c
#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();
}