有趣的链表相关题型

链表:也是线性表的一种。形象的来说:


就像火车的一个个车厢一样,一个个的链起来的。它有一个特点:它的头没有前驱,尾没有后继。

为什么会引入链表这个概念呢?之前我们知道的顺序表,是用数组的形式保存数据的。它使用起来也非常方便,优点在于它的尾删尾插非常方便,直接将数组空间大小加1,给最后一个数组赋值就ok了。但是对于数组来说,也有一定的缺点。比如:如果在中间插入或删除的话,就得移动一定得位数才可进行相关操作。最坏得情况是你在头插头删的时候,时间的消耗更巨大。为了避免这种重复的移位操作,我们引入了链表这个概念。链表的头插头删就容易多了,只需修改头节点的位置就好啦。

链表的种类很多,有单链表、双向链表、循环链表等。今天我们主要讲单链表。

那么链表的结构是怎么样的呢?

typedef int DataType;

struct Node
{
DataType data;             //节点里存放的数据
struct Node* next;         //指向下一个节点的指针
};

下面我们来一一实现它们吧~

//SList.h
#pragma once
#include<iostream>
using namespace std;
typedef int DataType;
typedef struct Node
{
	int data;
	struct Node* next;
}Node,*pNode;

void InitSlist(pNode *pHead);

void PushBack(pNode *pHead,DataType data);
void PopBack(pNode *pHead);

void PushFront(pNode *pHead,DataType data);
void PopFront(pNode *pHead);
pNode BuyNode(DataType data);
pNode Find(pNode pHead, DataType data);
void Insert(pNode pos, DataType data);                //某个位置插入data

void Erase(pNode* pHead, pNode pos);        //删除位置节点
void Remove(pNode* pHead, DataType data);     //删除某个数据的节点
void RemoveAll(pNode* pHead, DataType data);      //删除所有数据为data的节点
void Destroy(pNode* pHead);                 //销毁
int Empty(pNode pHead);                       //判空
int Size(pNode pHead);                          //节点数目
//SList.cpp
#include"SList.h"
#include<assert.h>

void InitSlist(pNode *pHead)
{
	*pHead = NULL;
}

pNode BuyNode(DataType data)                //创建一个新节点
{
	pNode newNode = (pNode)malloc(sizeof(Node));
	assert(newNode);
	newNode->data = data;
	newNode->next = NULL;
	return newNode;
}

void PushBack(pNode *pHead,DataType data)
{
	
	if(*pHead == NULL)
	{
		*pHead = BuyNode(data);
		(*pHead)->next = NULL;
	}
	else
	{
		pNode pCur = *pHead;
		while(pCur->next)
		{
			pCur = pCur->next;
		}
		pCur->next = BuyNode(data);
	}
}

void PopBack(pNode *pHead)
{
	if(*pHead == NULL)
		return;
	if((*pHead)->next == NULL)
	{
		free(*pHead);
		*pHead = NULL;
	}
	else
	{
		pNode pCur = *pHead;
		pNode pPrev = NULL;
		while(pCur->next)
		{
			pPrev = pCur;
			pCur = pCur->next;
		}
		free(pCur);
		pPrev->next = NULL;
	}
}

void PushFront(pNode *pHead,DataType data)
{
	if(*pHead == NULL)
		*pHead = BuyNode(data);
	else
	{
		pNode cur = BuyNode(data);
		cur->next = *pHead;
		*pHead = cur;
	}
}

void PopFront(pNode *pHead)
{
	if(*pHead == NULL)
		return;
	else
	{
		pNode pDel = *pHead;
		*pHead = (*pHead)->next;
		free(pDel);
	}
}

pNode Find(pNode pHead, DataType data)
{
		pNode pCur = pHead;
		while(pCur)
		{
			if(pCur->data == data)
			{
				return pCur;
			}
			pCur = pCur->next;
		}
		return NULL;
}

void Insert(pNode pos, DataType data)
{
	pNode newNode = BuyNode(data);
	if(pos == NULL)
		return;
	newNode->next = pos->next;
	pos->next = newNode;
}

void Erase(pNode* pHead, pNode pos)
{
	pNode pCur = *pHead;
	if(*pHead == pos && (*pHead)->next == NULL)
	{
		free(pos);
		*pHead = NULL;
		return;
	}
	while(pCur)
	{
		pNode pPrev = pCur;
		while(pPrev->next == pos)
		{
			pNode pDel = pos;
			pPrev->next = pos->next;
			free(pDel);
			return;
		}
		pCur = pCur->next;
	}
	return;
}

void Remove(pNode* pHead, DataType data)
{
	pNode pos = Find(*pHead,data);
	Erase(pHead,pos);
}

void Destroy(pNode* pHead)
{
	while(*pHead)
	{
		pNode pDel = *pHead;
		*pHead = (*pHead)->next;
		free(pDel);
	}
	return;
}

int Empty(pNode pHead)
{
	return pHead == NULL;
}

int Size(pNode pHead)
{
	pNode pCur = pHead;
	int count = 0;
	if(pHead == NULL)
		return 0;
	while(pCur)
	{
		count++;
		pCur = pCur->next;
	}
	return count;
}


void Print(pNode pHead)
{
	pNode pCur = pHead;
	while(pCur)
	{
		cout<<pCur->data<<"->";
		pCur = pCur->next;
	}
	cout<<"NULL"<<endl;
}

对于单链表,我们还有一些有趣的题来和大家分享哦。

有趣的链表问题>>点击进入喽


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值