目录
1.typedef struct Node* LinkList;<==等价于==>Node* LinkList;
注意:
1.typedef struct Node* LinkList;<==等价于==>Node* LinkList;
2.空链表与链表不存在搞清楚
空链表就是有头结点但是没有第一个存储数据的结点,
链表不存在(即连头结点的空间都没有分配,也就是说头指针指向为空,即头指针内自己的空间内存储的地址为空) ;
3.工作指针P与暂存指针Q(一般习惯是S)
工作指针P和暂存指针Q,之所以叫做暂存指针是因为他的作用只是暂时存储一些要删除结点的地址.
4.C++的NULL与C语言的NULL有什么不同?
可以看出c++中 NULL为(int)0 , C中NULL为(void*)0。看来C和C++中NULL宏的值略有不同
//注意: 1.typedef struct Node* LinkList;<==等价于==>Node* LinkList;
//2.空链表与链表不存在搞清楚
//不能为空链表,或者是链表不存在(即连头结点的空间都没有分配,也就是说头指针指向为空,即头指针内自己的空间内存储的地址为空) ;
//3.工作指针P和暂存指针Q,之所以叫做暂存指针是因为他的作用只是暂时存储一些要删除结点的地址.
//4.可以看出c++中 NULL为(int)0 , C中NULL为(void*)0。看来C和C++中NULL宏的值略有不同
//头文件
#include<stdlib.h> //free()函数在这个头文件中
//宏定义
#define OK 1
#define ERROR 0
//取别名
typedef int Status;
//结点类型
typedef struct Node{
Status data;
struct Node * Next;
}Node;
//取别名
typedef struct Node* LinkList;//如果上方定义结点类型的时候。取了别名为Node的话,其实可以写成Node* LinkList;
//typedef struct Node* LinkList;<==等价于==>Node* LinkList;
//删除链表操作
//参数:*L,i,*e;*L表明L是一个二级指针,便于该函数对真正的链表进行操作,*e是为了返回删除的结点的数据域内的值;
//初始条件:不能为空链表,或者是链表不存在(即连头结点的空间都没有分配,也就是说头指针指向为空,即头指针内自己的空间内存储的地址为空) ;
Status DeleteList(LinkList *L,Status i,Status *e){
//操作过程:1. 判断是否为空链表或者是该链表压根就不存在,如果是就返回ERROR
if(!((*L)->Next) || !(*L)){
return ERROR;
}
// 2.走到这里说明链表是正常的,那么就开始判断删除的位置i是否是正常的,定义工作指针P,从前向后一个个指向每一个结点,如果在找到第i个之前工作指针P为空,那么说明位置不合适
LinkList P=(*L);//注意在删除和插入的时候一定要把工作指针开始的位置定为头结点,因为头结点的作用就是这,让第一个存储数据的结点的操作和其他结点一致。
int j=1;
printf("%d",P);
printf("%d",&P);
while(j<i && P){
P=P->Next;
j++;
}
if(!P || j>i){//防止i不正常,即i可能为0或负数。如果P此时为空说明i的位置还是不正常,i超过了链表长度。
return ERROR;
}
// 3.因为一个P是工作指针,一个工作指针无法完成删除的工作,所以需要定义一个指向被删除结点的指针来帮助完成删除操作。
// 并且取出Q指针所指向的结点的数据域内的值给整型指针e所指向的空间。即回调
LinkList Q;
Q=P->Next;
*e=Q->data;
// 4.走到这里说明链表和插入位置都是正常的,并且此时工作指针P正在指向要删除的结点的前驱结点,那么就将目前Q暂存指针所指向的结点的左右关系更改好。
P->Next=Q->Next;//即将Q的下一个结点的地址给P所指向的结点的指针域.
// 5.释放此时暂存指针Q所指向的结点的空间并返回OK。
free(Q);
}
//操作结果:删除了该链表中的除了头结点外的第i个结点,并且返回删除的结点的数据域内的值。