Data structure - sequence table, single linked table

Posted by boneXXX on Sat, 30 Oct 2021 10:50:10 +0200

● 🧑 Personal homepage: You're handsome. You say it first
● 📃 Welcome to praise 👍 follow ðŸ’Ą Collection 💖
● 📖 Having chosen the distance, he only cares about the wind and rain.
● ðŸĪŸ If you have any questions, please feel free to write to me!
● 🧐 Copyright: This article is original by [you Shuai, you say first.] and launched by CSDN. Infringement must be investigated.

ðŸĐ 1. Linearity table

A linear list is a finite sequence of n data elements with the same characteristics. Linear table is a data structure widely used in practice. Common linear tables: sequential table, linked list, stack, queue, string
A linear table is logically a linear structure, that is, a continuous straight line. However, the physical structure is not necessarily continuous. When the linear table is stored physically, it is usually stored in the form of array and chain structure.

🐒 2. Sequence table

🐎 2.1 concept and structure

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. Complete the addition, deletion, query and modification of data on the array.

The sequence table can generally be divided into:

  1. Static sequential table: uses a fixed length array to store elements.
  2. Dynamic sequential table: use dynamic array storage.

🐈 2.2 interface implementation

The static sequence table is only applicable to the scenario where you know how much data needs to be stored. The fixed length array of static sequence table leads to large N, waste of space and insufficient space. Therefore, in reality, dynamic sequential tables are basically used to dynamically allocate space according to needs, so let's implement dynamic sequential tables below.

typedef int SLDataType;
// Dynamic storage of sequential tables
typedef struct SeqList
{
 SLDataType* array; // Point to a dynamic array
 size_t size ; // Number of valid data
 size_t capicity ; // Size of capacity space
}SeqList

ðŸĒ 2.2.1 initialization sequence table

void SeqListInit(SL* ps)
{
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

ðŸģ 2.2.2 printing sequence table

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

🐝 2.2.3 check space allowance

void SeqListCheckCapacity(SL* ps)
{
	// If there is no space or insufficient space, we will expand the capacity
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity*sizeof(SLDataType));
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newcapacity;
	}
}

🐎 2.2.4 tail insertion of sequence table

void SeqListPushBack(SL* ps, SLDataType x)
{
	SeqListCheckCapacity(ps);

	ps->a[ps->size] = x;
	ps->size++;
}

🐙 2.2.5 deletion at the end of sequence table

void SeqListPopBack(SL* ps)
{
	assert(ps->size > 0);
	ps->size--;
}

ðŸĶ‰ 2.2.6 sequential header insertion

void SeqListPushFront(SL* ps, SLDataType x)
{
	SeqListCheckCapacity(ps);

	// Mobile data
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps->a[0] = x;
	ps->size++;
}

ðŸĶœ 2.2.7 deletion of sequence header

void SeqListPopFront(SL* ps)
{
	assert(ps->size > 0);

	// Mobile data
	int begin = 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		++ begin;
	}

	ps->size--;
}

🐘 2.2.8 finding Subscripts

int SeqListFind(SL* ps, SLDataType x)
{
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}

ðŸŋïļ 2.2.9 insertion at specified position

void SeqListInsert(SL* ps, int pos, SLDataType x)
{
	assert(pos >= 0 && pos <= ps->size);
	SeqListCheckCapacity(ps);
	// Mobile data
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}

	ps->a[pos] = x;
	ps->size++;
}

🐇 2.2.10 insertion at specified position

void SeqListErase(SL* ps, int pos)
{
	assert(pos >= 0 && pos < ps->size);

	int begin = pos + 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	}

	ps->size--;
}

🐉 2.2.11 destruction of sequence table

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

🐅 3. Single linked list

ðŸĶŒ 3.1 concept

Concept: linked list is a non continuous and non sequential storage structure in physical storage structure. The logical order of data elements is realized through the pointer link order in the linked list.


This is the logical structure of the single linked list, which is hypothetical and convenient for us to understand. The physical structure of the linked list is what it really looks like.

🐆 3.2 interface implementation

typedef int SLTDateType;
typedef struct SListNode
{
 	SLTDateType data;
 	struct SListNode* next; 
}SLTNode;

From the above figure, we know that the single linked list is accessed by saving the address of the next node.
Therefore, the operation of a single linked list to access the next node is as follows

SLTNode* Node;
Node = Node->next;

Only after you understand this, can you understand the next interface implementation

🐂 3.2.1 create node

SLTNode* BuyListNode(SLTDateType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}

🐖 3.2.2 single chain table tail insertion

void SListPushBack(SLTNode** pphead, SLTDateType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	newnode->data = x;
	newnode->next = NULL;
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		SLTNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}

		tail->next = newnode;
	}	
}

🐓 3.2.3 deletion of the end of the single chain table

void SListPopBack(SLTNode** pphead)
{
	assert(*pphead != NULL);
	// 1. One node
	// 2. Two or more nodes
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		SLTNode* tail = *pphead;
		while (tail->next->next)
		{
			tail = tail->next;
		}

		free(tail->next);
		tail->next = NULL;
	}
}

ðŸĪ 3.2.4 single chain meter insertion

void SListPushFront(SLTNode** pphead, SLTDateType x)
{
	SLTNode* newnode = BuyListNode(x);

	newnode->next = *pphead;
	*pphead = newnode;
}

ðŸĶ 3.2.5 deletion of single chain header

void SListPopFront(SLTNode** pphead)
{
	//if (*pphead == NULL)
	//	return;
	assert(*pphead != NULL);

	SLTNode* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}

🐧 3.2.6 single linked list printing

void SListPrint(SLTNode* phead)
{
	SLTNode* cur = phead;
	while (cur != NULL)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

ðŸĶĒ 3.2.7 finding nodes

SLTNode* SListFind(SLTNode* phead, SLTDateType x)
{
	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		else
		{
			cur = cur->next;
		}
	}

	return NULL;
}

ðŸĶš 3.2.8 insertion at designated position

void SListInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x)
{
	SLTNode* newnode = BuyListNode(x);
	if (*pphead == pos)
	{
		newnode->next = *pphead;
		*pphead = newnode;
	}
	else
	{
		// Find the previous position of pos
		SLTNode* posPrev = *pphead;
		while (posPrev->next != pos)
		{
			posPrev = posPrev->next;
		}

		posPrev->next = newnode;
		newnode->next = pos;
	}
}

ðŸĶĐ 3.2.9 insert after specifying the position

void SListInsertAfter(SLTNode* pos, SLTDateType x)
{
	assert(pos);

	SLTNode* newnode = BuyListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

🐙 3.2.10 designated location deletion

void SListErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead);
	assert(pos);

	if (*pphead == pos)
	{
		SListPopFront(pphead);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}

		prev->next = pos->next;
		free(pos);
		//pos = NULL;
	}
}

🐞 3.2.11 delete after specifying the location

void SListEraseAfter(SLTNode* pos)
{
	assert(pos);
	assert(pos->next);

	SLTNode* next = pos->next;
	pos->next = next->next;
	free(next);
}

ðŸĶ˜ 3.2.12 destruction of single linked list

void SListDestory(SLTNode** pphead)
{
	assert(pphead);

	SLTNode* cur = *pphead;
	while (cur)
	{
		SLTNode* next = cur->next;
		free(cur);
		cur = next;
	}

	*pphead = NULL;
}

🐕🐕🐕🐕🐕🐕🐕🐕🐕🐕🐕🐕🐕🐕🐕🐕
Don't you like such an article quickly 👍 follow ðŸ’Ą Collection 💖
🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈

Topics: data structure linked list