【数据结构】单链表-----基本操作

链表的实现:
https://blog.csdn.net/weixin_41892460/article/details/82855823

删除指定位置的节点


void Erase(pList * pplist, pNode pos)
{
	assert(pplist != NULL);
	assert(pos != NULL);
	if (*pplist == pos)//如果指向第一个节点
	{
		pNode del = pos;
		*pplist = (*pplist)->next;
		free(del);
		del = NULL;
	}
	else
	{
		pNode cur = *pplist;
		while (cur && cur->next != pos)//此处要找到pos的前一个节点,由于要将pos节点free前,
			//必须将pos的前一节点和后一节点连起来,所以此处不用cur!=pos作为条件
		{
			cur = cur->next;
		}
		if (cur != NULL)
		{
			cur->next = pos->next;
			free(pos);
			pos = NULL;
		}
	}
}


void TestErase()
{
	Node* plist = NULL;//指向第一个节点的指针
	pNode pos = NULL;
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	PrintLinkList(plist);
	pos = Find(plist, 2);
	if (pos != NULL)
	{
		Erase(&plist, pos);
	}
	PrintLinkList(plist);
	DestroyLinkList(&plist);
}





删除一个不是尾节点的节点


void EraseNotTailNode(pNode pos)
{
	pNode del = NULL;
	assert(pos);
	assert(pos->next);
	//
	del = pos->next;
	pos->data = pos->next->data;
	//
	pos->next = del->next;
	free(del);
	del = NULL;
}


void TestEraseNotNode()
{
	Node* plist = NULL;//指向第一个节点的指针
	pNode pos = NULL;
	PushFront(&plist, 1);
	PushFront(&plist, 2);
	PushFront(&plist, 3);
	PushFront(&plist, 4);
	PrintLinkList(plist);
	pos = Find(plist, 3);
	if (pos != NULL)
	{
		EraseNotTailNode(pos);
	}
	PrintLinkList(plist);
	DestroyLinkList(&plist);
}




删除指定值的节点

void Remove(pList* pplist, DataType d)
{
	pNode cur = NULL;
	pNode prev = NULL;
	assert(pplist);
	cur = *pplist;
	while (cur)
	{
		if (cur->data == d)
		{
			//第一个节点
			if (*pplist == cur)
			{
				{
					*pplist = cur->next;
					free(cur);
					cur = NULL;
				}
			}
			else
			{
				prev->next = cur->next;
				free(cur);
				cur = NULL;
			}
		}
		else
		{
			prev = cur;
			cur = cur->next;
		}
	}
}



void TestRemove()
{
	Node* plist = NULL;//指向第一个节点的指针
	pNode pos = NULL;
	PushBack(&plist, 3);
	PushBack(&plist, 1);
	PushBack(&plist, 3);
	PushBack(&plist, 3);
	PrintLinkList(plist);
	Remove(&plist, 1);
	PrintLinkList(plist);
}



删除所有的指定值

void RemoveAll(pList * pplist, DataType d)
{
	pNode cur = NULL;
	pNode prev = NULL;
	cur = *pplist;
	assert(pplist != NULL);
	while (cur)
	{
		if (cur->data == d)//找到了
		{
			if (*pplist == cur)//第一个节点
			{
				*pplist = cur->next;
				free(cur);
				cur = *pplist;
			}
			else//不是第一个节点
			{
				prev->next = cur->next;
				free(cur);
				cur = prev;
			}
		}
		else
		{
			prev = cur;
			cur = cur->next;
		}
	}
}

在指定位置之前插入一个数值

void Insert(pList * pplist, pNode pos, DataType d)
{
	pNode newNode = NULL;
	assert(pplist != NULL);
	assert(*pplist != NULL);
	assert(pos != NULL);
	if (pos == *pplist)
	{
		newNode = BuyNode(d);
		newNode->next = *pplist;
		*pplist = newNode;
	}
	else
	{
		pNode cur = *pplist;
		while (cur && cur->next != pos)
		{
			cur = cur->next;
		}
		if (cur != NULL)
		{
			newNode = BuyNode(d);
			newNode->next = pos;
			cur->next = newNode;
		}
	}
}



void TestInsert()
{
	Node* plist = NULL;//指向第一个节点的指针
	pNode pos = NULL;
	PushBack(&plist, 1);
	PushBack(&plist, 2);
	PushBack(&plist, 3);
	PrintLinkList(plist);
	pos = Find(plist, 2);
	if (pos != NULL)
	{
		Insert(&plist, pos, 8);
	}
	PrintLinkList(plist);
	DestroyLinkList(&plist);
}



由尾至头的打印节点

void PrintTailToHead(pList plist)
{
	pNode tail = NULL;
	pNode cur = plist;
	pNode prev = NULL;
	if (plist == NULL)
	{
		return;
	}
	while (cur)
	{
		tail = cur;
		cur = cur->next;
	}
	while (tail != plist)
	{
		cur = plist;
		while (cur != tail)
		{
			prev = cur;
			cur = cur->next;
		}
		printf("%d->", tail->data);
		tail = prev;
	}
	printf("%d->NULL\n", tail->data);
}

查找单链表的中间节点,要求只能遍历一次链表
思路:定义两个节点:一个走两步,一个走一步

void FindMidNode(pList* pplist)
{
	pNode fast = *pplist;
	pNode slow = *pplist;
	if (NULL == *pplist)
	{
	printf("该链表为空");
	}
	else if (NULL == slow->next)
	{
	printf("%d ", slow->data);
	}
	else
	{
	while (fast->next&&fast)
	{
	fast = fast->next->next;
	slow = slow->next;
	}
	printf("%d ", slow->data);
	}
}

查找单链表的倒数第k个节点,要求只能遍历一次链表
思路:一个节点先走k步

void FindLastKNode(pList *pplist, int k)
{

	pNode fast = *pplist;
	pNode slow = *pplist;
	if (NULL == *pplist || k <= 0)
	{
		printf("该链表为空");
	}
	while (k--)
	{
		fast = fast->next;
	}
	while (fast)
	{
		fast = fast->next;
		slow = slow->next;
	}
	printf("%d ", slow->data);
}



猜你喜欢

转载自blog.csdn.net/weixin_41892460/article/details/82887338