链表插入
- 要有空间
- 把数据装进去
-
把空间结点链接进去
1)把链子拆开
2)把上段的next连接到新节点上
3)把新节点的next连接到原来的下半段
4)千万别把指针丢了
链表销毁
- 遍历链表
- 把空间释放掉
尾删
- 拆链子(找对地方)
- 把空间free
- 把上半段直接连到下半段
常用定义
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");
}