Addition, deletion, query and modification of the sequence table of the primary data structure (2)


foreword

The meaning of the linear table:

A linear list is a finite sequence of n data elements with the same properties. A linear table is a data structure widely used in practice
. Common linear tables: sequence 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.

insert image description here


1. Sequence table

1.1 The concept of sequence table

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.

1.2 Classification of sequence table

Static sequence table: use fixed-length array to store elements

typedef int SLDatatype;
#define N 10
typedef int SLDatatype;
struct SeqList
{
    
    
	SLDatatype a[N];
	int size;
};

Dynamic sequence table: use dynamically opened array storage

typedef int SLDatatype;
typedef struct SeqList
{
    
    
	SLDatatype* a;
	int size;		//存储的有效数据个数
	int capacity;	//容量
}SL;

1.3. Interface definition of sequence table

1. Initialization of the sequence table

void SLInit(SL* psl)
{
    
    
	psl->a = (SLDatatype*)malloc(sizeof(SLDatatype) * 4);
	if (psl->a == NULL)
	{
    
    
		perror("malloc fail");
		return;
	}
	psl->capacity = 4;
	psl->size = 0;
}

First of all, we dynamically open up a space in the memory, and set the initial storage capacity to 4, psl->size actually means the subscript!

2. Destruction of the sequence table

void SLDestroy(SL* psl)
{
    
    
	free(psl->a);
	psl->a = NULL;
	psl->capacity = psl->size = 0;
}

First open up the data on the heap, we use the free statement in the c language to release, and then let the capacity and size become 0, so that the destruction is successful!

3. Printing of the sequence table

void SLPrint(SL* psl)
{
    
    
	int i = 0;
	for (i = 0; i < psl->size; i++)
	{
    
    
		printf("%d ", psl->a[i]);
	}
	printf("\n");
}

First of all, the principle of the sequence table is actually quite similar to that of an array. It is a storage unit with continuous physical addresses that stores data elements in sequence, so we can imagine the traversal of the array when printing. psl->size is the number of elements in the array. We only need You need to use a for loop to print it out.

4. Dynamic expansion in the array

void SLCheckCapacity(SL* psl)
{
    
    
	assert(psl);
	if (psl->capacity == psl->size)
	{
    
    
		SLDatatype* tmp = (SLDatatype*)realloc(psl->a, sizeof(SLDatatype) * 2 * psl->capacity);
		if (tmp == NULL)
		{
    
    
			perror("realloc fail");
			return;
		}
		psl->a = tmp;
		psl->capacity *= 2;
	}
}

First, when the number of elements is the same as the size of the array, we can dynamically increase the capacity of psl->a realloc. First, realloc has two parameters, one is the address to be increased, and the other is the size of the increase. After we increase the capacity, we assign the increased value to the original address of psl->a, and double the size of the array.

5. Tail insertion of sequence table

void SLPushBack(SL* psl, SLDatatype x)
{
    
    
	SLCheckCapacity(psl);//检查是否需要扩容
	psl->a[psl->size] = x;
	psl->size++;
}

We can see from the figure that the tail insertion of the sequence table only needs to find the position in psl->size, and at this position, we can insert the corresponding number.

insert image description here

6. Head plug of sequence table

void SLPushFront(SL* psl, SLDatatype x)
{
    
    
	assert(psl->size);
	SLCheckCapacity(psl);
	int end = psl->size - 1;
	while (end >= 0)
	{
    
    
		psl->a[end + 1] = psl->a[end];
		end--;
	}
	psl->a[0] = x;
	psl->size++;
}

First of all, if the plug is moved from the front to the back, it will overwrite the numbers in the back, so what should we do? We should move from the back to the front so that the numbers in each position will not be affected. We first find the subscript of the last number, and then move from back to front, as shown in the figure below, at this time the first position is empty, we can insert the number we want to insert, remember our data After adding one, our size will also increase by one, so we need psl->size++ in the end!


7. End deletion of sequence table

void SLPopBack(SL* psl)
{
    
    
	assert(psl->size > 0);
	psl->size--;
}

If the tail is deleted, we can directly delete psl->size with a little violence!

8. Delete the header of the sequence table

