A collection of linked list classic topics (c language version)

A collection of linked list classic topics (c language version)

As a more popular type of data structure, linked list has always been a common type of written test interviews in major companies. At the same time, linked list also has many classic topics, which can help beginners better understand linked list.
1. Print the linked list from end to end

First traverse the linked list, insert the value header of the linked list into a new linked list while traversing, and then print the new linked list.

void SLitsPrintTailToHead (SListNode * pHead)
{
	SListNode* _new, *ptr;
	_new = NULL;
	ptr = pHead;
	while (ptr)
	{
		SListPushFront(&_new, ptr->data);
		ptr = ptr->next;
	}
	while (_new)
	{
		printf("%d ", _new->data);
		_new = _new->next;
	}
}

2. Delete a non-tail node of a headless singly linked list (cannot traverse the linked list)
Assuming that the pos node is deleted, we can store the data of the next node of pos into the pos node, and delete the next node of the pos node.
void SListDelNonTailNode(SListNode* pos)
{
	SListNode* Ppos;
	Ppos = NULL;
	Ppos = pos->next;
	pos->data = Ppos->data;
	pos->next = Ppos->next;
	free(Ppos);
}

3. Insert a node before a node in a headless singly linked list (the linked list cannot be traversed)
Suppose we need to insert a node before pos, we can first insert a node with the same data as pos after pos, and then change the data of pos to the given value.
void SListInsertFrontNode(SListNode* pos, DataType x)
{
	SListNode* _new;
	_new = NULL;
	_new = BuySListNode(pos->data);
	_new->next = pos->next;
	pos->next = _new;
	pos->data = x;
}

4. Singly linked list implements Joseph Circle (JosephCircle)
The Joseph Ring is an applied mathematics problem: n people (represented by the numbers 1, 2, 3...n) are known to sit around a round table. The person numbered k starts to count, and the person who counts to m is dequeued; the next person starts to count from 1, and the person who counts to m is dequeued again; this pattern is repeated until around the round table. of people are all listed. Usually when solving such problems, we number from 0 to n-1, and the final result + 1 is the solution of the original problem.
First, iteratively find the tail node, and let the next pointer of the tail node point to the head node, which forms a loop, and then enters the loop. The end condition of the loop is that there is only one node left. Iterates continuously k times and then deletes the current node.
SListNode * SListJosephCircle (SListNode * pHead, int k)
{
	SListNode* str, *tail;
	int i = 0;
	str = pHead;
	tail = pHead;
	while (tail->next)
	{
		tail = tail->next;
	}
	tail->next = pHead;
	while (str->next!=str)
	{
		for (;i < k;++i)
		{
			str = str->next;
		}
		str->data = str->next->data;
		str->next = str->next->next;
		free(str->next);
	}
	return str;
}

5. Reverse/reverse a singly linked list
Traverse the linked list and insert the data header into the linked list at the same time, and the new linked list is a reverse linked list.
SListNode* SListReverse(SListNode* list)
{
	SListNode* _new, *str;
	_new = NULL;
	str = list;
	while (str)
	{
		SListPushFront(&_new, str->data);
		str = str->next;
	}
	return _new;
}
6. Singly linked list bubble sort
void SListBubbleSort(SListNode* list)
{
	int i, j,count;
	count = 0;
	int mid;
	SListNode* str,*ptri,*ptrj;
	str = list;
	while (str)
	{
		str = str->next;
		count++;
	}
	for (i = 0;i < count-1;i++)
	{
		ptri = list;
		ptri = ptri->next;
		for (j = 0;j < i-1;j++)
		{
			ptrj = list;
			ptrj = ptrj->next;
			if (ptri->data > ptrj->data)
			{
				mid = ptri->data;
				ptri->data = ptrj->data;
				ptrj->data = mid;
			}
		}
	}
}

7. Merge two ordered linked lists, which are still in order after the merger
Point the two pointers to two ordered linked lists respectively, compare the data pointed to by the two linked lists, insert the smaller one into the new linked list and move the pointer backwards, perform the next comparison, and end when both pointers are finished.

SListNode * SListMerge (SListNode * list1, SListNode * list2)
{
	SListNode* str1, *str2,*_new;
	str1 = list1;
	str2 = list2;
	_new = NULL;
	while (str1&&str2)
	{
		if (str1->data > str2->data)
		{
			SListPushBack(&_new,str2->data);
			str2 = str2->next;
		}
		if (str1->data < str2->data)
		{
			SListPushBack(&_new, str1->data);
			str1 = str1->next;
		}
		else
		{
			SListPushBack(&_new, str2->data);
		}
	}
	return _new;
}

8. Find the intermediate node of a singly linked list, requiring only one traversal of the linked list
Given two pointers, the first pointer takes one step when the second pointer takes two steps, and when the fast pointer finishes walking, the slow pointer goes to the middle node.
SListNode* SListFindMidNode(SListNode* list)
{
	SListNode* fast, *slow;
	fast = list;
	slow = list;
	while (fast->next)
	{
		fast = fast->next;
		if (fast->next == NULL)
		{
			break;
		}
		fast = fast->next;
		slow = slow->next;
	}
	return slow;
}

9. Find the k-th node from the bottom of the singly linked list, requiring only one traversal of the linked list
Two pointers are also defined, the fast pointer takes k steps first and the slow pointer starts to walk, and when the fast pointer finishes walking, the slow pointer goes to the Kth node from the bottom.
SListNode* SListFindTailKNode(SListNode* list, size_t k)
{
	SListNode* fast, *slow;
	fast = list;
	slow = list;
	int i;
	for (i = 0;i < k;i++)
	{
		fast = fast->next;
	}
	while (fast)
	{
		fast = fast->next;
		slow = slow->next;
	}
	return slow;
}

10. Construct a linked list with a ring
Find the node of the ring entry, let the tail node point to the entry node.
SListNode* SListIsCycle(SListNode* list)
{
	SListNode * str, * ptr;
	str = list;
	ptr = SListFind(list, 0);
	while (str)
	{
		str = str->next;
	}
	str->next = ptr;
	return ptr;
}

11. Find the length of the ring
Define two fast and slow pointers, the fast pointer takes two steps and the slow pointer takes one step, and ends when they meet in the ring. Let them continue to walk, and the fast pointer must be faster than the slow pointer by the length of the ring when they meet for the second time.
int SListCycleLen(SListNode* meetNode)
{
	int len,count1,count2;
	SListNode*fast, *slow;
	fast = meetNode->next;
	slow = meetNode;
	int count=1;
	while (fast!=slow)
	{
		fast = fast->next->next;
		slow = slow->next;
	}
	slow - slow->next;
	while (slow != fast)
	{
		slow = slow->next;
		count++;
	}
	return count;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324839321&siteId=291194637