#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 9
#define OK 1
#define FALSE 0
#define Size 5
typedef int LElemType;
typedef int Status;
typedef struct Lnode
{
LElemType data;
struct Lnode *next;
} LNode, *LinkNode;
//初始化
LinkNode init_link();
//循环链表
void foreach_link(LinkNode head);
//插入
LinkNode add_link(LinkNode head, int index, int val);
//删除
LinkNode del_link(LinkNode head, int index);
//根据内容查找
void find_link(LinkNode head, int value);
//根据索引查找
void findIndex_link(LinkNode head, int index);
//判断链表是否为空
Status static_link(LinkNode head);
//清空链表
LinkNode clear_link(LinkNode head);
int main()
{
LinkNode header = init_link();
// add_link(header, 50, 888);
// del_link(header, 30);
// find_link(header, 3);
// findIndex_link(header, 3);
header=clear_link(header);
int a = static_link(header);
printf("a=%d\n", a);
//循环
// foreach_link(header);
return 0;
}
LinkNode init_link()
{
LinkNode head = (LinkNode)malloc(sizeof(LNode));
head->data = -1;
head->next = NULL;
LinkNode p = head;
int val = -1;
while (1)
{
printf("请输入数据");
scanf("%d", &val);
if (val == -1)
break;
LinkNode newNode = (LinkNode)malloc(sizeof(LNode));
newNode->data = val;
newNode->next = NULL;
//TIPS: 构造一个空节点,这样head一直指向头部,p一直指向最后一个节点,新来的节点等于p的下一个就能连起来
p->next = newNode;
p = newNode;
}
return head;
}
void foreach_link(LinkNode head)
{
if (head->next == NULL)
{
printf("空链表");
exit(0);
}
LinkNode p = head->next;
while (p != NULL)
{
printf("%d\n", p->data);
p = p->next;
}
}
LinkNode add_link(LinkNode head, int index, int val)
{
if (head->next == NULL)
{
printf("空链表");
exit(0);
}
LinkNode pPrev = head;
LinkNode pNext = head->next;
//TIPS: 要考虑找不到节点的位置
while (pNext != NULL)
{
if (pNext->data == index)
break;
pPrev = pNext;
pNext = pNext->next;
}
if (pNext == NULL)
{
printf("找不到节点");
exit(0);
}
LinkNode newNode = (LinkNode)malloc(sizeof(LNode));
newNode->data = val;
newNode->next = NULL;
newNode->next = pNext;
pPrev->next = newNode;
return head;
}
LinkNode del_link(LinkNode head, int index)
{
if (head->next == NULL)
{
printf("链表为空");
exit(0);
}
//创造两个辅助指针
LinkNode pPrev = head;
LinkNode pNext = pPrev->next;
while (pNext != NULL)
{
if (pNext->data == index)
break;
pPrev = pNext;
pNext = pNext->next;
}
if (pNext == NULL)
{
printf("删除节点不存在");
exit(0);
}
pPrev->next = pNext->next;
// printf("pPrev=====%p\n",pPrev->next);这里pPrev和pNext都指向同一个地方,都是选中值的下一个地址,经过free之后,pNext变成了指向 随意 地方的野指针,有大小,有pNext自己的地址不变,只是pNext里面的值和下一个指向的地方是 野 的
// printf("pNext=====%p\n",pNext->next);
// free 真正释放的是 pNext 指向的那一块用 malloc 申请的内存空间,因为各个节点都是molloc出来的,一般释放了之后我们会将 pNext = NULL;这样是为了防止 pNext 变成野指针。free并不会释放 pNext 在地址空间申请的本身字节的内存,pNext 还能正常使用,只不过 free 之后 pNext 指向了一个随机的内存地址。
// free(pNext) 之后
// 所指的malloc释放了
// pNext->data为随意的值
// sizeof(pNext)大小和释放前的一样
// pNext地址也和原来的地址一样
// pNext->next指向了随意的方向
free(pNext);
// printf("free(pNext)=====%d\n",pNext->data);//为乱值
// printf("free(pNext)=====%d\n",sizeof(pNext));
// printf("free(pNext)=====%p\n",pNext);
// printf("free(pNext)=====%p\n",pNext->next);//指向随意的地方
pNext = NULL;
return head;
}
void find_link(LinkNode head, int value)
{
if (head->next == NULL)
{
printf("空链表");
exit(0);
}
LinkNode p = head->next;
int count = 1;
while (p != NULL)
{
if (p->data == value)
{
printf("%d\n", count);
break;
}
p = p->next;
count++;
}
if (p == NULL)
{
printf("找不到");
exit(0);
}
}
void findIndex_link(LinkNode head, int index)
{
if (head->next == NULL)
{
printf("链表为空");
exit(0);
}
LinkNode rear = head->next;
int allLength = 1;
while (rear != NULL)
{
rear = rear->next;
allLength++;
}
if (index >= allLength || index < 1)
{
printf("查询位置有问题");
exit(0);
}
LinkNode p = head->next;
if (p == NULL)
{
printf("查找不到");
exit(0);
}
for (int i = 0; i < index - 1; i++)
{
p = p->next;
}
printf("%d\n", p->data);
}
Status static_link(LinkNode head)
{
//TIPS: 可能是初始化的时候给head赋值了-1,所以根据head==NULL判断不了为空,可以根据head->next是否为空
if (head->next == NULL)
{
return FALSE;
}
else
{
printf("%d\n",head->next->data);
return OK;
}
}
LinkNode clear_link(LinkNode head)
{
if(head->next == NULL)
{
printf("空链表");
exit(0);
}
LinkNode pCurrent=head->next;
while(pCurrent!=NULL){
LinkNode p=pCurrent->next;
free(pCurrent);
pCurrent=p;
}
//TIPS: 最好给head一个交代,不然很多事情都是根据head来判断是否为空的
head->next=NULL;
return head;
}