void SLPopFront(SL* psl)
{
    
    
	assert(psl->size > 0);
	int start = 0;
	while (start < psl->size - 1)
	{
    
    
		psl->a[start] = psl->a[start + 1];
		start++;
	}
	psl->size--;
}

If the head is deleted, we will move forward from the beginning, and finally remember that we have lost one data, remember psl->size-oh!

9. Insertion of sequence table

void SLInsert(SL* psl, int pos, SLDatatype x)
{
    
    
	assert(pos >= 0 && pos <= psl->size);
	SLCheckCapacity(psl);
	int cur = psl->size - 1;
	while (pos <= cur)
	{
    
    
		psl->a[cur + 1] = psl->a[cur];
		cur--;
	}
	psl->a[pos] = x;
	psl->size++;
}

10. Deletion of sequence table

void SLErase(SL* psl, int  pos)
{
    
    
	assert(pos >= 0 && pos < psl->size);
	int end = pos + 1;
	while (pos <= psl->size)
	{
    
    
		psl->a[pos] = psl->a[pos + 1];
		pos++;
	}
	psl->size--;
}

11. Search of sequence table

int SLFind(SL* psl, SLDatatype x)
{
    
    
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
    
    
		if (psl->a[i] == x)
			return i;
	}
	return -1;
}

12. Modification of sequence table

void Modify(SL* psl, int pos, SLDatatype x)
{
    
    
	assert(psl);
	psl->a[pos] = x;
}

2. The complete realization of the sequence table

2.1 Completion and implementation of the code

seqlist.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Seqlist.h"
//void SLInit(SL* psl)
//{
    
    
//	psl->a = NULL;
//	psl->capacity = 0;
//	psl->size = 0;
//}
void SLInit(SL* psl)
{
    
    
	psl->a = (SLDatatype*)malloc(sizeof(SLDatatype) * 4);
	if (psl->a == NULL)
	{
    
    
		perror("malloc fail");
		return;
	}
	psl->capacity = 4;
	psl->size = 0;
}
void SLDestroy(SL* psl)
{
    
    
	free(psl->a);
	psl->a = NULL;
	psl->capacity = psl->size = 0;
}

void SLCheckCapacity(SL* psl)
{
    
    
	assert(psl);
	if (psl->capacity == psl->size)
	{
    
    
		SLDatatype* tmp = (SLDatatype*)realloc(psl->a, sizeof(SLDatatype) * 2 * psl->capacity);
		if (tmp == NULL)
		{
    
    
			perror("realloc fail");
			return;
		}
		psl->a = tmp;
		psl->capacity *= 2;
	}
}

void SLPrint(SL* psl)
{
    
    
	int i = 0;
	for (i = 0; i < psl->size; i++)
	{
    
    
		printf("%d ", psl->a[i]);
	}
	printf("\n");
}

void SLPushBack(SL* psl, SLDatatype x)
{
    
    
	SLCheckCapacity(psl);
	psl->a[psl->size] = x;
	psl->size++;
}
void SLPushFront(SL* psl, SLDatatype x)
{
    
    
	assert(psl->size);
	SLCheckCapacity(psl);
	int end = psl->size - 1;
	while (end >= 0)
	{
    
    
		psl->a[end + 1] = psl->a[end];
		end--;
	}
	psl->a[0] = x;
	psl->size++;
}
void SLPopBack(SL* psl)
{
    
    
	assert(psl->size > 0);
	psl->size--;
}
void SLPopFront(SL* psl)
{
    
    
	assert(psl->size > 0);
	int start = 0;
	while (start < psl->size - 1)
	{
    
    
		psl->a[start] = psl->a[start + 1];
		start++;
	}
	psl->size--;
}

void SLInsert(SL* psl, int pos, SLDatatype x)
{
    
    
	assert(pos >= 0 && pos <= psl->size);
	SLCheckCapacity(psl);
	int cur = psl->size - 1;
	while (pos <= cur)
	{
    
    
		psl->a[cur + 1] = psl->a[cur];
		cur--;
	}
	psl->a[pos] = x;
	psl->size++;
}
void SLErase(SL* psl, int  pos)
{
    
    
	assert(pos >= 0 && pos < psl->size);
	int end = pos + 1;
	while (pos <= psl->size)
	{
    
    
		psl->a[pos] = psl->a[pos + 1];
		pos++;
	}
	psl->size--;
}

