[Estrutura de dados e algoritmo] Realize a tabela de sequência estática e dinâmica na tabela linear

Este artigo é o início da estrutura de dados. Acima, aprendemos sobre o uso da linguagem C para implementar operações estáticas, dinâmicas e de arquivo no catálogo de endereços. O tipo de estrutura é usado nele. Na verdade, ele pode pertencer a o conteúdo da estrutura de dados. Em seguida, vamos aprender sobre a tabela de sequência.


Índice

prefácio

1. Mesa linear

1. O que é a tabela de sequência?

Em segundo lugar, a realização da tabela de sequência de análise

3. Tabela de sequência estática

1. Inicialização da tabela de sequência

2. Adicione elementos

1. Tampão traseiro

2. Plugue

3. Excluir elementos

1. Exclusão de cauda

2. Excluir cabeçalho

4. Alterar dados e pesquisa

5. Imprima e destrua a tabela de sequência

4. Tabela de Sequência Dinâmica

1. Inicialização

2. Expansão

3. Tabela de sequência de destruição

5. Demonstração completa do código

1. Tabela de sequência estática

1.teste.c

2.Seqtable.h

3.Seqtable.c

2. Tabela de sequência dinâmica

1.teste.c

2.Seqtable.h

3.Seqtable.c

Resumir


prefácio

O que são estruturas de dados?

Para todos, este é um novo módulo de conteúdo. Estrutura de dados é a maneira como os computadores armazenam e organizam dados . Uma estrutura de dados é uma coleção de elementos de dados que possuem um ou mais relacionamentos específicos entre si . Frequentemente, estruturas de dados bem escolhidas podem levar a maior eficiência operacional ou de armazenamento . As estruturas de dados são frequentemente associadas a algoritmos de recuperação e técnicas de indexação eficientes .

A seguir, explicaremos a implementação da tabela de sequência da estrutura de dados


1. Mesa linear

Uma lista linear é uma sequência finita de n elementos de dados com as mesmas propriedades. Tabela linear é uma estrutura de dados muito utilizada na prática, tabela linear comum: lista sequencial, lista encadeada, pilha, fila, string...

Uma mesa linear é logicamente uma estrutura linear, isto é, uma linha recta contínua. No entanto, a estrutura física não é necessariamente contínua.Quando a tabela linear é armazenada fisicamente, ela geralmente é armazenada na forma de uma matriz e uma estrutura em cadeia.

Na verdade, depois de aprender a tabela de sequência e a lista vinculada, é fácil aprender várias estruturas, como pilhas, filas e árvores binárias. Elas também são chamadas de tabelas de sequência e listas vinculadas. Elas são a base das estruturas de dados e da base para realização de conteúdo pós-sequência.

1. O que é a tabela de sequência?

1. Armazenar os elementos da tabela um a um em um grupo de unidades de armazenamento contínuo.Esta estrutura de armazenamento é uma estrutura sequencial .

2. Uma tabela linear armazenada em uma estrutura sequencial é chamada de tabela sequencial

Resumir:

A tabela de sequência é uma estrutura linear na qual os elementos de dados são armazenados sequencialmente em uma unidade de armazenamento com endereços físicos contínuos e geralmente são armazenados em uma matriz. Adicione, exclua, verifique e modifique dados na matriz.

Em segundo lugar, a realização da tabela de sequência de análise

A tabela de sequência é dividida em tabelas de sequência dinâmica e estática. As funções de operação real da tabela de sequência são aproximadamente, adição, exclusão, modificação e verificação, e subdivididas em operações como cabeça e cauda, ​​adição e exclusão, inicialização e destruição da sequência mesa.

Vamos apresentar como as tabelas de sequência estática e dinâmica são implementadas a seguir! ! !

3. Tabela de sequência estática

A estrutura utilizada é:

1. Inicialização da tabela de sequência

como a imagem mostra:

Demonstração do código:

//初始化函数
void InitSeqtable(Seqtable* st) {
	//for (int i = 0; i < MAX; i++) {
	//	st->date[i] = 0;//初始化为0  实际上可以不用初始化数组
	//}
	st->size = 0;
}

2. Adicione elementos

Dividido em inserção de cabeça e inserção de cauda

1. Tampão traseiro

como a imagem mostra:

