Data structure (1) singly linked list

When reviewing questions and interviewing, you will always encounter questions such as linked lists. Let's take a look at the questions on Leetcode:
Insert picture description here

1. What is a linked list?

In order to represent each data element ai a_iaiRather than the direct successor data ai + 1 a_{i+1}ai+1The logical relationship between, for data ai a_iaiIn other words, in addition to storing its own information, it also needs to store an indication of its successor information (that is, the storage location of the immediate successor). We call the domain that stores element data the data domain , and the domain that is stored in the immediate successor position is called the pointer domain . The information stored in the pointer field is called a pointer or chain. This two-part message consisting of the data element ai a_iaiThe storage image is called a node .

For the linked list, the head node is optional. It will appear before the first node of the singly linked list and add a new node to provide some additional information (such as length) of the linked list.
1

2

A linked list can have no head node, but it must have a head pointer, so the name of a linked list is usually represented by a head pointer. The role of the head node:

  • When deleting and inserting the linked list, the operation of the first node is more convenient
  • Unified processing of empty and non-empty lists

For specific explanation, please see https://blog.csdn.net/snow_7/article/details/106919353

According to the pointer domain, there is only one called singly linked list. This section only introduces singly linked lists. Later we will introduce circular linked lists and doubly linked lists.

Second, the structure of the node

We will use pointers to implement this structure. This structure contains at least two parts, the pointer field and the data field.

typedef struct Node{
    
    
	int data;
	struct Node* next;
}Node;
typedef struct Node* pNode;//指向一个结点的指针

Very important! ! ! ! For a linked list without additional head nodes, the head pointer points to the first node of the linked list; if it is a linked list with additional head nodes, the head pointer points to this additional head node. It seems that there is no additional head node when writing the question, and if the head node points to empty, then the length of the linked list is 0, that is, the empty linked list; if the head node -> next is empty, the length of the linked list is 1. The head node is not equal to the first node, it is the node before the first.

Three, value

//pHead在这里是一个指向头结点或者第一个结点
bool get_index_element(pNode pHead, int i, int* value)
{
    
    
	
	int j = 1;//用于标识当前检查的结点号
	pNode pCurNode = pHead->next;//j=1,cur指向结点1

    //进入循环的条件:没有达到链表最后结点或者还没检查到指定序号结点或给了一个比1还要小的检查序号
	while (pCurNode &&j<i)
	{
    
    
		
		//更新序号和待检查结点指针pCurNode
		j++;
		pCurNode = pCurNode->next;
		
	}
	
	//若到达最后了仍然没有找指定序号结点,那么说明长度不够,返回false
	//或者是用户给了一个不正确的序号参数(i<1)
	if (!pCurNode && i < j)
	{
    
    
		return false;
	}

	*value= pCurNode->data;
	return true;
}

PS: If the cur pointer is a null pointer, it is implicitly converted to false, otherwise it is true

Fourth, insert in front of the element

Before or after the selected element is inserted according to the new element

bool insert_index_element(pNode * pHead,int i,int value)
{
    
    
	int j = 1;
	pNode pCurNode = pHead->next;
	while (pCurNode || j < i)
	{
    
    
		pCurNode = pCurNode->next;
		j++;
	}

	if (!pCurNode && i < j)
	{
    
    
		return false;
	}
	pNode pNewNode = (pNode)malloc(sizeof(Node));
	pNewNode->data = value;
	pNewNode->next = pCurNode->next;
	pCurNode->next = pNewNode;

	return true;
}

Five, delete

bool delete_index_element(pNode pHead, int i, int *value)
{
    
    
	int j = 1;
	pNode pCurNode = pHead;

	while (!pCurNode->next || j < i)
	{
    
    
		pCurNode = pCurNode->next;
		j++;
	}
	if (!pCurNode->next || i < j)
	{
    
    
		return false;
	}

	*value = pCurNode->next->data;
	pNode q=pCurNode->next;//必要操作,防止下一步pCurNode->next丢失掉需要释放空间的结点
	pCurNode->next = pCurNode->next->next;
	free(pCurNode->next);
	return true;

}

Six, create the entire linked list

Creating a linked list can be divided into two types according to the insertion method: pre-insertion and post-insertion.

Tail insertion

//尾部插入法
void create_random_list(pNode* pHead, int n)
{
    
    
	srand(time(0));//初始化种子

	*pHead = (pNode)malloc(sizeof(Node));//创建头结点
	pNode pFinalNode = *pHead;
	pNode pNewNode = nullptr;

	for (int i = 0; i < n; i++)
	{
    
    
		pNewNode = (pNode)malloc(sizeof(Node));
		pNewNode->data = rand() % 100 + 1;
		cout << pNewNode->data << endl;
		pFinalNode->next = pNewNode;
		pFinalNode = pNewNode;
	}
	pFinalNode->next = nullptr;
}
//头部插入法
void front_create_list(pNode* pHead, int n)
{
    
    
	srand(time(0));//初始化种子

	*pHead = (pNode)malloc(sizeof(Node));//创建头结点
	pNode pNewNode = nullptr;

	for (int i = 0; i < n; i++)
	{
    
    
		pNewNode = (pNode)malloc(sizeof(Node));
		pNewNode->data = rand() % 100 + 1;
		cout << pNewNode->data << endl;
		pNewNode->next = (*pHead)->next;
		(*pHead)->next = pNewNode;
	}
	pNewNode->next = nullptr;
}

Here, we pass the pointer to the node , because it changed the head pointer points to, if not involved in the creation and deletion head node can not pass a pointer to a pointer .

Seven, delete the entire linked list

void clear_list(pNode pHead)
{
    
    
	pNode pCurNode= pHead->next;
	pNode pNextNode = pCurNode;
	while (pCurNode)//指针域不为空
	{
    
    
		pNextNode = pCurNode->next;
		free(pCurNode);
		pCurNode = pNextNode;
	}
	pHead->next = nullptr;

}

[1] https://blog.csdn.net/snow_7/article/details/106919353

Guess you like

Origin blog.csdn.net/weixin_39258979/article/details/114992787