单链表的增删查找操作

#pragma once
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
typedef int DataType;

typedef struct SLitsNode
{
	DataType data;
	struct SLitsNode *next;
}SListNode;

//初始化、销毁
void ListInit(SListNode **ppFirst)
{
	assert(ppFirst);
	*ppFirst = NULL;
}

void ListDestroy(SListNode **ppFirst)
{
	assert(ppFirst);
	SListNode *nextNode = NULL;
	SListNode *cur = *ppFirst;
	while (cur)
	{
		nextNode = cur->next;
		free(cur);
	}
	*ppFirst = NULL;
}

//创建新节点
SListNode *CreateNode(DataType data)
{
	SListNode *newNode = (SListNode *)malloc(sizeof(SListNode));
	assert(newNode);
	newNode->data = data;
	newNode->next = NULL;

	return newNode;
}

//增删查改
//头插
void  ListPushFront(SListNode **ppFirst, DataType data)
{
	assert(ppFirst);//考虑特殊情况,链表为空,但是这种情况依旧适合下列代码,所以没关系
	SListNode *newNode = CreateNode(data);
	
	newNode->next = *ppFirst;
	*ppFirst = newNode;
}

//尾插(至少要有一个节点)
void  ListPushBack(SListNode **ppFirst, DataType data)
{
	assert(ppFirst);
	SListNode *newNode = CreateNode(data);
	if (*ppFirst == NULL)//如果链表为空
	{
		newNode->next = NULL;
		*ppFirst = newNode;
		return;
	}

	SListNode *cur = *ppFirst;
	while (cur->next != NULL)
	{
		cur = cur->next;
	}
	
	newNode->next = NULL;
	cur->next = newNode;
}

//查找
SListNode *ListFind(SListNode *pFirst, DataType data)
{
	assert(pFirst);
	SListNode *cur = pFirst;
	for (cur = pFirst; cur != NULL; cur = cur->next)
	{
		if (data == cur->data)
		{
			return cur;
		}
	}
	return NULL;
}

//在节点pos前插入(节点在链表中)
void ListInsert(SListNode **ppFirst, SListNode *pos, DataType data)
{
	assert(ppFirst);
	if (pos == NULL){
		printf("have no pos\n");
		return;
	}
	if (pos == *ppFirst)
	{
		ListPushFront(ppFirst, data);
		return;
	}

	SListNode *cur = *ppFirst;
	while (cur->next != pos)
	{
		cur = cur->next;
	}

	SListNode *newNode = CreateNode(data);
	newNode->next = cur->next;
	cur->next = newNode;
}


//头删
void ListPopFront(SListNode **ppFirst)
{
	assert(ppFirst);
	assert(*ppFirst);//链表不能为空(特殊情况)
	SListNode *del = *ppFirst;
	*ppFirst = del->next;
	free(del);
}

//尾删
void ListPopBack(SListNode **ppFirst)
{
	assert(ppFirst);
	assert(*ppFirst);//链表不能为空(特殊情况)
	if ((*ppFirst)->next == NULL)//特殊情况(链表只有一个节点)
	{
		free(*ppFirst);
		(*ppFirst) = NULL;
		return;
	}

	SListNode *del = NULL;
	SListNode *cur = *ppFirst;
	while (cur->next->next != NULL)
	{
		cur = cur->next;
	}

	del = cur->next;
	cur->next = NULL;
	free(del);
}

//删除指定节点(节点在链表中)
void ListErase(SListNode **ppFirst, SListNode *pos)
{
	assert(ppFirst);
	assert(*ppFirst);
	if (pos == NULL){
		printf("have no pos\n");
		return;
	}

	if (pos == *ppFirst)
	{
		ListPopFront(ppFirst);
		return;
	}

	SListNode *cur = *ppFirst;
	SListNode *del = NULL;
	while (cur->next != pos)
	{
		cur = cur->next;
	}
	del = cur->next;
	cur->next = del->next;
	free(del);
}

void ListPrint(SListNode *pFirst)
{
	SListNode *cur = pFirst;
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

void Test()
{
	SListNode *first;//头指针
	ListInit(&first);//first的指向要改变,所以要传地址

	//ListPushBack(&first, 2);//尾插
	//ListPushFront(&first, 1);//头插
	//ListPopFront(&first);
	//ListPopBack(&first);
	ListPushBack(&first, 1);//尾插
	ListPushBack(&first, 2);//尾插
	ListPushBack(&first, 3);//尾插
	ListPushBack(&first, 4);//尾插
	ListPushBack(&first, 5);//尾插
	//ListInsert(&first, ListFind(first, 2), 10);
	ListErase(&first, ListFind(first, 5));

	ListPrint(first);
}

猜你喜欢

转载自blog.csdn.net/qq_42080151/article/details/84112622