int SLFind(SL* psl, SLDatatype x)
{
    
    
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
    
    
		if (psl->a[i] == x)
			return i;
	}
	return -1;
}
void Modify(SL* psl, int pos, SLDatatype x)
{
    
    
	assert(psl);
	psl->a[pos] = x;
}

seqlist.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//#define N 10
//typedef int SLDatatype;
//struct SeqList
//{
    
    
//	SLDatatype a[N];
//	int size;
//};
typedef int SLDatatype;
typedef struct SeqList
{
    
    
	SLDatatype* a;
	int size;		//存储的有效数据个数
	int capacity;	//容量
}SL;

void SLInit(SL* psl);
void SLDestroy(SL* psl);

void SLPrint(SL* psl);

void SLPushBack(SL* psl, SLDatatype x);
void SLPushFront(SL* psl, SLDatatype x);
void SLPopBack(SL* psl);
void SLPopFront(SL* psl);

void SLInsert(SL* psl, int pos, SLDatatype x);
void SLErase(SL* psl, int  pos);

int SLFind(SL* psl, SLDatatype x);
void Modify(SL * psl, int pos, SLDatatype x); 

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
//#define INT_PTR int*
//typedef int* int_ptr;
//
//#define N 4
//#define Y(n) ((N+2)*n) ((6) * 5 + 1)
//
//INT_PTR a, b;
//int_ptr c, d;
//int main()
//{
    
    
//	int z = 2 * (N + Y(5 + 1));
//	return 0;
//}
//
//#include<stddef.h>
struct S
{
    
    
	int a;
	char c;
	double d;
};

#define OFFSETOF(type,name)   (size_t)&(((type*)0)->name) 

int main()
{
    
    
	struct S s;
	printf("%d\n", OFFSETOF(struct S, a));
	printf("%d\n", OFFSETOF(struct S, c));
	printf("%d\n", OFFSETOF(struct S, d));
	return 0;
}
//
#define SWAP_BIT(x)  (x = (((x & 0x55555555) << 1) + ((x & 0xaaaaaaaa) >> 1)))

int main()
{
    
    
	int a = 5;
	SWAP_BIT(a);
	printf("%d", a);
	return 0;
}
//
//void Func1()
//{
    
    
//	int a = 0;
//	printf("%p\n", &a);
//}
//
//void Func2()
//{
    
    
//	int b = 0;
//	printf("%p\n", &b);
//}
//
//int main()
//{
    
    
//	Func1();
//	Func2();
//
//
//	return 0;
//}


#include"Seqlist.h"

void test1()
{
    
    
	SL s;
	SLInit(&s);
	SLPushBack(&s, 1);
	SLPushBack(&s, 2);
	SLPushBack(&s, 3);
	SLPushBack(&s, 4);
	SLPrint(&s);
	SLPushFront(&s, 5);
	SLPushFront(&s, 4);
	SLPushFront(&s, 3);
	SLPushFront(&s, 2);
	SLPrint(&s);
	SLDestroy(&s);
}
void test2()
{
    
    
	SL s;
	SLInit(&s);
	SLPushBack(&s, 1);
	SLPushBack(&s, 2);
	SLPushBack(&s, 3);
	SLPushBack(&s, 4);
	SLPrint(&s);
	SLInsert(&s, 3, 6);
	SLInsert(&s, 2, 4);
	SLPrint(&s);
	SLErase(&s, 2);
	SLPrint(&s);
	SLDestroy(&s);
}

void test3()
{
    
    
	SL s;
	SLInit(&s);
	SLPushBack(&s, 1);
	SLPushBack(&s, 2);
	SLPushBack(&s, 3);
	SLPushBack(&s, 4);
	/*int pos = SLFind(&s, 2);
	printf("%d\n", pos);*/
	Modify(&s, 1, 5);
	SLPrint(&s);
	SLDestroy(&s);
}
int main()
{
    
    
	test3();
	return 0;
}

Summarize

This is the end of the implementation of the sequence table this time, this is the beginning of sharing! Please continue to follow me!

Guess you like

Origin blog.csdn.net/m0_64361522/article/details/130309793