[data structure] dynamic sequence table

Keywords: C C++ data structure

1, Data structure Preface

1. Data structure: data and organization between data

2. Program (data and function composition) = data structure + algorithm

3. Time complexity

Concept: the number of execution times of a statement of an algorithm program (rather than the running time of the algorithm);

Time complexity is a function T (n). For convenience, the standard of large o representation is generally used: progressive time complexity O (f (n));

Time complexity of common algorithms:

  1. Time complexity of recursive algorithm = time complexity of single call + total recursion times
  2. Bubble sort time complexity = O(n^2)
  3. Binary search time complexity = O(log(n))
  4. Recursive Fibonacci number time complexity prime = O(2^n)

4. Space complexity

Concept: the amount of space temporarily occupied by an algorithm during operation (i.e. the newly opened space after operation);

Spatial complexity is a function S (n). For convenience, the standard of large o representation is generally used: progressive spatial complexity O (f (n));

Common complexity performance

2, Sequence table

  • Sequential table is a linear structure in which data elements are stored in sequence with a storage unit with continuous physical addresses. Generally, array storage is used. In array
    Complete data addition, deletion, query and modification on.

1. Two development methods of sequence table (data structure of sequence table)

Static sequence table

Put the data directly into a fixed length array

//Static storage of sequence table
#define N 7
struct SeqList
{
	int array[N];  //Fixed length array
	size_t size;  //Number of valid data
}

Dynamic sequence table

Dynamically open up the array on the heap and return the starting position pointer

//Dynamic storage of sequence table
struct SeqList
{
	int *array;  //A pointer is used as the starting position of the array
	size_t size;  //Number of valid data
	size_t capicticy;  //Size of space on heap
}

2. Common functions of sequence table

1) Initialize dynamic sequence table

Open up a custom length sequence table on the heap, with a minimum of three elements by default

void SeqListInit(SeqList* ps, int initCapacity)
{
	assert(ps); //Check whether the incoming address is legal
	initCapacity = initCapacity <= 0 ? 3 : initCapacity;  //Detect the second parameter. If it is illegal, three spaces are opened by default
	ps->array = (DataType*)malloc(initCapacity * sizeof(DataType));
	if (NULL == ps->array)
	{
		assert(0); //Display the cause of the error through assert
		return;
	}

	ps->capacity = initCapacity;
	ps->size = 0;
}

2) Release sequence table

Because the dynamic sequence table is opened on the heap, it needs to be released after the call to avoid memory overflow

void SeqListDestroy(SeqList* ps)
{
	assert(ps);
	if (ps->array)
	{
		free(ps->array); //The linked list memory is continuously opened up and released as a whole
		ps->array = NULL;
		ps->capacity = 0;
		ps->size = 0;
	}
}

3) Tail insertion and head insertion of sequence table

a. Before inserting the sequence table, you must check whether the space is sufficient. Customize the space detection function static void ChecKCapacity(SeqList* ps)
b. The header insert needs to move all the following elements backward in turn
c. Therefore, the tail insertion time complexity is O(1) and the head insertion time complexity is O(N)
d. Remember to add 1 to the effective size of the array after the insert operation

// Tail insertion
void SeqListPushBack(SeqList* ps, DataType data)
{
	assert(ps);
	//1. Check whether the space is sufficient
	ChecKCapacity(ps);

	//2. Insert data for the last element
	ps->array[ps->size] = data;
	ps->size++;
}
// Head insert
void SeqListPushFront(SeqList* ps, DataType data)
{
	assert(ps);
	//1. Check whether the space is sufficient
	ChecKCapacity(ps);

	//2. Move all elements back one bit as a whole
	for (int i = ps->size - 1; i >= 0; i--)
	{
		ps->array[i + 1] = ps->array[i];
	}
	//3. Insert element
	ps->array[0] = data;
	ps->size++;
}

4) Sequential table space detection function

a. It is defined as static static function to make it valid only in the program of this document
b. If the space is insufficient, the new space opened each time is twice as large as the original space (here, use the shift left < < operator to expand it by 2 times)
c. Note that after the new space is opened, the original heap space should be released

