本篇文章的代码大多使用无头结点的单链表:
相关定义:
#include
#include
#include
typedef int DataType;
typedef struct Linklist{
LDataType data;
struct Linklist *next;
}Linklist,*pLinklist;
相关函数的定义:
pLinklist BuyNewNode(LDataType data); //创建一个数据域为data的新结点
void InitLinklist(pLinklist *pL); //初始化单链表
void PushBackLinklist(pLinklist* pL,LDataType data); //尾插
void PushFrontLinklist(pLinklist *pL,LDataType data); //头插
void PopBackLinklist(pLinklist *pL); //尾删
void PopFrontLinklist(pLinklist *pL); //头删
void PrintLinklist(pLinklist pL); //打印出链表
pLinklist FindLinklist(Linklist *pL,LDataType data); //找到数据域为data的第一个结点
void InsertLinklist(pLinklist *pL,pLinklist p,LDataType data); //指定位置插入
void RemoveLinklist(pLinklist *pL,LDataType data); //删除第一个数据为data的结点
void RemoveAllLinklist(pLinklist *pL,LDataType data); //删除数据为data的全部结点
int IsEmpty(pLinklist pL); //判断单链表是否为空
void DestoryLinklist(pLinklist *pL); //删除整个链表,释放内存
由上面可以看出,只要是涉及到头指针发生改变的,我们在函数中都是传入指向头指针的指针。就像我们在swap函数中要交换a和b的值,我们是传入地址,而现在我们要改变头指针的值,也必须要传入指向头指针的一个指针来进行相关的操作。
此处借鉴了c语言函数传递参数的问题。
下面是对函数的展开,我会比较详细的分析一下函数实现:
0.动态生成新结点
pLinklist BuyNewNode(LDataType data){
pLinklist NewNode = (pLinklist)malloc(sizeof(Linklist));
if(pLinklist == NULL){
printf("空间开辟失败");
return NULL;
}
NewNode->data = data;
NewNode->next = NULL;
return NewNode;
}
1.初始化操作
void InitLinklist(pLinklist *pL){
assert(pL != NULL);
(*pL) = NULL;
}
2.尾插一个数据为data的结点
void PushBackLinklist(pLinklist *pL,LDataType data){
assert(pL != NULL); //大多数中都有这个,是为了防止使用空指针,书中经常会说,千万不要使用空指针,你应该有印象
pLinklist NewNode = BuyNewNode(data);
if(*pL == NULL){ //判断这个是否为空链表
*pL = NewNode;
return ;
}
pLinklist cur = *pL;
while(cur->next != NULL){ //其实这里也可以用cur != NULL,但是上面已经把把空链表大情况写出来了,如果再这样写会重复,不会错,但是复杂一点点
cur = cur->next;
}
cur->next = NewNode;
}
3.头插一个数据为data的结点
void PushFrontLinklist(pLinklsit *pL,LDataType data){
assert(pL != NULL);
pLinklist NewNode = BuyNewNode(data);
if(*pL == NULL){
*pL = NewNode;
return ;
}
NewNode->next = *pL;
*pL = NewNode;
}
4.判断无头链表是否为空
int IsEmptyLinklist(pLinklist pL){
//这里的pL是一个指向链表的指针,而不是一个指向链表指针的指针
return (pL == NULL);
}
5.尾删
void PopBackLinklist(pLinklist *pL){
assert(pL != NULL);
if(IsEmptyLinklist(*pL)){
//*pL是一个指向链表的指针
printf("链表为空");
return ;
}
//尾删需要找到前面那一个结点
pLinklist cur = *pL;
pLinklist pre;
if(cur->next == NULL){
*pL = NULL;
free(cur);
cur = NULL;
return ;
}
while(cur->next){
pre = cur;
cur = cur->next;
}
pre->next = NULL;
free(cur);
cur = NULL;
}
6.头删
void PopFrontLinklist(pLinklist *pL){
assert(pL != NULL);
if(*pL == NULL){
printf("链表为空");
return ;
}
pLinklist p = *pL;
*pL = p->next;
free(p);
p = NULL;
}
7.找到第一个数据为data的结点
pLinklist FindLinklist(pLinklist *pL,LDataType data){
assert(pL != NULL);
plinklist cur = *pL;
while(cur != NULL){
if(cur->data == data){
return cur;
}
cur = cur->next;
}
return NULL;
}
8.在给出的结点之前插入一个数据为data的结点
void InsertLinklist(pLinklist *pL,pLinklist p,LDataType data){
assert(pL != NULL);
pLinklist NewNode = BuyNewNode(data);
pLinklist cur = *pL;
while(cur->next != p){
cur = cur->next;
}
NewNode->next = cur->next;
cur->next = NewNode;
}
9.删除第一个数据为data的结点
void RemoveLinklist(pLinklist *pL,LDataType data){
assert(pL != NULL);
pLinklist cur = FindLinklist(pL,data);
if(cur == NULL){
printf("没找到");
return ;
}
if(cur == *pL){
//刚好在第一个结点
*pL = cur->next;
free(cur);
cur = NULL;
return ;
}
pLinklist p = *pL;
while(p->next != cur){
p = p->next;
}
p->next = cur->next;
free(cur);
cur = NULL;
}
10.删除每一个数据都是data的结点
void RemoveAllLinklist(pLinklist *pL,LDataType data){
assert(pL != NULL); //删除每一个数据域都是data的结点
pLinklist cur = NULL;
pLinklist p = *pL; //pre保存要删除结点的前一个结点
pLinklist pre = *pL;
while(p){
if (p->data == data && (*pL) == p){
//第一个结点是
pre = p;
p = p->next;
*pL = p;
free(pre);
pre = NULL;
}
else if(p->data == data){
//后续结点是
cur = p;
p = p->next;
pre->next = p;
free(cur);
cur = NULL;
}
else{
//此结点不是
pre = p;
p = p->next;
}
}
}
11.打印出链表
void PrintLinklist(Linklist *pL){
pLinklist cur = pL; //打印链表
while(cur){
printf("%d--->",cur->data);
cur = cur->next;
}
printf("NULL\n");
}
12.摧毁链表
void DestoryLinklist(pLinklist *pL){
assert(pL != NULL); //摧毁链表
pLinklist cur = *pL;
pLinklist pre = NULL;
if (*pL == NULL){
printf("链表为空");
return ;
}
if (cur->next = NULL){
*pL = NULL;
free(cur);
cur = NULL;
return ;
}
while(cur){
pre = cur;
cur = cur->next;
free(pre);
pre = NULL;
}
}
添加到短语集
没有此单词集:中文(简体) -> 英语…
创建新的单词集…
拷贝
手机扫一扫
移动阅读更方便
你可能感兴趣的文章