链表的相关操作

 

 

链表插入

  1. 要有空间
  2. 把数据装进去
  3. 把空间结点链接进去

          1)把链子拆开

          2)把上段的next连接到新节点上

          3)把新节点的next连接到原来的下半段

          4)千万别把指针丢了

 

 

 

 

链表销毁

  1. 遍历链表
  2. 把空间释放掉

尾删

  1. 拆链子(找对地方)
  2. 把空间free
  3. 把上半段直接连到下半段

常用定义

typedef int DataType;//值类型
typedef struct SList创建链表//创建链表
{
	DataType data;
	struct SList *pNext;
}	SList;


void Init(SList * *ppHead)//初始化
{
	*ppHead = NULL;
}

static SList * BuyNewNode(DataType data)
{
	SList *pNewNode = (SList *)malloc(sizeof(SList));
	assert(pNewNode);
	pNewNode->data = data;
	pNewNode->pNext = NULL;

	return pNewNode;
}

/*
	1. 要有空间
	2. 把数据装进去
	3. 把空间结点链接上去
		1) 把链子拆开
			1) 找到拆的地方
		2) 把上半段的 next 连到新结点上
		3) 把 新结点的 next 连到原来的下半段
		4) ** 千万把指针丢了
*/
//尾插
void PushBack(SList **ppHead, DataType data)
{
	SList *pNewNode = BuyNewNode(data);

	// 空
	if (*ppHead == NULL) {
		*ppHead = pNewNode;
		return;
	}

	// 正常情况
	//  找倒数第一个
	SList *pNode = *ppHead;
	while (pNode->pNext != NULL) {
		pNode = pNode->pNext;
	}

	pNewNode->pNext = pNode->pNext;
	pNode->pNext = pNewNode;
	
}
//头插
void PushFront(SList **ppHead, DataType data)
{
	SList *pNewNode = BuyNewNode(data);

	pNewNode->pNext = *ppHead;
	*ppHead = pNewNode;
}


// 尾删
void PopBack(SList **ppHead)
{
	if (*ppHead == NULL) {
		printf("已经是空的了\n");
		return;
	}

	if ((*ppHead)->pNext == NULL) {
		free(*ppHead);
		*ppHead = NULL;
		return;
	}

	// 倒数第二个
	SList *pNode, *pNext;
	pNode = *ppHead;
	while (pNode->pNext->pNext != NULL) {
		pNode = pNode->pNext;
	}

	pNext = pNode->pNext;
	pNode->pNext = pNext->pNext;
	//pNode->pNext = NULL;
	free(pNext);
}

// 头删
void PopFront(SList **ppHead)
{
	// 判断是否为空链表
	if (*ppHead == NULL) {
		printf("已经是空的了\n");
		return;
	}

	// 正常情况
	SList *pHead = *ppHead;
	SList *pNext = pHead->pNext;
	free(pHead);
	*ppHead = pNext;
}
//任意插入
void Insert(SList **ppHead, SList *pPosNode, DataType data)
{
	// 1. 找拆链子
	// 2. Buy 结点
	// 3. 把新结点挂在链子上
	// 指针丢掉
	// 特殊情况考虑
	// 定义域
	// pPosNode 一定是在链子里的吧

	//下面的特殊的情况
	//如果是空链表
	if (*ppHead == NULL && pPosNode == NULL) {
		*ppHead = BuyNewNode(data);
		return;
	}
	//在头的位置插入
	if (*ppHead == pPosNode) {
		PushFront(ppHead, data);
		return;
	}

	SList *pNode;
	for (pNode = *ppHead; pNode->pNext != pPosNode; pNode = pNode->pNext) {
	}

	SList *pNewNode = BuyNewNode(data);
	pNewNode->pNext = pPosNode;
	pNode->pNext = pNewNode;
}

int Size(SList *pHead)
{
	int size = 0;
	SList *pNode;

	for (pNode = pHead; pNode != NULL; pNode = pNode->pNext) {
		size++;
	}

	return size;
}
//找某节点(pPosNode)并删除
void Erase(SList **ppHead, SList *pPosNode)
{
	if (*ppHead == pPosNode) {
		PopFront(ppHead);
		return;
	}

	SList *pNode;
	// 结束后 pNode 就是 pPosNode 的前一个
	for (pNode = *ppHead; pNode->pNext != pPosNode; pNode = pNode->pNext) {
	}

	pNode->pNext = pPosNode->pNext;
	free(pPosNode);
}
//按值查找,返回找到的结点
// 如果找到就返回 装数据的结点指针
// 如果没找到就返回 NULL
SList * Find(SList *pHead, DataType data)
{
	SList *pNode;
	for (pNode = pHead; pNode != NULL; pNode = pNode->pNext) {
		if (pNode->data == data) {
			return pNode;
		}
	}

	return NULL;
}



// 按值删除,只删遇到的第一个
// O(N)
void Remove(SList **ppHead, DataType data)
{
	SList *pPosNode = Find(*ppHead, data);
	if (pPosNode != NULL) {
		Erase(ppHead, pPosNode);
	}
}
//按值删除,删所有
void RemoveAll(SList **ppHead, DataType data)
{
	SList *pNode = *ppHead;
	SList *pDel;

	while (pNode->pNext != NULL) {
		if (pNode->pNext->data == data) {
			pDel = pNode->pNext;
			pNode->pNext = pDel->pNext;
			free(pDel);
		} else {
			pNode = pNode->pNext;
		}
	}

	if ((*ppHead)->data == data) {
		PopFront(ppHead);
	}
}
//销毁
void Destroy(SList **ppHead)
{
	SList *pNode, *pNext;
	for (pNode = *ppHead; pNode != NULL ; pNode =pNext) {
		pNext = pNode->pNext;
		free(pNode);
	}

	*ppHead = NULL;
}

//打印
void Print(SList *pHead)
{
	SList *pNode;
	for (pNode = pHead; pNode != NULL; pNode = pNode->pNext) {
		printf("%2d -> ", pNode->data);
	}

	printf("NULL\n");
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值