Demonstração do código:

//尾插入
void BackSeqtable(Seqtable* st, int data) {
	//尾部插入的时候要进行判别是否为满
	if (st->size == MAX) {
		//表示满了
		perror("顺序表已经满员,无法插入新数据\n");
		exit(-1);//退出就可以
	}
	//没有满员,就加入数据即可
	st->date[st->size++] = data;
}

2. Plugue

como a imagem mostra:

 código mostra como abaixo:

//头插入
void FrontSeqtable(Seqtable* st, int data) {
	//一样先进行判断是否满员
	if (st->size == MAX) {
		perror("满员无法插入");
		exit(-1);
	}
	//头部插入。就是将原有数据向后移动一个位置
	int num = st->size - 1;
	for (int i = num; i>=0; i--) {
		st->date[i + 1] = st->date[i];
	}
	//while (num>=0) {
	//	st->date[num + 1] = st->date[num];
	//	num--;
	//}
	//最后插入数据
	st->date[0] = data;
	st->size++;
}

3. Excluir elementos

Dividido em exclusão de cabeça e exclusão de cauda

1. Exclusão de cauda

como a imagem mostra:

 código mostra como abaixo:

//尾删除
void SeqtablePopBack(Seqtable* st) {
	//尾删除,需要判断是否为空
	assert(st->size > 0);//断言判断
	st->size--;//直接元素个数减去一个就可以

}

2. Excluir cabeçalho

como a imagem mostra:

 código mostra como abaixo:

//头删除
void SeqtablePopFront(Seqtable* st) {
	//头部删除,也要判空
	assert(st->size > 0);//断言
	//将后面的数据覆盖前面的数据
	for (int i = 0; i < st->size-1; i++) {
		st->date[i] = st->date[i + 1];
	}
	st->size--;//size减去一个元素即可
}

4. Alterar dados e pesquisa

Se você deseja alterar os dados do subscrito especificado, insira o elemento que deseja encontrar e, para alterar os dados, deve primeiro encontrar as coordenadas correspondentes, alterar o valor facilmente e não considerar o problema da duplicação e consultar em ordem da esquerda para a direita

código mostra como abaixo:

//查找
int SearchSeqtable(Seqtable* st) {
	assert(st->size > 0);//如果为空,不用查找,直接报错
	int num = 0;
	scanf("%d", &num);//输入查找的元素
	for (int i = 0; i < st->size; i++) {
		if (st->date[i] == num) {
			return i;//找到返回下标
		}
	}
	return -1;//没找到返回-1
	
}

void ChangeSeqtable(Seqtable* st) {
	int num=SearchSeqtable(st);//进入查找,返回下标
	if (num == -1) {
		printf("顺序表中没有该元素,无法修改\n");
		return;
	}
	int a = 0;
	scanf("%d", &a);//输入想要更改的数据
	st->date[num] = a;
}

5. Imprima e destrua a tabela de sequência

código mostra como abaixo:

//摧毁顺序表
void SeqtableDestory(Seqtable* st) {
	//摧毁的话,静态表直接初始化为0
	st->size = 0;
}

//打印
void PrintSeqtable(Seqtable* st) {
	for (int i = 0; i < st->size; i++) {
		printf("%d ", st->date[i]);
	}
}

4. Tabela de Sequência Dinâmica

A diferença entre uma tabela de sequência dinâmica e uma tabela de sequência estática é a estrutura, inicialização, destruição da tabela de sequência e expansão

A estrutura é a seguinte:

//动态顺序表
typedef struct Seqtable {
	int* data;//数据域
	int size;//个数
	int capacity;//容量
}Seqtable;

//实际上动态顺序表和静态顺序表,只有在初始化、销毁、扩容的时候不一样

1. Inicialização

//初始化顺序表
void InitSeqtable(Seqtable* st) {
	st->size = st->capacity = 0;
	st->data = NULL;
}

2. Expansão

como a imagem mostra: 

Demonstração do código:

//扩容
void Expansion(Seqtable* st) {
	//1.直接扩容二倍,这样防止后序一致扩容
	int newcapacity = st->capacity = 0 ? 4 : st->capacity * 2;
	int* tmp = (int*)realloc(st->data, newcapacity * sizeof(int));
	if (tmp == NULL) {
		//表示创建失败
		perror("realloc fail\n");
		exit(-1);
	}
	//创建成功  tmp给data
	st->data = tmp;
	st->capacity = newcapacity;
}

