代码实现单链表的操作函数

#pragma once

#include<assert.h>
#include<stdio.h>
#include<stdlib.h>

typedef int DataType;

typedef struct SListNode{
	DataType data;
	struct SListNode *pNext;
}SListNode;

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

//销毁
void Slistdestroy(SListNode **ppfirst){
	assert(ppfirst);
	SListNode *pNode, *pNext;
	pNode = *ppfirst;
	while (pNode != NULL);
	{
		pNext = pNode->pNext;
		free(pNode);
		pNode = pNext;
	}
	*ppfirst = NULL;
}
//销毁
void SListDestroy(SListNode **ppfirst)
{
	assert(ppfirst != NULL);
	SListNode *pNode, *pNext;
	pNode = *ppfirst;
	while (pNode != NULL)
	{
		pNext = pNode->pNext;
		free(pNode);
		pNode = pNext;
	}
	*ppfirst = NULL;
}
//增删改查
SListNode *CreatNewNode(int data)
{
	SListNode *pNewNode = (SListNode*)malloc(sizeof(SListNode));
	assert(pNewNode);
	pNewNode->data = data;
	pNewNode->pNext = NULL;
	return pNewNode;
}
//尾插
void SListPushback(SListNode **ppfirst, DataType data){
	assert(ppfirst);
	SListNode *pNewNode = CreatNewNode(data);
	if (*ppfirst == NULL)
	{
		*ppfirst = pNewNode;
		return;
	}
	SListNode *pNode;
	pNode = *ppfirst;
	while (pNode->pNext != NULL)
	{
		pNode = pNode->pNext;
	}
	pNode->pNext = pNewNode;
}
//头插
void SListPushFront(SListNode **ppfirst,DataType data)
{
	assert(ppfirst);
	SListNode *pNewNode = CreatNewNode(data);
	pNewNode->pNext = *ppfirst;
	*ppfirst = pNewNode;
}

//插入到指定的节点pPos前,pPos肯定在节点里

void InSert(SListNode **ppfirst, SListNode *pPos, DataType data)
{
	assert(ppfirst != NULL);
	assert(pPos != NULL);
	SListNode *pNode;
	SListNode *pos = pPos;
	if (pos == *ppfirst)
	{
		SListPushFront(ppfirst, data);
		return;
	}
	SListNode *pNewNode = CreatNewNode(data);
	for (pNode = *ppfirst; pNode->pNext != pos; pNode = pNode->pNext)
	{
	}
	pNode->pNext = pNewNode;
	pNewNode->pNext = pos;
}

//查找,返回遇到的第一个
//如果找到返回节点地址
//如果没找到,返回NULL

SListNode *Find(SListNode **ppfirst, DataType data){
	assert(ppfirst);
	SListNode *pNode;
	for (pNode = *ppfirst; pNode; pNode = pNode->pNext)
	{
		if (pNode->data == data)
		{
			return pNode;
		}
	}
	return NULL;
}


//打印
void print(SListNode *pfirst){
	assert(pfirst);
	SListNode *pNode = pfirst;
	for (pNode = pfirst; pNode != NULL; pNode = pNode->pNext)
	{
		printf("%d ->", pNode->data);
	}
	printf("NULL \n");
}


void TestSList()
{
	SListNode *pFirst = NULL;
	//SListInit(&pFirst);
	//SListPushback(&pFirst, 1);
	//SListPushback(&pFirst, 2);
	SListPushback(&pFirst, 3);
	SListPushback(&pFirst, 4);
	SListPushFront(&pFirst, 5);
	SListPushFront(&pFirst, 6);
	SListPushFront(&pFirst, 7);
	print(pFirst);

	SListNode *pFound = Find(&pFirst, 6);
	if (pFound == NULL)
	{
		printf("没有找到\n");
	}
	else{
		printf("%d\n", pFound->data);
		InSert(&pFirst, pFound,100);
		print(pFirst);
	}
}

//头删
void PopFront(SListNode **ppfirst)
{
	assert(ppfirst != NULL);
	assert(*ppfirst != NULL);
	SListNode *pNode = *ppfirst;
	*ppfirst = pNode->pNext;
	free(pNode);
}

//尾删
void PopBack(SListNode **ppfirst)
{
	assert(ppfirst != NULL);
	assert(*ppfirst != NULL);
	SListNode *pfirst = *ppfirst;
	if ((pfirst->pNext) == NULL)
	{
		free(pfirst);
		pfirst = NULL;
		return;
	}
	while (pfirst->pNext->pNext != NULL)
	{
		pfirst = pfirst->pNext;
	}
	free(pfirst->pNext);
	pfirst->pNext = NULL;
}
//根据节点地址删除,节点肯定在链表里
void Erase(SListNode **ppfirst, SListNode *pPos)
{
	assert(ppfirst != NULL);
	assert(*ppfirst != NULL);
	SListNode *pos = pPos;
	SListNode *pfirst = *ppfirst;
	if (pfirst == pos)
	{
		PopFront(ppfirst);
		return;
	}
	while (pfirst->pNext != pos)
	{
		pfirst = pfirst->pNext;
	}
	pfirst->pNext = pos->pNext;
	free(pos);

}

//根据数据去删除,删除遇到的第一个节点
void Remove(SListNode **ppfirst, DataType data)
{
	SListNode *pNode = *ppfirst;
	SListNode *pFound = Find(ppfirst, data);
	if (pFound != NULL){
		Erase(ppfirst, pFound);
	}

}
//根据数据去删除,删除遇到的所有节点
void RemoveAll(SListNode **ppfirst, DataType data)
{
	SListNode *pNode = *ppfirst;
	SListNode *pNext;
	while (pNode->pNext){
		if (pNode->pNext->data == data)
		{
			pNext = pNode->pNext;
			pNode->pNext = pNode->pNext->pNext;
			free(pNext);
		}
		else{
			pNode = pNode->pNext;
		}
	}
	if ((*ppfirst)->data == data)
	{
		PopFront(ppfirst);
	}
}
void TextList()
{
	SListNode *pFirst = NULL;
	SListPushback(&pFirst, 3);
	SListPushback(&pFirst, 5);
	SListPushback(&pFirst, 6);
	SListPushback(&pFirst, 8);
	SListPushback(&pFirst, 8);
	SListPushback(&pFirst, 8);
	SListPushback(&pFirst, 8);
	SListPushback(&pFirst, 5);
	SListPushback(&pFirst, 0);
	SListPushback(&pFirst, 3);
	print(pFirst);
	PopFront(&pFirst);
	//PopFront(&pFirst);
	//PopFront(&pFirst);
	PopBack(&pFirst);
	print(pFirst);

	SListNode *pFound = Find(&pFirst, 5);
	if (pFound == NULL)
	{
		printf("nothing");
	}
	else{
		printf("%d\n", pFound->data); 
		Erase(&pFirst,pFound);
	}
	print(pFirst);
	Remove(&pFirst, 5);
	print(pFirst);
	RemoveAll(&pFirst, 6);
	print(pFirst);
	SListDestroy(&pFirst);
}

定义一个结构体,这个结构体就是链表的结点,里面有两个参数,一个data是链表节点的数据,一个pNext,存放的是下一个节点的地址,最后一个节点的pNext指向NULL。

pFirst是链表的首节点的地址

程序中使用的增删改查函数的参数全部是二级指针 ,需要特别注意。

代码开始将节点数据类型重命名,这样若需要更改数据类型时更加方便。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值