单向链表的基本操作

"SListNode.h”

<strong><span style="font-size:18px;">#ifndef __SListNode_H__
#define __SListNode_H__
#pragma once  //能够保证头文件只被编译一次
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int DataType;

typedef struct SListNode 
{
	DataType data;
	struct SListNode *_NextNode;
}SListNode,*PSListNode;

// 初始化单链表(对于无头结点单链表,该函数没有意义)
void InitList(PSListNode* pHead);
// 销毁单链表
void DestroyList(PSListNode* pHead);
// 尾插
void PushBack(PSListNode* pHead, DataType data);
// 尾出
void PopBack(PSListNode* pHead);
// 头插
void PushFront(PSListNode* pHead, DataType data);
// 头出
void PopFront(PSListNode* pHead);
// 在链表中查找元素data
PSListNode Find(PSListNode* pHead, DataType data);
// 删除pos位置的结点(注意不能用那种替换形式)
void  Erase(PSListNode* pHead, PSListNode pos);
// 在链表的pos位置插入元素data
void  Insert(PSListNode* pHead, PSListNode pos, DataType data);
//打印链表存放的数据
void PrintList(PSListNode* pHead);


#endif//__SListNode_H__</span></strong>


 

"SListNode.c"

<strong><span style="font-size:18px;">#define _CRT_SECURE_NO_WARNINGS 1
#include "SListNode.h"

//这里参的是二级指针,因为要对结构体指针的内容进行修改,所以必须传该指针的地址(即
//一个二级指针),一级指针相当于值传递,不会对实参有改变

void InitList(PSListNode* pHead)
{
	assert(pHead);
	pHead = NULL;
}

PSListNode ByeNode(DataType data)
{
	PSListNode pNewNode = (PSListNode)malloc(sizeof(struct SListNode));
	if (pNewNode != NULL)
	{
		pNewNode->data = data;
		pNewNode->_NextNode = NULL;//一定要记得把新开辟结点的下一个结点赋值为空
	} 
	else
	{
		printf("开辟内存失败\n");
	}

	return pNewNode;
}

void PrintList(PSListNode* pHead)
{
	PSListNode pNode = NULL;
	assert(pHead);
	if (*pHead == NULL)
	{
		return;
	} 
	else
	{
		pNode = *pHead;

		while (NULL != pNode)//最好写成while(NULL != pNode)
		{
			printf("%d ",pNode->data);
			pNode = pNode->_NextNode;
		}
		printf("\n");
	}
}

void PushBack(PSListNode* pHead, DataType data)
{
	PSListNode pNode = NULL;
	PSListNode pNewNode = NULL;
	assert(pHead);
	if (*pHead == NULL)
	{
		*pHead = ByeNode(data);
	} 
	else
	{
		pNode = *pHead;

		//找到尾结点
		while (NULL != pNode->_NextNode)
		{
			//保存尾结点
			pNode = pNode->_NextNode;
		}

		pNewNode = ByeNode(data);
		pNode->_NextNode = pNewNode;
		pNewNode->_NextNode = NULL;
	}
}

void PopBack(PSListNode* pHead)
{
	PSListNode pNode1 = NULL;   
	PSListNode pNode2 = NULL;
	assert(pHead);
    pNode1 = *pHead;

	if (*pHead == NULL)
	{
		printf("SListNode is emtpy\n");
		return;
	} 
	else if (pNode1->_NextNode == NULL) //当只剩下一个节点的情况下,要单独处理头指针
	{
		*pHead = NULL;
		free(pNode1);
		pNode1 = NULL;
	}
	else
	{
		while (pNode1->_NextNode != NULL)
		{
			pNode2 = pNode1;//用一个指针追踪当前指针,一遍记录当前位置
			pNode1 = pNode1->_NextNode;
		}

		pNode2->_NextNode = NULL;//保证链表最后一个节点的的_NextNode为空

		free(pNode1);//和malloc配套使用   释放最后一个节点
		pNode1 = NULL;//将释放掉的结点赋值为空,以防变成空指针
	}
}

void PushFront(PSListNode* pHead, DataType data)
{
	PSListNode pNode = NULL;
	assert(pHead);

	if (*pHead == NULL)
	{
		*pHead = ByeNode(data);
		(*pHead)->_NextNode = NULL;
	} 
	else
	{
		pNode = ByeNode(data);
		pNode->_NextNode = *pHead;
		*pHead = pNode;
	}
}