static void ChecKCapacity(SeqList* ps)
{
	assert(ps);
	if (ps->size == ps->capacity)
	{
		//Open up new space
		int newCapacity = (ps->capacity << 1); //One bit to the left is twice the size
		DataType* temp = (DataType*)malloc(newCapacity * sizeof(DataType));
		if (NULL == temp)
		{
			assert(0);
			return;
		}
		//Copy the original space value to the new space
		for (int i = 0; i < ps->size; i++)
		{
			temp[i] = ps->array[i];
		}
		//Free up original heap space
		free(ps->array);

		ps->array = temp;
		ps->capacity = newCapacity;
	}
}

5) Tail deletion and header deletion of sequence table

a. Before deleting the sequence list, you must first judge whether to operate on the empty linked list. If it is an empty list, it will jump out directly
b. To delete a header, you need to move all the following elements forward in turn
c. Therefore, the time complexity of head insertion is O(1) and the time complexity of tail insertion is O(N)
d. Remember to subtract 1 from the effective size of the array after the delete operation

// Tail deletion
void SeqListPopBack(SeqList* ps)
{
	assert(ps);
	//1. Check whether there are elements in the linked list
	if (SeqListEmpty(ps))
	{
		printf("ERROR:The sequence table has no content\n");
		return;
	}
	//2. Delete
	ps->size--; //Just change the number of legal elements without releasing the space
}
// Header deletion
void SeqListPopFront(SeqList* ps)
{
	assert(ps);
	//1. Check whether there are elements in the linked list
	if (SeqListEmpty(ps))
	{
		printf("ERROR:The sequence table has no content\n");
		return;
	}
	//2. Move all elements forward one bit as a whole
	for (int i = 0; i < ps->size; i++)
	{
		ps->array[i] = ps->array[i + 1];
	}
	ps->size--;
}

6) Insert and delete the specified position of the sequence table

Before inserting and deleting, first judge whether the pos position is within the effective length of the array

// Insert the element data in the pos position of the sequence table
// Note: the range of pos must be [0, PS - > size]
void SeqListInsert(SeqList* ps, int pos, DataType data) //pos is the subscript, starting from 0
{
	assert(ps);
	//1. Position detection
	if (pos<0 || pos>ps->size)
	{
		printf("ERROR:Insertion position out of range\n");
		return;
	}
	//2. Capacity test
	ChecKCapacity(ps);
	//3.pos element moves back one bit
	for (int i = ps->size; i >= pos; i--)
	{
		ps->array[i + 1] = ps->array[i];
	}
	//4. Insert element
	ps->array[pos] = data;
	ps->size++;
}

// The sequence table deletes the value of pos position
// Note: the range of pos must be [0, PS - > size)
void SeqListErase(SeqList* ps, int pos)  //pos is the subscript, starting from 0
{
	assert(ps);
	//1. Position detection
	if (pos<0 || pos>ps->size)
	{
		printf("ERROR:Insertion position out of range\n");
		return;
	}
	//2.pos and subsequent elements move forward one bit
	for (int i = pos; i < ps->size; i++)
	{
		ps->array[i] = ps->array[i + 1];
	}
	ps->size--;
}

7) Other functions of the sequence table

// 9. Number of effective elements
int SeqListSize(SeqList* ps)
{
	assert(ps);
	return ps->size;
}

// 10. Total space size
int SeqListCapacity(SeqList* ps)
{
	assert(ps);
	return ps->capacity;
}

// 11. Find element location
int SeqListFind(SeqList* ps, DataType data)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (data == ps->array[i])
		{
			return i;
		}
	}
	return -1;
}

// 12. Check whether the sequence table is empty
int SeqListEmpty(SeqList* ps)
{
	assert(ps);
	return 0 == ps->size;  //If it is empty, the equation is true and the return value is 1
}

// 13. Get the first element in the sequence table
DataType SeqListFront(SeqList* ps)
{
	assert(ps);
	return ps->array[0];
}

// 14. Get the last element in the sequence table
DataType SeqListBack(SeqList* ps)
{
	assert(ps);
	return ps->array[ps->size];
}

// 15. Get the element at any position in the sequence table
DataType SeqListGet(SeqList* ps, int pos)
{
	assert(ps);
	return ps->array[pos];
}

3. Sequence table summary

1) Because the sequential table is continuously opened in memory, it can be found directly when looking for data at any position

2) The header insertion and deletion of the sequence table need to move the data circularly, and the time complexity is high

3) In order to expand the capacity of the sequence table, the original data needs to traverse the new space of the copy value, which consumes a lot of energy