Conforme mostrado na figura, outro método de expansão pode ser encontrado neste artigo sobre expansão dinâmica do catálogo de endereços, que contém uma introdução (24 mensagens) [Linguagem C] Use a linguagem C para realizar o catálogo de endereços estático e dinâmico (fácil de entender)_小Blog de Wang Xuecode - Blog da CSDN

3. Tabela de sequência de destruição

void SeqListDestory(Seqtable* ps) {
	free(ps->data);//直接释放a的空间 
	ps->data = NULL;//然后指向NULL
	ps->capacity = ps->size = 0;
}

Além disso, é quase o mesmo que a tabela de sequência estática

5. Demonstração completa do código

1. Tabela de sequência estática

O chamado estático significa que o número máximo de elementos de armazenamento na tabela de sequência não pode ser alterado, pode sobrar muito ou pode não ser suficiente

1.teste.c

O uso da função principal

#define _CRT_SECURE_NO_WARNINGS
#include"Seqtable.h"
//实现顺序表
void test1()
{
	Seqtable st;
	InitSeqtable(&st);//初始化
	//尾插
	BackSeqtable(&st, 1);
	BackSeqtable(&st, 2);
	BackSeqtable(&st, 3);
	BackSeqtable(&st, 4);
	BackSeqtable(&st, 5);
	//打印
	PrintSeqtable(&st);
	printf("\n");
	//头插
	FrontSeqtable(&st, 1);
	FrontSeqtable(&st, 2);
	FrontSeqtable(&st, 3);
	FrontSeqtable(&st, 4);
	FrontSeqtable(&st, 5);
	PrintSeqtable(&st);
	//尾巴删除
	SeqtablePopBack(&st);
	SeqtablePopBack(&st);
	SeqtablePopBack(&st);
	SeqtablePopBack(&st);
	SeqtablePopBack(&st);
	printf("\n");
	//打印
	PrintSeqtable(&st);
	//头删除
	SeqtablePopFront(&st);
	printf("\n");
	//打印
	PrintSeqtable(&st);

	摧毁顺序表
	//SeqtableDestory(&st);
	printf("\n");
	//打印
	ChangeSeqtable(&st);
	PrintSeqtable(&st);
}
int main()
{	//实现静态顺序表
	test1();
	return 0;
}

2.Seqtable.h

Uso de arquivos de cabeçalho

#define _CRT_SECURE_NO_WARNINGS

//头文件,进行函数的声明
//		结构体的实现

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>

#define MAX 100
//静态顺序表的实现
typedef struct Seqtable {
	int date[MAX];//数据域
	int size;//数据个数
}Seqtable;



//实现函数声明

//初始化函数
void InitSeqtable(Seqtable* st);

//尾插入
void BackSeqtable(Seqtable* st, int data);

//头插入
void FrontSeqtable(Seqtable* st, int data);

//尾删除
void SeqtablePopBack(Seqtable* st);

//头删除
void SeqtablePopFront(Seqtable* st);

//摧毁顺序表
void SeqtableDestory(Seqtable* st);

//打印
void PrintSeqtable(Seqtable* st);

//查找指定元素
//有 返回 下标
//没有 返回 -1

int SearchSeqtable(Seqtable* st);
//更改数据
void ChangeSeqtable(Seqtable* st);

3.Seqtable.c

implementação de função

#define _CRT_SECURE_NO_WARNINGS
#include"Seqtable.h"
//实现方法
//顺序表的,头插尾插,头删尾删
//初始化,和销毁

//静态顺序表

