Partage de technologie

"Structure des données : table de séquence d'implémentation du langage C"

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. Tableau de séquence

Une table de séquence est un type de table linéaire, une structure de données utilisée pour stocker une séquence limitée de n éléments de données ayant les mêmes caractéristiques.
La structure logique de la forme de stockage de la table de séquence est continue et la structure physique est également continue. La couche inférieure est un tableau pour compléter le stockage des données.

1. Tableau de séquence statique

L'espace de la table de séquence statique est fixe, la taille du tableau est fixe et le nombre de données stockées est limité. Par conséquent, si l'espace est défini pour les données statiques, il sera plus grand et s'il est plus petit, il sera plus grand. ne suffira pas, mais s’il est plus grand, cela fera perdre de la place.

2. Tableau de séquence dynamique

La table de séquence dynamique ajuste la taille de l'espace en fonction des besoins en espace mémoire, ce qui réduit considérablement le gaspillage d'espace. Par conséquent, la table de séquence est implémentée sous la forme d'une séquence de séquence dynamique.

2. Implémentation d'une table de séquence dynamique

La mise en œuvre d'une table de séquence dynamique créera trois fichiers à compléter :

  • 1. Fichier d'en-tête de séquence_list.h, déclaration et définition de fonction
  • 2. Le fichier source de séquence_list.c implémente la fonction de la fonction
  • 3. Le fichier source de test.c est utilisé pour tester le fonctionnement de la table de séquence

Insérer la description de l'image ici

1. Créez un type personnalisé

Une fois créé, implémentez-le étape par étape
1. Dans le fichier séquence_list.h, vous devez d'abord créer un type de structure personnalisé à utiliser dans la liste de séquences.

#pragma once
//sequence_list.h文件中

#include<stdio.h>

//顺序表存放数据的类型
typedef int SLDATETYPE;

//顺序表的类型创建
typedef struct SequenceList
{
	//存放指定类型数据的指针
	SLDATETYPE* a;

	//存放数据的有效个数
	int count;

	//属性表空间大小
	int size;
}SL;//重命名一个简单的名字
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
2. Terminez la création de la table de séquence et testez les exigences fonctionnelles

2. Créez une table de séquence dans le fichier test.c, puis vérifiez quelles fonctions sont nécessaires, puis implémentez les fonctions correspondant à chaque fonction.

//在test.c文件中

//1、首先包含头文件
#include"sequence_list.h"

//3、测试函数test1的任务
void test1()
{
	//4、创建一个顺序表
	SL s;

	//5、顺序表没有初始化需要初始化
	SLInitialize(&s);//传址调用

	//6、最后不使用时要完成销毁
	SLDestroy(&s);
}