void PopFront(PSListNode* pHead)
{
	PSListNode pNode = NULL;
	assert(pHead);

	
	if (NULL == *pHead)
	{
		printf("SListNode is empty\n");
	} 
	else if ((*pHead)->_NextNode == NULL)
	{
		pNode = *pHead;
		*pHead = NULL;
		free(pNode);
		pNode = NULL;
	}
	else
	{
		pNode = *pHead;
		*pHead = (*pHead)->_NextNode;
		free(pNode);
		pNode = NULL;
	}
}

PSListNode Find(PSListNode* pHead, DataType data)
{
	PSListNode pNode = NULL;
	assert(pHead);

	pNode = *pHead;
	while (NULL != pNode)
	{
		if (pNode->data == data)
		{
			return pNode;
		} 
		else
		{
			pNode = pNode->_NextNode;
		}
	}

	return NULL;
}

void Erase(PSListNode* pHead, PSListNode pos)
{
	PSListNode pNode = NULL;
	PSListNode pNode2 = NULL;
	assert(pHead);
	assert(pos);

	pNode = *pHead;

	while (NULL != pNode)
	{
		if (pNode->_NextNode == pos )
		{
			pNode2 = pNode->_NextNode;
			pNode->_NextNode = pNode->_NextNode->_NextNode;
			free(pNode2);
			pNode2 = NULL;
		} 
		else if(pNode == pos)
		{
			*pHead = (*pHead)->_NextNode;
			free(pNode);
			pNode = NULL;
		}
		else
		{
			pNode = pNode->_NextNode;
		}
	}
}

void Insert(PSListNode* pHead, PSListNode pos, DataType data)
{
	PSListNode pNode = NULL;
	PSListNode pNewNode = NULL;
	assert(pHead);
	assert(pos);

	pNode = *pHead;

	while (NULL != pNode)
	{
		if (pNode->_NextNode == pos)
		{
			pNewNode = ByeNode(data);
			pNewNode->_NextNode = pNode->_NextNode;
			pNode->_NextNode = pNewNode;
			break;
		} 
		else if(pNode == pos)
		{
			pNewNode = ByeNode(data);
			pNewNode->_NextNode = *pHead;
			*pHead = pNewNode;
			break;
		}
		else
		{
			pNode = pNode->_NextNode;
		}
	}
}

void DestroyList(PSListNode* pHead)
{
	PSListNode pNode = NULL;
	PSListNode pNode2 = NULL;
	assert(pHead);

	pNode = *pHead;

	while (NULL != pNode)
	{
		pNode2 = pNode;
		pNode = pNode->_NextNode;
		free(pNode2);
		pNode2 = NULL;
	}
	*pHead = NULL;
}</span></strong>


 

"test.c"

<strong><span style="font-size:18px;">#define _CRT_SECURE_NO_WARNINGS 1
#include "SListNode.h"

void Test1()//PushBack   PopBack
{
	PSListNode pHead = NULL;
	InitList(&pHead);
	PushBack(&pHead,0);
	PushBack(&pHead,1);
	PushBack(&pHead,2);
	PushBack(&pHead,3);
	PushBack(&pHead,4);

	PrintList(&pHead);

	PopBack(&pHead);
	PopBack(&pHead);

	PrintList(&pHead);
}

void Test2()//PushFront   PopFront   Find
{ 
	PSListNode ret = NULL;
	PSListNode pHead = NULL;
	InitList(&pHead);
	PushFront(&pHead,0);
	PushFront(&pHead,1);
	PushFront(&pHead,2);
	PushFront(&pHead,3);
	PushFront(&pHead,4);

	PrintList(&pHead);

	PopFront(&pHead);
	PopFront(&pHead);
	//PopFront(&pHead);
	//PopFront(&pHead);
	//PopFront(&pHead);
	//PopFront(&pHead);

	PrintList(&pHead);

	ret = Find(&pHead,2);
	if (ret == NULL)
	{
		printf("no find\n");
	} 
	else
	{
		printf("%d \n",ret->data);
	}
}

void Test3()//Erase
{
	PSListNode pHead = NULL;
	InitList(&pHead);
	PushBack(&pHead,0);
	PushBack(&pHead,1);
	PushBack(&pHead,2);
	PushBack(&pHead,3);
	PushBack(&pHead,4);
	PrintList(&pHead);

	//Erase(&pHead,Find(&pHead,2));
	Erase(&pHead,Find(&pHead,4));
	//Erase(&pHead,Find(&pHead,0));
	PrintList(&pHead);

	Insert(&pHead,Find(&pHead,2),8);
	Insert(&pHead,Find(&pHead,0),9);
	PrintList(&pHead);

	DestroyList(&pHead);
	PrintList(&pHead);
}
int main()
{
	//Test1();
	//Test2();
	Test3();
	system("pause");
	return 0;
}</span></strong>


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值