Linear Table-Sequence Table Part Knowledge Induction and Implementation of Interfaces in Dynamic Storage (C Language)

Posted by JonathanS on Tue, 23 Jul 2019 11:42:48 +0200

Linear table:

_linear table is the most basic, simple and commonly used data structure. A linear table is a finite sequence of N data elements with the same characteristics, which is widely used in practice.
_linear table is logically linear structure, that is to say, a continuous straight line, but it is not necessarily continuous in physical structure. When stored in physical structure, it is usually stored in the form of array and chain structure. The relationship between data elements in a linear table is one-to-one, that is, all data elements except the first and last data elements are end-to-end (note that this sentence only applies to most linear tables, not all of them). For example, a circular linked list is also a linear table at the logical level (the storage level belongs to chain storage), but it points the tail pointer of the last data element to the first node.
_Common linear lists are sequence list, linked list, stack, queue, string, etc.

Sequence table:

_Sequential table is a linear table stored in computer memory in the form of arrays. Sequential storage of linear table is to store the elements of linear table sequentially with a set of memory cells with successive addresses, so that the adjacent data elements in the linear table can be stored in adjacent physical storage units logically, that is, through numbers. According to the adjacent relationship of physical storage of elements, the logical adjacent relationship between data elements is reflected. Linear tables with sequential storage structure are usually called sequential tables. Sequence table is to store the nodes in the table in succession in a set of memory cells with continuous addresses in the computer memory.

The order table is divided into:

  1. Static Sequence Table: Store with a fixed-length array
// Static Storage of Sequence Table
#define N 4
typedef int SLDataType;
typedef struct SeqList
{
   SLDataType array[N]; // Fixed-length array
   size_t size; // Number of valid data
}SeqList;
  1. Dynamic Sequence List: Storage with dynamically opened arrays
// Dynamic Storage of Sequence Table
typedef struct SeqList
{
	SLDataType* array; // Array pointing to dynamic pioneering
	size_t size ; // Number of valid data
	size_t capacity ; // Size of capacity space
}SeqList;

Interface implementation:

_Because the static sequential table is only applicable to scenarios where we have determined how many data we need to store, if the setting of N in the static sequential table is too large, it will lead to waste of space, and if the setting of N is too small, it will lead to insufficient space. So in practice, we use dynamic sequential table more and move according to need. The space size is allocated by the state, so the dynamic storage of the sequence table is only implemented below.

_We mainly implement the following 16 interfaces (basic + extension + extension):

// Basic add-delete check-modify interface 
1. void SeqListInit(SeqList* psl, size_t capacity); //Initialization

2. void SeqListDestory(SeqList* psl); //Destruction

3. void CheckCapacity(SeqList* psl); //Capacity expansion

4. void SeqListPushBack(SeqList* psl, SLDataType x); //Tail insertion

5. void SeqListPopBack(SeqList* psl); //Tail deletion

6. void SeqListPushFront(SeqList* psl, SLDataType x); //Head insertion

7. void SeqListPopFront(SeqList* psl); //Header deletion

8. int SeqListFind(SeqList* psl, SLDataType x); //lookup

9. void SeqListInsert(SeqList* psl, size_t pos, SLDataType x); //Fixed-point insertion

10. void SeqListErase(SeqList* psl, size_t pos); //Fixed-point deletion

11. void SeqListRemove(SeqList* psl, SLDataType x); //Delete the specified number

12. void SeqListModify(SeqList* psl, size_t pos, SLDataType x); //modify

13. void SeqListPrint(SeqList* psl); //Printing

// Expanding the Implementation of Interview Questions 
14. void SeqListBubbleSort(SeqList* psl); //Bubble sort

15. int SeqListBinaryFind(SeqList* psl, SLDataType x); //Binary search

// Requirements: Time Complexity: O(N) Space Complexity O(1) 
16. void SeqListRemoveAll(SeqList* psl, SLDataType x); //Delete all specified numbers

_Next we implement these 16 interfaces separately:

  1. Initialization
void SeqListInit(SeqList* psl, size_t capacity); //Initialization
{
	assert(psl);
	assert(capacity != 0);
	psl->capacity = capacity;
	psl->array = (SLDataType *)malloc(sizeof(SLDataType) * psl->capacity);
	psl->size = 0;
	assert(psl->array);
}
  1. Destruction