//初始化函数
void InitSeqtable(Seqtable* st) {
	for (int i = 0; i < MAX; i++) {
		st->date[i] = 0;//初始化为0  实际上可以不用初始化数组
	}
	st->size = 0;
}
//尾插入
void BackSeqtable(Seqtable* st, int data) {
	//尾部插入的时候要进行判别是否为满
	if (st->size == MAX) {
		//表示满了
		perror("顺序表已经满员,无法插入新数据\n");
		exit(-1);//退出就可以
	}
	//没有满员,就加入数据即可
	st->date[st->size++] = data;
}
//头插入
void FrontSeqtable(Seqtable* st, int data) {
	//一样先进行判断是否满员
	if (st->size == MAX) {
		perror("满员无法插入");
		exit(-1);
	}
	//头部插入。就是将原有数据向后移动一个位置
	int num = st->size - 1;
	for (int i = num; i>=0; i--) {
		st->date[i + 1] = st->date[i];
	}
	//while (num>=0) {
	//	st->date[num + 1] = st->date[num];
	//	num--;
	//}
	//最后插入数据
	st->date[0] = data;
	st->size++;
}

//尾删除
void SeqtablePopBack(Seqtable* st) {
	//尾删除,需要判断是否为空
	assert(st->size > 0);//断言判断
	st->size--;//直接元素个数减去一个就可以

}
//头删除
void SeqtablePopFront(Seqtable* st) {
	//头部删除,也要判空
	assert(st->size > 0);//断言
	//将后面的数据覆盖前面的数据
	for (int i = 0; i < st->size-1; i++) {
		st->date[i] = st->date[i + 1];
	}
	st->size--;//size减去一个元素即可
}
//摧毁顺序表
void SeqtableDestory(Seqtable* st) {
	//摧毁的话,静态表直接初始化为0
	st->size = 0;
}

//打印
void PrintSeqtable(Seqtable* st) {
	for (int i = 0; i < st->size; i++) {
		printf("%d ", st->date[i]);
	}
}

//查找
int SearchSeqtable(Seqtable* st) {
	assert(st->size > 0);//如果为空,不用查找,直接报错
	int num = 0;
	scanf("%d", &num);//输入查找的元素
	for (int i = 0; i < st->size; i++) {
		if (st->date[i] == num) {
			return i;//找到返回下标
		}
	}
	return -1;//没找到返回-1
	
}

void ChangeSeqtable(Seqtable* st) {
	int num=SearchSeqtable(st);//进入查找,返回下标
	if (num == -1) {
		printf("顺序表中没有该元素,无法修改\n");
		return;
	}
	int a = 0;
	scanf("%d", &a);//输入想要更改的数据
	st->date[num] = a;
}

2. Tabela de sequência dinâmica

A chamada dinâmica é usar funções como realloc para abrir espaço dinamicamente e tentar tornar o espaço da tabela de sequência razoável.

1.teste.c

Função principal para testar e usar a tabela de sequência

#define _CRT_SECURE_NO_WARNINGS
#include"动态顺序表.h"

void test2() {
	Seqtable st;
	InitSeqtable(&st);//初始化
	//尾插
	BackSeqtable(&st, 1);
	BackSeqtable(&st, 2);
	BackSeqtable(&st, 3);
	BackSeqtable(&st, 4);
	BackSeqtable(&st, 5);
	//打印
	PrintSeqtable(&st);
	printf("\n");
	//头插
	FrontSeqtable(&st, 1);
	FrontSeqtable(&st, 2);
	FrontSeqtable(&st, 3);
	FrontSeqtable(&st, 4);
	FrontSeqtable(&st, 5);
	PrintSeqtable(&st);
	//尾巴删除
	SeqtablePopBack(&st);
	SeqtablePopBack(&st);
	SeqtablePopBack(&st);
	SeqtablePopBack(&st);
	SeqtablePopBack(&st);
	printf("\n");
	//打印
	PrintSeqtable(&st);
	//头删除
	SeqtablePopFront(&st);
	printf("\n");
	//打印
	PrintSeqtable(&st);
	摧毁顺序表
	SeqListDestory(&st);
	//printf("\n");
	打印
	//PrintSeqtable(&st);
}

int main()
{
	test2();
	return 0;
}

2.Seqtable.h

Declaração de função e criação de estrutura

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
//动态顺序表
typedef struct Seqtable {
	int* data;//数据域
	int size;//个数
	int capacity;//容量
}Seqtable;

//实际上动态顺序表和静态顺序表,只有在初始化、销毁、扩容的时候不一样


//实现函数声明

//初始化函数
void InitSeqtable(Seqtable* st);

//尾插入
void BackSeqtable(Seqtable* st, int data);

//头插入
void FrontSeqtable(Seqtable* st, int data);