4) The sequence table will cause a waste of space, because the space is opened up in advance

source code

Header file

//The header file is used to declare the calling function
#pragma once

#include<stdio.h>
#include<Windows.h>
#include<malloc.h>
#include<assert.h>
#pragma warning(disable:4996)

/*
// 1.Static sequence table: the elements in the sequence table are stored in a fixed array
#define MAXSIZE 100

struct SeqList
{
	int array[MAXSIZE];
	int size;
};
*/

// 2. Dynamic sequence table: the underlying space is dynamically applied from the heap
typedef int DataType;

typedef struct SeqList
{
	DataType* array;     // Points to the starting position of the storage element space
	int capacity;   // Represents the total size of the space
	int size;       // Number of valid elements
}SeqList;


// typedef struct SeqList   SeqList;

 
// 1. Initialize dynamic sequence table
void SeqListInit(SeqList* ps, int initCapacity);

// 2. Release linked list
void SeqListDestroy(SeqList* ps);

// 3. Tail plug
void SeqListPushBack(SeqList* ps, DataType data);
// 4. Deletion
void SeqListPopBack(SeqList* ps);

// 5. Head insert
void SeqListPushFront(SeqList* ps, DataType data);
// 6. Header deletion
void SeqListPopFront(SeqList* ps);

// 7. Insert the element data in the pos position of the sequence table
// Note: the range of pos must be [0, PS - > size]
void SeqListInsert(SeqList* ps, int pos, DataType data);

// 8. Delete the value of pos position in the sequence table
// Note: the range of pos must be [0, PS - > size)
void SeqListErase(SeqList* ps, int pos);

// 9. Number of effective elements
int SeqListSize(SeqList* ps);

// 10. Total space size
int SeqListCapacity(SeqList* ps);

// 11. Find element location
int SeqListFind(SeqList* ps, DataType data);

// 12. Check whether the sequence table is empty
int SeqListEmpty(SeqList* ps);

// 13. Get the first element in the sequence table
DataType SeqListFront(SeqList* ps);

// 14. Get the last element in the sequence table
DataType SeqListBack(SeqList* ps);

// 15. Get the element at any position in the sequence table
DataType SeqListGet(SeqList* ps, int pos);
///

// Test sequence table
void TestSeqList();

Function file

#include "seqlist.h"


// Detect sequential tablespaces
static void ChecKCapacity(SeqList* ps)
{
	assert(ps);
	if (ps->size == ps->capacity)
	{
		//Open up new space
		int newCapacity = (ps->capacity << 1); //One bit to the left is twice the size
		DataType* temp = (DataType*)malloc(newCapacity * sizeof(DataType));
		if (NULL == temp)
		{
			assert(0);
			return;
		}
		//Copy the original space value to the new space
		for (int i = 0; i < ps->size; i++)
		{
			temp[i] = ps->array[i];
		}
		//Free up original heap space
		free(ps->array);

		ps->array = temp;
		ps->capacity = newCapacity;
	}
}

// Print function
static void SeqListPrint(SeqList* ps)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->array[i]);
	}
	printf("\n");
}

///
// 1. Initialize dynamic sequence table
void SeqListInit(SeqList* ps, int initCapacity)
{
	assert(ps); //Check whether the incoming address is legal
	initCapacity = initCapacity <= 0 ? 3 : initCapacity;  //Detect the second parameter. If it is illegal, three spaces are opened by default
	ps->array = (DataType*)malloc(initCapacity * sizeof(DataType));
	if (NULL == ps->array)
	{
		assert(0); //Display the cause of the error through assert
		return;
	}

	ps->capacity = initCapacity;
	ps->size = 0;
}

// 2. Release sequence table
void SeqListDestroy(SeqList* ps)
{
	assert(ps);
	if (ps->array)
	{
		free(ps->array); //The linked list memory is continuously opened up and released as a whole
		ps->array = NULL;
		ps->capacity = 0;
		ps->size = 0;
	}
}

// 3. Tail plug
void SeqListPushBack(SeqList* ps, DataType data)
{
	assert(ps);
	//1. Check whether the space is sufficient
	ChecKCapacity(ps);

	//2. Insert data for the last element
	ps->array[ps->size] = data;
	ps->size++;
}
// 4. Deletion
void SeqListPopBack(SeqList* ps)
{
	assert(ps);
	//1. Check whether there are elements in the linked list
	if (SeqListEmpty(ps))
	{
		printf("ERROR:The sequence table has no content\n");
		return;
	}
	//2. Delete
	ps->size--; //Just change the number of legal elements without releasing the space
}