void SeqListDestory(SeqList* psl); //Destruction
{
	assert(psl);
	free(psl->array);
	psl->size = 0;
	psl->capacity = 0;
}
  1. Capacity expansion
void CheckCapacity(SeqList* psl); //Capacity expansion
{
	assert(psl);
	if (psl->size == psl->capacity)
	{
		psl->capacity *= 2;
		realloc(psl->array, sizeof(SLDataType)* psl->capacity);
	}
}
  1. Tail insertion
void SeqListPushBack(SeqList* psl, SLDataType x); //Tail insertion
{
	assert(psl);
	CheckCapacity(psl);
	psl->array[psl->size] = x;
	psl->size++;
}
  1. Tail deletion
void SeqListPopBack(SeqList* psl); //Tail deletion
{
	assert(psl);
	assert(psl->size > 0);
	psl->size--;
}
  1. Head insertion
void SeqListPushFront(SeqList* psl, SLDataType x); //Head insertion
{
	assert(psl);
	CheckCapacity(psl);
	for (int i = psl->size; i > 0; i--)
	{
		psl->array[i] = psl->array[i - 1];
	}
	psl->array[0] = x;
	psl->size++;
}
  1. Header deletion
void SeqListPopFront(SeqList* psl); //Header deletion
{
	assert(psl);
	assert(psl->size > 0);
	for (int i = 1; i < psl->size; i++)
	{
		psl->array[i - 1] = psl->array[i];
	}
	psl->size--;
}
  1. lookup
int SeqListFind(SeqList* psl, SLDataType x); //lookup
{
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
		if (psl->array[i] == x)
		{
			return i;
		}
	}
	return -1;
}
  1. Fixed-point insertion
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x); //Fixed-point insertion
{
	assert(psl);
	assert((pos >= 0) && (pos <= psl->size));
	CheckCapacity(psl);
	for (int i = psl->size; i>pos; i--)
	{
		psl->array[i] = psl->array[i - 1];
	}
	psl->array[pos] = x;
	psl->size++;
}
  1. Fixed-point deletion
void SeqListErase(SeqList* psl, size_t pos); //Fixed-point deletion
{
	assert(psl);
	assert((pos >= 0) && (pos < psl->size));
	for (int i = pos + 1; i < psl->size; i++)
	{
		psl->array[i - 1] = psl->array[i];
	}
	psl->size--;
}
  1. Delete the specified number
void SeqListRemove(SeqList* psl, SLDataType x); //Delete the specified number
{
	assert(psl);
	int pos = SeqListFind(psl, x);
	if (pos != -1)
	{
		SeqListErase(psl, pos);
	}
}
  1. modify
void SeqListModify(SeqList* psl, size_t pos, SLDataType x); //modify
{
	assert(psl);
	assert((pos >= 0) && (pos < psl->size));
	psl->array[pos] = x;
}
  1. Printing
void SeqListPrint(SeqList* psl); //Printing
{
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
		printf("%d ", psl->array[i]);
	}
	printf("\n");
}
  1. Bubble sort
void SeqListBubbleSort(SeqList* psl); //Bubble sort
{
	assert(psl);
	for (int i = 1; i < psl->size; i++)
	{
		int out = 1;
		for (int j = 0; j < psl->size - i; j++)
		{
			if (psl->array[j] > psl->array[j + 1])
			{
				int t = psl->array[j];
				psl->array[j] = psl->array[j + 1];
				psl->array[j + 1] = t;
				out = 0;
			}
		}
		if (out == 1)
		{
			return;
		}
	}
}
  1. Binary search
int SeqListBinaryFind(SeqList* psl, SLDataType x); //Binary search
{
	assert(psl);
	int left = 0;
	int right = psl->size - 1;
	int mid;
	while (left <= right)
	{
		mid = (right - left) / 2 + left;
		if (x < psl->array[mid])
		{
			right = mid - 1;
		}
		else if (x > psl->array[mid])
		{
			left = mid + 1;
		}
		else
			return mid;
	}
	return -1;
}
  1. Delete all specified numbers
void SeqListRemoveAll(SeqList* psl, SLDataType x); //
{
	assert(psl);
	for (int i = 0; i < psl->size; i++)
	{
		if (psl->array[i] == x)
		{
			SeqListErase(psl, i);
		}
	}
}
The next part will update the linear list - part of the list knowledge induction!