C++语言实现单链表的尾插,尾删,头插,头删等

#include <stdio.h>
#include <stdlib.h>
#pragma once
typedef int DataType;//因为PushBack要返回的类型如果需要换,在这里直接替换int就可以了,不用每个函数都换
typedef struct Node//宏定义和typedef都是一种可维护性代码
{
DataType data;//定义一个DataType类型的数据data
struct Node* next;//因为此Node只能在后面用,所以用struct
}Node;
Node* BuyNode(DataType x)//指针
{
Node* node = (Node*)malloc(sizeof(Node));//给node申请一个空间,他是一个指针
node->data = x;//它所指向的数据是x
node->next = NULL;//它所指向的下一个为null
return node;//返回node
}
//动态开辟的内存按需所取
//1、尾插
void PushBack(Node** ppHead, DataType x)//指向头指针的指针pHead,插入元素x
{
if (*ppHead == NULL)//第一:如果头指针的为空,说明没元素
{
*ppHead = BuyNode(x);//给头指针一个函数,此函数得到指向该插入元素x的指针,把x放进去
}
else//第二:如果头指针不为空,说明有节点,如何找到最后一个节点
{
Node* tail = *ppHead;//把头指针给指针tail
while (tail->next)//只要指针tail指向的下一个节点不为空,就一直循环
{
tail=tail->next;//指针tail不断向后移动
}
tail->next = BuyNode(x);//直到跳出循环,则说明指针tail指向最后一个节点了,让他的下一个节点指针为指向x的指针
}
}
void PrintList(Node* pHead)
{
Node* cur = pHead;//定义一个指向当前节点的指针cur,指向头节点
while (cur)//直到当前节点cur不存在
{
printf("%d", cur->data);//打印当前指针指向的节点
cur = cur->next;//满足循环条件就一直向后移动,直到当前指着指向的节点不存在停止
}
printf("\n");
}
void TestList1()
{
Node* list = NULL;
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PrintList(list);
}
输出结果是1234,都插进去了
------------------------------------------------------------------------------------------


//2、尾删
//把尾free掉,把prev的next置空
//第一是空的,不用删了
//第二不是空的,有一个节点,把它free掉,让指向头结点的指针指向NULL
//第三不是空的,有两个及以上的节点,找到最后一个,free掉,再找到倒数第二个节点,让它的指针域指向NULL
void PopBack(Node** ppHead)//里面改变外面才会改变
{
if(*ppHead==NULL)//没有节点
{
return;
}
else if ((*ppHead)->next == NULL)//一个节点
{
free(*ppHead);
*ppHead = NULL;
}
else//多个节点
{
Node* cur = *ppHead;//给一个指向当前节点的指针cur,然它目前指向头结点
Node* prev = NULL;//给一个prev来保存cur的前一个指针
while (cur->next)
{
prev = cur;//cur走之前,把cur给prev保存
cur = cur->next;//直到cur走到尾,prev就指向倒数第二个
}
prev->next = NULL;
free(cur);
}

}
//打印
void PrintList(Node* pHead)
{
Node* cur = pHead;//定义一个指向当前节点的指针cur,指向头节点
while (cur)//直到当前节点cur不存在
{
printf("%d", cur->data);//打印当前指针指向的节点
cur = cur->next;//满足循环条件就一直向后移动,直到当前指着指向的节点不存在停止
}
printf("\n");
}
void TestList1()
{
Node* list = NULL;
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PrintList(list);
PopBack(&list);
PopBack(&list);
PrintList(list);
}
输出结果是
1234
12
------------------------------------------------------------------------------------------
//3、头插
//第一种无节点,直接插入
//第二种有节点,给x一个指针,让它指向*ppHead,再让*ppHead指向x
void PushFront(Node** ppHead, DataType x)
{
if (*ppHead == NULL)//无节点
{
*ppHead = BuyNode(x);
}
else//有节点
{
Node* tmp = BuyNode(x);//给x一个指针tmp
tmp->next = *ppHead;//把tmp放在头指针的前面
*ppHead = tmp;//让头指针指向新的头结点
}
}
void TestList1()
{
Node* list = NULL;
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PrintList(list);
PopBack(&list);
PopBack(&list);
PrintList(list);
PushFront(&list, 8);
PrintList(list);
}
输出结果
1234
12
812
-----------------------------------------------------------------------------------------
//4、头删
//第一种无节点,直接return
//第二种有一个节点,free掉,*ppHead=NULL
//第三种有两个及以上的节点,头指针指向第二个节点,free掉第一个节点
void PopFront(Node** ppHead)
{
if (*ppHead == NULL)
{
return;
}
else if ((*ppHead)->next == NULL)
{
free(*ppHead);
*ppHead = NULL;
}
else
{
Node* next = (*ppHead)->next;//找出第二个节点,并保留指向他的指针
free(*ppHead);
*ppHead = next;
}
}
void TestList1()
{
Node* list = NULL;
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PrintList(list);
//PopBack(&list);
//PopBack(&list);
//PrintList(list);
//PushFront(&list, 8);
//PrintList(list);
PopFront(&list);
PrintList(list);
}
输出结果:
1234
2334
------------------------------------------------------------------------------------------
//5、随机插入
//首先要考虑pos存不存在
//第一种该pos指针就是头指针,也就是说没有节点,直接插入
//第二种有节点,包含头插,分两步,把要插入的前面的指针指向x,x的指针指向pos
void Insert(Node** ppHead, Node* pos, DataType x)
{
assert(pos);//断言保证pos存在
if (pos == *ppHead)
{
PushFront(ppHead, x);
}
else
{
Node* tmp = BuyNode(x);
Node* prev =  *ppHead;
while ((prev->next)!=pos)
{
prev = prev->next;
}
prev->next = tmp;
tmp->next = pos;
}
}
void TestList1()
{
Node* list = NULL;
Node* pos = NULL;
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PrintList(list);
pos = list;
pos = pos->next;
Insert(&list, pos, 6);
PrintList(list);
}
结果:
1234
16234
-------------------------------------------------------------------------------------------
//6、删除
//第一种头删,第二种尾删
//第三种中间删,要找他的前一个和后一个
void Erase(Node** ppHead, Node* pos)
{
assert(pos);
if (pos == *ppHead)
{
PopFront(ppHead);//头删
}
else if (pos->next == NULL)
{
PopBack(ppHead);//尾删
}
else
{
Node* prev = *ppHead;
Node* next = pos->next;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = next;
free(pos);
}
}
void TestList1()
{
Node* list = NULL;
Node* pos = NULL;
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PrintList(list);
pos = list;
pos = pos->next;
Erase(&list, pos);
PrintList(list);
}
结果:
1234
134
------------------------------------------------------------------------------------------
//7、查找
Node* Find(Node* pHead, DataType x)
{
Node* cur = pHead;
while (cur)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
void TestList1()
{
Node* list = NULL;
Node* pos = NULL;
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PrintList(list);
        pos = Find(list, 3);
Erase(&list, pos);
PrintList(list);
}
结果:
1234
124
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值