//尾删除
void SeqtablePopBack(Seqtable* st);

//头删除
void SeqtablePopFront(Seqtable* st);

//摧毁顺序表
void SeqtableDestory(Seqtable* st);

//打印
void PrintSeqtable(Seqtable* st);

//查找
int SearchSeqtable(Seqtable* st);
//更改
void ChangeSeqtable(Seqtable* st);


3.Seqtable.c

Código:

#define _CRT_SECURE_NO_WARNINGS
#include"动态顺序表.h"
//动态顺序表

//初始化顺序表
void InitSeqtable(Seqtable* st) {
	st->size = st->capacity = 0;
	st->data = NULL;
}
//扩容
void Expansion(Seqtable* st) {
	//1.直接扩容二倍,这样防止后序一致扩容
	int newcapacity = st->capacity = 0 ? 4 : st->capacity * 2;
	int* tmp = (int*)realloc(st->data, newcapacity * sizeof(int));
	if (tmp == NULL) {
		//表示创建失败
		perror("realloc fail\n");
		exit(-1);
	}
	//创建成功  tmp给data
	st->data = tmp;
	st->capacity = newcapacity;
}

//尾插入
void BackSeqtable(Seqtable* st, int data) {
	//判断是否满员
	if (st->size == st->capacity) {
		//满员进行扩容
		//两个方法
		//1.直接扩容二倍,这样防止后序一致扩容
		Expansion(st);
	}
	//如果没有满员,就正常使用
	st->data[st->size++] = data;
}
//头插入
void FrontSeqtable(Seqtable* st, int data) {
	//使用动态的
	if (st->size == st->capacity) {
		Expansion(st);
	}
	int end = st->size - 1;
	while (end >= 0) {
		st->data[end + 1] = st->data[end];
		--end;
	}
	st->data[0] = data;
	st->size++;
}
//尾删除
void SeqtablePopBack(Seqtable* st) {
	//尾删除,需要判断是否为空
	assert(st->size > 0);//断言判断
	st->size--;//直接元素个数减去一个就可以

}
//头删除
void SeqtablePopFront(Seqtable* st) {
	//头部删除,也要判空
	assert(st->size > 0);//断言
	//将后面的数据覆盖前面的数据
	for (int i = 0; i < st->size - 1; i++) {
		st->data[i] = st->data[i + 1];
	}
	st->size--;//size减去一个元素即可
}
//打印
void PrintSeqtable(Seqtable* st) {
	for (int i = 0; i < st->size; i++) {
		printf("%d ", st->data[i]);
	}
}
//摧毁动态顺序表
//void SeqtableDestory(Seqtable* st) {
//	//先释放空间
//	free(st->data);
//	st->data = NULL;
//	free(st);
//	st->size = st->capacity = 0;
//}
void SeqListDestory(Seqtable* ps) {
	free(ps->data);//直接释放a的空间 
	ps->data = NULL;//然后指向NULL
	ps->capacity = ps->size = 0;
}

//查找
int SearchSeqtable(Seqtable* st) {
	assert(st->size > 0);//如果为空,不用查找,直接报错
	int num = 0;
	scanf("%d", &num);//输入查找的元素
	for (int i = 0; i < st->size; i++) {
		if (st->data[i] == num) {
			return i;//找到返回下标
		}
	}
	return -1;//没找到返回-1

}

void ChangeSeqtable(Seqtable* st) {
	int num = SearchSeqtable(st);//进入查找,返回下标
	if (num == -1) {
		printf("顺序表中没有该元素,无法修改\n");
		return;
	}
	int a = 0;
	scanf("%d", &a);//输入想要更改的数据
	st->data[num] = a;
}

Resumir

Explicamos neste artigo o uso de tabelas de sequência em tabelas lineares. Implementamos tabelas de sequência estáticas e dinâmicas respectivamente, que são a base das estruturas de dados. O que explicaremos a seguir são as listas encadeadas em tabelas lineares.

Bem, este é o fim da escrita, obrigado por seu encorajamento e apoio durante este período de tempo, Xiao Wang continuará trabalhando duro para aprender o código, vamos trabalhar duro juntos! ! !

Acho que você gosta

Origin blog.csdn.net/qq_63319459/article/details/128760646
Recomendado
Clasificación