数据结构中单链表的基本操作

在数据结构中,链表的相关操作尤为重要,链表有单向链表和双向链表。 此篇博客主要向大家介绍单链表的相关操作,

其中包括链表的增删改查,头删尾删,头插尾插。  在链表中由于需要不断的扩充或者减小结构,因此将链表定义为动态内存,

使用malloc来满足这一操作。


#include <stdio.h>
#include <windows.h>
#include <assert.h>
// 值类型 
typedef int DataType;

typedef struct SListNode {
	DataType data; // 值 
	struct SListNode *pNext; // 指向下一个结点 
} SListNode;

// 初始化 
void SListInit(SListNode **ppFirst)
{
	*ppFirst = NULL;
}

// 尾部插入 
void SListPushBack(SListNode** ppFirst, DataType data)
{
	assert(ppFirst != NULL);
	SListNode *pNewNode = (SListNode *)malloc(sizeof(SListNode));
	assert(pNewNode);
	pNewNode->data = data;
	pNewNode->pNext = NULL;
	if (*ppFirst == NULL){
		*ppFirst = pNewNode;
		return 0;
	}

	SListNode *pNode;
	pNode = *ppFirst;
	while (pNode->pNext != NULL)
	{
		pNode = pNode->pNext;
	}
	pNode->pNext = pNewNode;
}

// 头部插入 
void SListPushFront(SListNode **ppFirst, DataType data)
{
	assert(ppFirst != NULL);
	SListNode *pFirst = (SListNode*)malloc(sizeof(SListNode));
	pFirst->data=data;
	pFirst->pNext = *(ppFirst);
}

// 尾部删除 
void SListPopBack(SListNode **ppFirst)
{

	if ((*ppFirst)->pNext == NULL)
	{
		free(*ppFirst);
		(*ppFirst) = NULL;
	}
	SListNode *Back = *ppFirst;
	while (Back->pNext->pNext != NULL)
	{
		Back=Back->pNext;
	}
	free(Back->pNext);
	Back->pNext = NULL;
}

// 头部删除 
void SListPopFront(SListNode **ppFirst)
{
	assert(*ppFirst != NULL);
	SListNode *oldFirst = *ppFirst;
	*ppFirst = (*ppFirst)->pNext;
	free(oldFirst);
}

// 给定结点插入,插入到结点前   
void SListInsert(SListNode **ppFirst, SListNode *pPos, DataType data)
{
	assert(ppFirst != NULL);
	SListNode *pNode;
	pNode = *ppFirst;
	while( pNode->pNext != pPos)
	{
		pNode = pNode->pNext;
	}
	//两个位置交换
	pNode->pNext = pPos;
	pPos->pNext = pNode->pNext;

}

// 给定结点删除 
void SListErase(SListNode **ppFirst, SListNode *pPos)
{
	assert(ppFirst);	
	/*SListNode *NewFirst = *ppFirst;
	while (NewFirst != pPos)
	{
		NewFirst = NewFirst->pNext;
	}
	free(ppFirst);
	pPos->pNext = NewFirst->pNext;
	pPos = NewFirst;*/
	if (*ppFirst == pPos)
	{
		SListPopFront(ppFirst);
	}
	SListNode *NewFirst = *ppFirst;
	for (NewFirst; NewFirst->pNext != pPos; NewFirst = NewFirst->pNext)
	{
		;
	}
	NewFirst->pNext = pPos->pNext;
	free(pPos);
}
// 按值查找,返回第一个找到的结点指针,如果没找到,返回 NULL 
SListNode* SListFind(SListNode *pFirst, DataType data)
{
	SListNode *Node = pFirst;
	while (Node)
	{
		if (Node->data == data)
		{
			return Node;
		}
		Node = Node->pNext;
	}
	return NULL;
}
// 按值删除,只删遇到的第一个 
void SListRemove(SListNode **ppFirst, DataType data)
{
	SListNode *Find = SListFind(*ppFirst, data);
	if (Find != NULL)
	{
		SListErase(ppFirst, Find);
	}
}

// 按值删除,删除所有的 
void SListRemoveAll(SListNode **ppFirst, DataType data)
{
	SListNode *Node = *ppFirst;
	while (Node)
	{
		if (Node->pNext->data== data)
		{
			Node->pNext = Node->pNext->pNext;
			free(Node->pNext);
		}
		if (Node->data = data)
		{
			Node = Node->pNext;
			free(Node);
		}
		else 
		{
			Node = Node->pNext;
		}
	}
}

// 销毁 
void SListDestroy(SListNode **ppFirst)
{
	SListNode *Node, *Next;
	Node = *ppFirst;
	while (Node!=NULL)
	{
		Next = Node->pNext;
		free(Node);
		Node = Next;
	}
	*ppFirst = NULL;
}


void show(SListNode *Sln)
{
	while (Sln)
	{
		printf("%d->", Sln->data);
		Sln = Sln->pNext;
	}
	printf("NULL");
}
int main()
{
	SListNode *Sln;
	SListInit(&Sln);	
	SListPushBack(&Sln, 5);
	show(Sln);
	system("pause");
	return 0;
}
至此,单链表的相关操作就在代码中体现出来了。 链表的概念有些抽象,博主给大家一个小方法,在写链表的操作时可以用画图的形式来理解,这样写代码时就更容易实现链表的相关操作了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值