[Data structure and algorithm] Realize the static and dynamic sequence table in the linear table

This article is the beginning of the data structure. Above, we learned about the use of C language to implement static, dynamic, and file operations in the address book. The type of structure is used in it. In fact, it can belong to the content of the data structure. Next, we will come to Learn about the sequence table.


Table of contents

foreword

1. Linear table

1. What is the sequence table?

Second, the realization of the analysis sequence table

3. Static sequence table

1. Sequence table initialization

2. Add elements

1. Tail plug

2. Plug

3. Delete elements

1. Tail deletion

2. Head delete

4. Change data and lookup

5. Print and destroy sequence table

4. Dynamic Sequence Table

1. Initialization

2. Expansion

3. Destruction sequence table

5. Complete code demo

1. Static sequence table

1.test.c

2.Seqtable.h

3.Seqtable.c

2. Dynamic sequence table

1.test.c

2.Seqtable.h

3.Seqtable.c

Summarize


foreword

What are data structures?

For everyone, this is a brand new content module. Data structure is the way computers store and organize data . A data structure is a collection of data elements that have one or more specific relationships with each other . Often, well-chosen data structures can lead to higher operational or storage efficiency . Data structures are often associated with efficient retrieval algorithms and indexing techniques.

Next, we will explain the implementation of the sequence table of the data structure


1. Linear table

A linear list is a finite sequence of n data elements with the same properties. Linear table is a data structure widely used in practice, common linear table: sequential list, linked list, stack, queue, string...

A linear table is logically a linear structure, that is to say, a continuous straight line. However, the physical structure is not necessarily continuous. When the linear table is physically stored, it is usually stored in the form of an array and a chain structure.

In fact, after learning the sequence table and linked list, it is easy to learn various structures such as stacks, queues, and binary trees. They are also called sequence tables and linked lists. They are the basis of data structures and the basis for realizing post-sequence content.

1. What is the sequence table?

1. Store the elements in the table one by one in a group of continuous storage units . This storage structure is a sequential structure .

2. A linear table stored in a sequential structure is called a sequential table

Summarize:

The sequence table is a linear structure in which data elements are sequentially stored in a storage unit with continuous physical addresses, and is generally stored in an array. Add, delete, check and modify data on the array.

Second, the realization of the analysis sequence table

The sequence table is divided into dynamic and static sequence tables. The actual operation functions of the sequence table are roughly, adding, deleting, modifying and checking, and subdivided into operations such as head and tail adding and deleting, initialization, and destroying the sequence table.

Let's introduce how the static and dynamic sequence tables are implemented next! ! !

3. Static sequence table

The structure used is:

1. Sequence table initialization

as the picture shows:

Code demo:

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

2. Add elements

Divided into head insertion and tail insertion

1. Tail plug

as the picture shows:

Code demo:

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

2. Plug

as the picture shows:

 code show as below:

//头插入
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. Delete elements

Divided into head deletion and tail deletion

1. Tail deletion

as the picture shows:

 code show as below:

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

}

2. Head delete

as the picture shows:

 code show as below:

//头删除
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. Change data and lookup

If you want to change the data of the specified subscript, enter the element you want to find, and change the data, you must first find the corresponding coordinates, change the value easily, do not consider the problem of duplication, and query in order from left to right

code show as below:

//查找
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. Print and destroy sequence table

code show as below:

//摧毁顺序表
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. Dynamic Sequence Table

The difference between a dynamic sequence table and a static sequence table is the structure, initialization, destruction of the sequence table, and expansion

The structure is as follows:

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

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

1. Initialization

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

2. Expansion

as the picture shows: 

Code demo:

//扩容
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;
}

As shown in the figure, another expansion method can be found in this article on dynamic address book expansion, which contains an introduction (24 messages) [C language] Use C language to realize static and dynamic address book (easy to understand)_小Wang Xuecode's Blog - CSDN Blog

3. Destruction sequence table

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

In addition, it is almost the same as the static sequence table

5. Complete code demo

1. Static sequence table

The so-called static means that the maximum number of storage elements in the sequence table cannot be changed, there may be a lot left, or it may not be enough

1.test.c

The use of the main function

#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

Use of header files

#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

function implementation

#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. Dynamic sequence table

The so-called dynamic is to use functions such as realloc to dynamically open up space, and try to make the space of the sequence table reasonable.

1.test.c

Main function to test and use sequence table

#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

Function declaration and structure creation

#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

Code:

#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;
}

Summarize

We have explained in this article the use of sequence tables in linear tables. We have implemented static and dynamic sequence tables respectively, which are the basis of data structures. What we will explain next is linked lists in linear tables.

Well, this is the end of the writing, thank you for your encouragement and support during this period of time, Xiao Wang will continue to work hard to learn the code, let's work hard together! ! !

Guess you like

Origin blog.csdn.net/qq_63319459/article/details/128760646