链表的删除和插入有异曲同工之处,只要明白其原理,就可以顺手使用,通过判断头删除与中间删除,但是中间删除时如果不加入判断是否删除的是尾结点,则会使尾结点变成是删除的地址。
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int id;
struct node *pNext;
}List;
void addnode(List **pphead,List **ppend,int id);
void deletenode(List **pphead,List **ppend,int id);
int main()
{
List *phead = NULL;
List *pend = NULL;
addnode(&phead,&pend,1);
addnode(&phead,&pend,2);
addnode(&phead,&pend,3);
addnode(&phead,&pend,4);
addnode(&phead,&pend,5);
/*deletenode(&phead,&pend,1);*/
deletenode(&phead,&pend,5);
while (phead != NULL)
{
printf("%d\n",phead ->id);
phead = phead ->pNext;
}
return 0;
}
void addnode(List **pphead,List **ppend,int id)
{
List *ptemp = (List *)malloc(sizeof(List));
ptemp ->id = id;
ptemp ->pNext = NULL;
if(*pphead == NULL)
{
(*pphead) = ptemp;
}
else
{
(*ppend) ->pNext = ptemp;
}
*ppend = ptemp;
}
void deletenode(List **pphead,List **ppend,int id)
{
List *pDel = NULL;
List *pMark = *pphead;
//头删除
if((*pphead) ->id == id)
{
//删除标记指向头节点
pDel = *pphead;
//头指针指向头的的下一个
*pphead = (*pphead) ->pNext;
//释放删除标记
free(pDel);
pDel == NULL;
return;
}
//2.中间删除
while(pMark ->pNext !=NULL)
{
//遍历标记停在删除节点的前一个上
if(pMark ->pNext ->id == id)
{
//删除标记指向遍历标记的下一个
pDel = pMark ->pNext;
//遍历标记的下一个指向遍历标记下一个的下一个
pMark ->pNext = pMark ->pNext ->pNext;
//释放删除标记
free(pDel);
pDel = NULL;
//判断是否删除的是尾节点
if(pMark -> pNext == NULL)
{
*ppend = pMark;
}
return;
}
pMark = pMark ->pNext;
}
}