文章目录
头文件 宏定义 部分变量
#include <stdio.h>
#include <stdlib.h>
#define OVERFLOW -2
#define ERROR 0
#define OK 1
typedef int Status;
typedef int Elemtype;
typedef struct LNode{
Elemtype data;
struct LNode * next;
}LNode,* LinkList;
Elemtype flag=0;//flag用于判断链表是否初始化 0:未初始化 1:已初始化
Elemtype cflag=0;//cflag用于判断链表是否为空 0:空 1:不空
初始化一个空的链表
注:L是指向头结点的指针(也叫头指针,不知道什么是头结点,首元结点,好吧,简要说下)
首元结点:是指链表中用来存储数据元素的节点中的第一个节点
头结点:指在链表的首元节点之前附设的一个结点,数据域内只放空表标 志和表长等信息,也可以什么都不放
什么?为什么要这样设置?
这。。。。。。。
当然是因为这是前辈们的智慧喽
单链表头结点、首元节点详解
嗯,为什么形参定义是LinkList * L呢?
因为我们要改变头指针的指向,分配一个大小是LNode的内存空间,让头指针指向它,如果不需要改变头指针的指向,我们就只需要定义成LinkList L即可,然后让头结点的指针域为空,代表这是个空表,返回OK代表初始化成功。
Status InitList(LinkList * L)
{
*L=(LinkList)malloc(sizeof(LNode));
if(!(*L))
{
exit(OVERFLOW);
}
(*L)->next=NULL;
return OK;
}
调用
case 1:
printf("初始化或重置链表\n");
printf("初始化请按1\n");
printf("重置链表请按2\n");
scanf("%d",&elem);
if(elem==1)
{
flag=InitList(&L);
if(flag==0)
printf("初始化失败\n");
else
printf("初始化成功\n");
}
if(elem==2)
{
if(flag==1)
{
cflag=ClearList(L);
printf("链表已清空\n");
}else
{
printf("链表未初始化\n");
}
}
system("pause");
break;
重置链表(清空链表)
使p指向首元结点,如果p不为空,进入循环,让q指向p的后继结点,然后释放p所指向的 结点,p再移到下一个结点,q就像一个引路人,引着 p遍历完链表,释放所有的元素结点。当p指向尾结点进入循环后,q就为空,释放p后,p=q ,p为空,不再执行循环,所有元素结点均被清空。令L的指针域为空,返回ERROR代表空表标志
Status ClearList(LinkList L)
{
LinkList p,q;
p=L->next;
while(p)
{
q=p->next;
free(p);
p=q;
}
L->next=NULL;
return ERROR;
}
调用
case 3:
if(flag!=0)
{
cflag=ClearList(L);
printf("链表已清空\n");
}else
{
printf("链表未初始化\n");
}
system("pause");
break;
销毁链表
遍历,然后释放每个结点所分配的空间。
Status DestroyList(LinkList * L)
{
LinkList p,q;
p=(*L)->next;
while(p)
{
q=p->next;
free(p);
p=q;
}
p=*L;
free(p);
return ERROR;
}
调用
case 2:
if(flag!=0)
{
printf("销毁链表\n");
flag=DestroyList(&L);
printf("销毁成功\n");
}else
{
printf("链表未初始化\n");
}
system("pause");
break;
求链表的长度
定义一个计数器count,遍历到每个结点时,count++;直到遍历到最后一个结点,尾结点的指针域(为空)赋值给p,count+1;无法再次进行循环,返回count;
Status ListLength(LinkList L)
{
Elemtype count=0;
LinkList p;
p=L->next;
while(p)
{
p=p->next;
count++;
}
return count;
}
调用
case 4:
if(flag!=0)
{
printf("链表的长度为%d\n",ListLength(L));
}else
{
printf("链表未初始化\n");
}
system("pause");
break;
求指定位置的元素值
定义一个指针p指向头结点,当i=1时,p=p->next,指向第一个结点,当i=position时,指向所找的位置,返回该位置的数据域即可。
Status GetElem(LinkList L,Elemtype position)
{
Elemtype i;
LinkList p;
p=L;
for(i=1;i<=position;i++)
{
p=p->next;
}
return p->data;
}
调用
case 5:
if(flag!=0)
{
printf("请输入你所查找的位置\n");
scanf("%d",&position);
if(position<=0||position>ListLength(L))
{
printf("不存在这个位置\n");
}else
{
elem=GetElem(L,position);
printf("该位置上的元素是%d\n",elem);
}
}else
{
printf("链表未初始化\n");
}
system("pause");
break;
求指定元素的位序
求位序,我们就要定义一个position,通过遍历结点,找到与elem相等的位置,返回该位序。当position等于1时,p指向第一个结点,判断,若不等,则指向第二个结点,position+1;直到找到position,返回position即可。
Status LocateElem(LinkList L,Elemtype elem)
{
Elemtype position=1;
LinkList p;
p=L->next;
while(p)
{
if(elem==p->data)
break;
p=p->next;
position++;
}
return position;
}
调用
case 6:
if(flag!=0)
{
printf("请输入你所查找的元素\n");
scanf("%d",&elem);
position=LocateElem(L,elem);
if(position>ListLength