//2、创建主函数
int main()
{
	//调用测试函数
	test1();
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
3. Complétez les fonctions d'initialisation et de destruction de la table de séquence

3. Complétez la déclaration de fonction correspondante et l'implémentation des fichiers d'en-tête de squence_list.h et squence_list.c selon les exigences.

  • (1) Initialisation de la table de séquence
  • (2) Destruction de la table de séquence
#pragma once
//sequence_list.h文件中
//包含检查头文件
#include<assert.h>

//动态内存开辟函数对应的头文件
#include<stdlib.h>

//顺序表的初始化
void SLInitialize(SL* ps);

//顺序表的销毁
void SLDestroy(SL* ps);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
//在squence_list.c文件中

//包含头文件
#include"sequence_list.h"

//顺序表的初始化
void SLInitialize(SL* ps)
{
	//对顺序表检查
	//要添加对应的<assert.h>头文件
	//在sequence_list.h头文件包含就可以了
	assert(ps != NULL);
	ps->a = NULL;
	ps->count = ps->size = 0;
}

//顺序表的销毁
void SLDestroy(SL* ps)
{
	assert(ps != NULL);
	
	//动态内存开辟的空间要free
	//动态内存开辟函数要添加头文件<stdlib.h>

	free(ps->a);
	ps->a = NULL;
	ps->count = ps->size = 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
4. Insérer des données et imprimer des données dans la table de séquence

4. Continuez à tester le fichier test.c
La fonction requise est une fonction qui ajoute des données
Il existe trois manières d'ajouter des données :

  • (1)Ajouter à la fin
  • (2) Ajout d'en-tête
  • (3)Ajouter n'importe où

Besoin d'observer les données, utilisez la fonction d'impression pour réaliser

//在test.c文件中

//1、首先包含头文件
#include"sequence_list.h"

//3、测试函数test1的任务
void test1()
{
	//4、创建一个顺序表
	SL s;

	//5、顺序表没有初始化需要初始化
	SLInitialize(&s);//传址调用

	//添加数据
	//7、尾部添加数据
	SLPutEnd(&s, 1);
	SLPutEnd(&s, 2);
	SLPutEnd(&s, 3);

	//8、打印数据
	SLPrint(&s);

	//9、头部插入
	SLPutFirst(&s, 5);
	SLPutFirst(&s, 4);

	SLPrint(&s);

	//10、任意位置前插入数据
	SLInsert(&s, 0, 3);
	SLInsert(&s, s.count-1, 6);
	SLInsert(&s, 1, 6);
	SLPrint(&s);

	
	//6、最后不使用时要完成销毁
	SLDestroy(&s);
}

//2、创建主函数
int main()
{
	//调用测试函数
	test1();
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
//sequence_list.h文件中

//判断空间是否足够
void SLEnough(SL* ps)
{
	//空间满了申请空间
	if (ps->count == ps->size)
	{
		int n;
		n = (ps->size == 0 ? 4 : ps->size * 2);
		SLDATETYPE* tmp = (SLDATETYPE*)realloc(ps->a,n * sizeof(SLDATETYPE));
		if (tmp == NULL)
		{
			//开辟失败退出
			exit(1);
		}
		ps->a = tmp;
		tmp = NULL;
		ps->size = n;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

//顺序表末尾放置数据
void SLPutEnd(SL* ps, SLDATETYPE x)
{
	assert(ps != NULL);
	//判断空间是否足够容纳数据
	SLEnough(ps);
	ps->a[ps->count++] = x;
}


//打印顺序表中的数据
void SLPrint(SL* ps)
{
	assert(ps != NULL);
	int i = 0;
	for (i = 0; i < ps->count; i++)
	{
		printf("%d", ps->a[i]);
	}
	printf("n");
}

//顺序表头部插入数据
void SLPutFirst(SL* ps, SLDATETYPE x)
{
	assert(ps != NULL);
	SLEnough(ps);
	for (int i = ps->count; i > 0; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[0] = x;
	ps->count++;
}

//顺序表任意位置前插入数据
void SLInsert(SL* ps, int pos, SLDATETYPE x)
{
	assert(ps != NULL);
	assert(pos >= 0 && pos <= ps->count);
	SLEnough(ps);
	for (int i = ps->count; i > pos; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[pos] = x;
	ps->count++;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
5. Supprimer les données

(1)Suppression de la queue
(2)Suppression d'en-tête
(3) Supprimer à n'importe quel endroit
(4) Trouver l'indice de données correspondant

3. Tableau de séquence pour compléter le code final

Code dans le fichier test.c : utilisé pour tester la faisabilité du programme
//在test.c文件中

//1、首先包含头文件
#include"sequence_list.h"

//3、测试函数test1的任务
void test1()
{
	//4、创建一个顺序表
	SL s;

	//5、顺序表没有初始化需要初始化
	SLInitialize(&s);//传址调用

	//添加数据
	//7、尾部添加数据
	SLPutEnd(&s, 1);
	SLPutEnd(&s, 2);
	SLPutEnd(&s, 3);


	//8、打印数据
	//SLPrint(&s);

	//9、头部插入
	SLPutFirst(&s, 4);

	//SLPrint(&s);

	//10、任意位置前插入数据
	SLInsert(&s, 0, 5);
	SLInsert(&s, 0, 6);
	
	SLPrint(&s);

	//11、尾部删除数据
	SLDeleteEnd(&s);

	//l2、头部删除数据
	SLDeleteFirst(&s);

	//13、任意位置删除数据
	SLDelete(&s, 0);

	SLPrint(&s);
	//14、查找数据对应下标
	int ret=SLFind(&s, 6);
	if (ret >= 0)
	{
		printf("找到了,下标为%dn",ret);
	}
	else
		printf("没有找到");
	//6、最后不使用时要完成销毁
	SLDestroy(&s);
}

//2、创建主函数
int main()
{
	//调用测试函数
	test1();
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
Fichier d'en-tête séquence_list.h :
#pragma once
//sequence_list.h文件中

#include<stdio.h>

//包含检查头文件
#include<assert.h>

//动态内存开辟函数对应的头文件
#include<stdlib.h>


//顺序表存放数据的类型
typedef int SLDATETYPE;

//顺序表的类型创建
typedef struct SequenceList
{
	//存放指定类型数据的指针
	SLDATETYPE* a;

	//存放数据的有效个数
	int count;

	//属性表空间大小
	int size;
}SL;//重命名一个简单的名字


//顺序表的初始化
void SLInitialize(SL* ps);

//顺序表的销毁
void SLDestroy(SL* ps);

//判断空间是否足够
void SLEnough(SL* ps);

//顺序表末尾放置数据
void SLPutEnd(SL* ps, SLDATETYPE x);

//打印顺序表中的数据
void SLPrint(SL* ps);

//顺序表头部插入数据
void SLPutFirst(SL* ps, SLDATETYPE x);

//顺序表任意位置前插入数据
void SLInsert(SL* ps, int pos, SLDATETYPE x);

//顺序表尾删
void SLDeleteEnd(SL* ps);

//顺序表头删
void SLDeleteFirst(SL* ps);

//顺序表任意位置删除数据
void SLDelete(SL* ps, int pos);

//顺序表中寻找对应数据下标
int SLFind(SL* ps, SLDATETYPE x);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
fichier séquence_list.c :
#define _CRT_SECURE_NO_WARNINGS 1

//在squence_list.c文件中

//包含头文件
#include"sequence_list.h"

//顺序表的初始化
void SLInitialize(SL* ps)
{
	//对顺序表检查
	//要添加对应的<assert.h>头文件
	//在sequence_list.h头文件包含就可以了
	assert(ps != NULL);
	ps->a = NULL;
	ps->count = ps->size = 0;
}

//顺序表的销毁
void SLDestroy(SL* ps)
{
	assert(ps != NULL);
	
	//动态内存开辟的空间要free
	//动态内存开辟函数要添加头文件<stdlib.h>

	free(ps->a);
	ps->a = NULL;
	ps->count = ps->size = 0;
}

//判断空间是否足够
void SLEnough(SL* ps)
{
	//空间满了申请空间
	if (ps->count == ps->size)
	{
		int n;
		n = (ps->size == 0 ? 4 : ps->size * 2);
		SLDATETYPE* tmp = (SLDATETYPE*)realloc(ps->a,n * sizeof(SLDATETYPE));
		if (tmp == NULL)
		{
			//开辟失败退出
			exit(1);
		}
		ps->a = tmp;
		tmp = NULL;
		ps->size = n;
	}
}

//顺序表末尾放置数据
void SLPutEnd(SL* ps, SLDATETYPE x)
{
	assert(ps != NULL);
	//判断空间是否足够容纳数据
	SLEnough(ps);
	ps->a[ps->count++] = x;
}


//打印顺序表中的数据
void SLPrint(SL* ps)
{
	assert(ps != NULL);
	int i = 0;
	for (i = 0; i < ps->count; i++)
	{
		printf("%d", ps->a[i]);
	}
	printf("n");
}

//顺序表头部插入数据
void SLPutFirst(SL* ps, SLDATETYPE x)
{
	assert(ps != NULL);
	SLEnough(ps);
	for (int i = ps->count; i > 0; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[0] = x;
	ps->count++;
}

//顺序表任意位置前插入数据
void SLInsert(SL* ps, int pos, SLDATETYPE x)
{
	assert(ps != NULL);
	assert(pos >= 0 && pos <= ps->count);
	SLEnough(ps);
	for (int i = ps->count; i > pos; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[pos] = x;
	ps->count++;
}

//顺序表尾删
void SLDeleteEnd(SL* ps)
{
	assert(ps != NULL);
	if (ps->count == 0)
	{
		printf("数据已经删完了n");
	}
	else
	{
		ps->count--;
		printf("删除成功n");
	}
}

//顺序表头删
void SLDeleteFirst(SL* ps)
{
	assert(ps != NULL);
	if (ps->count == 0)
	{
		printf("数据已经删完了n");
	}
	else
	{
		for (int i = 0; i < ps->count - 1; i++)
		{
			ps->a[i] = ps->a[i + 1];
		}
		ps->count--;
		printf("删除成功n");
	}
}

//顺序表任意位置删除数据
void SLDelete(SL* ps, int pos)
{
	assert(ps != NULL);
	assert(pos >= 0 && pos <= ps->count);
	if (ps->count == 0)
	{
		printf("数据已经删完了n");
	}
	else
	{
		for (int i = pos; i < ps->count - 1; i++)
		{
			ps->a[i] = ps->a[i + 1];
		}
		ps->count--;
		printf("删除成功n");
	}
}

//顺序表中寻找对应数据下标
int SLFind(SL* ps, SLDATETYPE x)
{
	assert(ps != NULL&&ps->a != NULL);
	for (int i = 0; i < ps->count; i++)
	{
		if (ps->a[i] == x)
		{
			return 1;
		}
	}
	return -1;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167