기술나눔

"데이터 구조: C 언어 구현 시퀀스 테이블"

2024-07-12

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

1. 서열표

시퀀스 테이블은 동일한 특성을 가진 n개의 데이터 요소로 구성된 제한된 시퀀스를 저장하는 데 사용되는 데이터 구조인 선형 테이블 유형입니다.
시퀀스 테이블의 저장 형태의 논리적 구조는 연속적이며, 물리적 구조도 연속적이다. 맨 아래 계층은 데이터 저장을 완료하는 배열이다.

1. 정적 시퀀스 테이블

정적 시퀀스 테이블의 공간은 고정되어 있고, 배열의 크기도 고정되어 있으며, 저장되는 데이터의 개수도 제한되어 있으므로 정적 데이터용으로 공간을 설정하면 커지고, 작으면 커지게 됩니다. 충분하지는 않지만 더 크면 공간이 낭비됩니다.

2. 동적 시퀀스 테이블

동적 시퀀스 테이블은 메모리 공간 요구에 따라 공간 크기를 조정하므로 공간 낭비가 크게 줄어듭니다. 따라서 시퀀스 테이블은 동적 시퀀스 시퀀스 형태로 구현됩니다.

2. 동적 시퀀스 테이블 구현

동적 시퀀스 테이블을 구현하면 완료할 세 개의 파일이 생성됩니다.

  • 1. 시퀀스_목록.h의 헤더 파일, 함수 선언 및 정의
  • 2. 시퀀스_리스트.c의 소스 파일은 함수의 기능을 구현합니다.
  • 3. test.c의 소스 파일은 시퀀스 테이블의 기능을 테스트하는 데 사용됩니다.

여기에 이미지 설명을 삽입하세요.

1. 사용자 정의 유형 만들기

일단 생성되면 단계별로 구현하십시오.
1. 시퀀스 목록에 사용할 사용자 정의 유형의 구조를 먼저 시퀀스_목록.h 파일에서 생성해야 합니다.

#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. 시퀀스 테이블 생성을 완료하고 기능적 요구사항을 테스트합니다.

2. test.c 파일에 시퀀스 테이블을 생성한 후 어떤 기능이 필요한지 확인한 후, 각 기능에 해당하는 기능을 구현해 보세요.

//在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. 시퀀스 테이블의 초기화 및 소멸 기능을 완료합니다.

3. 요구 사항에 따라 squence_list.h 및 squence_list.c 헤더 파일의 해당 함수 선언 및 구현을 완료합니다.

  • (1) 시퀀스 테이블 초기화
  • (2)시퀀스 테이블 파괴
#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. 시퀀스 테이블에 데이터 삽입 및 데이터 인쇄

4. 계속해서 test.c 파일을 테스트하세요.
필수 기능은 데이터를 추가하는 기능입니다
데이터를 추가하는 방법에는 세 가지가 있습니다.

  • (1) 마지막에 추가
  • (2) 헤더 추가
  • (3)어디든지 추가

데이터를 관찰해야 하며 인쇄 기능을 사용하여 달성해야 합니다.

//在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. 데이터 삭제

(1)꼬리 삭제
(2)헤더 삭제
(3) 임의의 위치에서 삭제
(4) 해당 데이터 첨자를 찾습니다.

3. 최종 코드를 완성하기 위한 시퀀스 테이블

test.c 파일의 코드: 프로그램의 타당성을 테스트하는 데 사용됩니다.
//在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
Sequence_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
시퀀스_목록.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