// 5. Head insert
void SeqListPushFront(SeqList* ps, DataType data)
{
	assert(ps);
	//1. Check whether the space is sufficient
	ChecKCapacity(ps);

	//2. Move all elements back one bit as a whole
	for (int i = ps->size - 1; i >= 0; i--)
	{
		ps->array[i + 1] = ps->array[i];
	}
	//3. Insert element
	ps->array[0] = data;
	ps->size++;
}
// 6. Header deletion
void SeqListPopFront(SeqList* ps)
{
	assert(ps);
	//1. Check whether there are elements in the linked list
	if (SeqListEmpty(ps))
	{
		printf("ERROR:The sequence table has no content\n");
		return;
	}
	//2. Move all elements forward one bit as a whole
	for (int i = 0; i < ps->size; i++)
	{
		ps->array[i] = ps->array[i + 1];
	}
	ps->size--;
}

// 7. Insert the element data in the pos position of the sequence table
// Note: the range of pos must be [0, PS - > size]
void SeqListInsert(SeqList* ps, int pos, DataType data) //pos is the subscript, starting from 0
{
	assert(ps);
	//1. Position detection
	if (pos<0 || pos>ps->size)
	{
		printf("ERROR:Insertion position out of range\n");
		return;
	}
	//2. Capacity test
	ChecKCapacity(ps);
	//3.pos element moves back one bit
	for (int i = ps->size; i >= pos; i--)
	{
		ps->array[i + 1] = ps->array[i];
	}
	//4. Insert element
	ps->array[pos] = data;
	ps->size++;
}

// 8. Delete the value of pos position in the sequence table
// Note: the range of pos must be [0, PS - > size)
void SeqListErase(SeqList* ps, int pos)  //pos is the subscript, starting from 0
{
	assert(ps);
	//1. Position detection
	if (pos<0 || pos>ps->size)
	{
		printf("ERROR:Insertion position out of range\n");
		return;
	}
	//2.pos and subsequent elements move forward one bit
	for (int i = pos; i < ps->size; i++)
	{
		ps->array[i] = ps->array[i + 1];
	}
	ps->size--;
}

// 9. Number of effective elements
int SeqListSize(SeqList* ps)
{
	assert(ps);
	return ps->size;
}

// 10. Total space size
int SeqListCapacity(SeqList* ps)
{
	assert(ps);
	return ps->capacity;
}

// 11. Find element location
int SeqListFind(SeqList* ps, DataType data)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (data == ps->array[i])
		{
			return i;
		}
	}
	return -1;
}

// 12. Check whether the sequence table is empty
int SeqListEmpty(SeqList* ps)
{
	assert(ps);
	return 0 == ps->size;  //If it is empty, the equation is true and the return value is 1
}

// 13. Get the first element in the sequence table
DataType SeqListFront(SeqList* ps)
{
	assert(ps);
	return ps->array[0];
}

// 14. Get the last element in the sequence table
DataType SeqListBack(SeqList* ps)
{
	assert(ps);
	return ps->array[ps->size];
}

// 15. Get the element at any position in the sequence table
DataType SeqListGet(SeqList* ps, int pos)
{
	assert(ps);
	return ps->array[pos];
}
///

//Test function 1
static void Test1()
{
	SeqList s;
	SeqListInit(&s, 3); //Note that the parameter here is the address

	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPushBack(&s, 5);
	SeqListPushBack(&s, 6);
	SeqListPrint(&s);

	SeqListErase(&s, 4);
	SeqListPushFront(&s, 0);
	SeqListPrint(&s);

	printf("Sequence table significant digits:%d\n", SeqListSize(&s));
	printf("Sequential table space:%d\n", SeqListCapacity(&s));
	printf("Subscript of number 5 in sequence table:%d\n", SeqListFind(&s, 5));

	SeqListDestroy(&s);
}

//Test sequence table
void TestSeqList()
{
	Test1();
}

Main function file

#include "seqlist.h"


int main()
{
	TestSeqList();

	system("pause");
	return 0;
}


Posted by Goat on Tue, 30 Nov 2021 08:11:27 -0800