静态链表写通讯录
C语言在没有使用指针之前,前辈们为了弥补数组的不足,就发明了静态链表。静态链表与动态链表最大的不同就是没有使用指针,没有使用malloc函数来动态申请内存,故被称之为静态链表。而它与数组最大的不同就在于,它多了一个游标cur作用类似与链表指针,用来指向下一个节点。
让数组的每个元素由data和cur两部分组成,其中cur相当于链表的next指针,这种用数组描述的链表叫做静态链表,这种描述方法叫做游标实现法。我们对数组的第一个和最后一个元素做特殊处理,不存数据。让数组的第一个元素cur存放第一个备用元素(未被占用的元素)下标,而数组的最后一个元素cur存放第一个有值的元素下标,相当于头结点作用。空的静态链表如下图
用静态链表写了一个通讯录,代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 1000
#define OK 1
#define Error 0
typedef struct Staticdata
{
char name[20];
char num[20];
int cur;
}Staticdata;
Staticdata StaticLinklist[MAXSIZE];//定义一个静态链表
void Welcome(void)
{
printf("----欢迎来到袁强的静态链表通讯录----\n\
请输入以下命令:\n\
1:初始化\n\
2:新增联系人\n\
3:删除联系人\n\
4:显示整个通讯录\n\
5:退出\n\
");
}
int InitLinklit(Staticdata *L)//初始化链表
{
int i = 0;
int k = MAXSIZE-1;//用来保存最后一个数
for (i=0;i< MAXSIZE;i++)
{
(L + i)->cur = i + 1;//初始化游标
}
(L + k)->cur = 0;
return OK;
}
int Getcur(void)//获取备用/空闲链表的下标
{
int i = 0;
i=StaticLinklist[0].cur;
if (i)
{
StaticLinklist[0].cur = StaticLinklist[i].cur;//把下一个分量的地址赋予第一个元素的游标
return i;
}
return Error;
}
int InsertList(int i, char *e, char *b)//在i位置插入一个新的节点
{
int j = 0,k=0,a=0,L=0;
if (i<1||i>MAXSIZE+1)
{
return Error;
}
k = MAXSIZE - 1;
//StaticLinklist[k].cur = 1;
j = Getcur();//把数据插入到空闲位置,并且返回数据所在位置j
strcpy_s(StaticLinklist[j].name,e);//将数据放在空闲位处
strcpy_s(StaticLinklist[j].num,b);//将数据放在空闲位处
for (L=1; L<i; L++)
{
k = StaticLinklist[k].cur;//最后一个节点的游标指向第一个数据下标,于是开始循环直到找到插入位置前一个的下标
}
StaticLinklist[j].cur = StaticLinklist[k].cur;将前一位置要指向的游标赋值给已经插入数据的游标
StaticLinklist[k].cur = j;//让前一位置指向当前数据的下标
}
int DeleteList(char *e)//删除链表
{
int i = 0,k=0,L=0;
k = MAXSIZE - 1;
for (i = 0; i < MAXSIZE && strcmp(StaticLinklist[i].name, e)&&strcmp(StaticLinklist[i].num, e); i++);//如果未到静态链表末尾,并且没有找到name或者num,则一直循环执行。
if (i >= MAXSIZE)
{
printf("没有找到\n");
return Error;
}
while (StaticLinklist[k].cur!=i)//找到要删除节点的前一个位置
{
k = StaticLinklist[k].cur;
}
StaticLinklist[k].cur = StaticLinklist[i].cur;//将要删除节点的下一个位置赋值给上一位的游标
StaticLinklist[0].cur = i;//将i节点标记为空闲游标
}
void Paixu(void)
{
int Length = 0,i=0,j=0;
char num[20] = {0};
Length = StaticLinklist[0].cur-1;
for (i = 1; i < Length; i++)//冒泡排序第一趟进行length-1,后面每一趟依次递减
{
for (j= Length-1;j>0;j--)
{
//第一趟开始的下标从1开始,后面每一趟一次增加,如果第j项大于j+1项就进行交换。
if (strcmp(StaticLinklist[Length -j].num, StaticLinklist[Length +1 - j].num)>0)
{
//先交换电话号码
strcpy_s(num, StaticLinklist[Length - j].num);
memset(StaticLinklist[Length - j].num,0,strlen(StaticLinklist[Length - j].num));
strcpy_s(StaticLinklist[Length - j].num, StaticLinklist[Length + 1 - j].num);
memset(StaticLinklist[Length +1- j].num, 0, strlen(StaticLinklist[Length +1 - j].num));
strcpy_s(StaticLinklist[Length + 1 - j].num, num);
//再交换名字
memset(num,0,sizeof(num));
strcpy_s(num, StaticLinklist[Length - j].name);
memset(StaticLinklist[Length - j].name, 0, strlen(StaticLinklist[Length - j].name));
strcpy_s(StaticLinklist[Length - j].name, StaticLinklist[Length + 1 - j].name);
memset(StaticLinklist[Length +1 - j].name, 0, strlen(StaticLinklist[Length +1 - j].name));
strcpy_s(StaticLinklist[Length + 1 - j].name,num);
}
}
}
}
int Printlist(Staticdata *L)//显示整个通讯录
{
int lenth = 0,i=0;
if (L==NULL)
{
return Error;
}
Paixu();//先进行排序
lenth = L->cur;
if (lenth == 1)
printf("没有数据请输入\n");
for (i=1;i < lenth;i++)//从1开始到空闲链表lenth之前全部打印出来
{
printf("data:%s-%s\n",(L+i)->name,(L+i)->num);
}
return OK;
}
int main(void)
{
int i = 0,j=0;
char c = 0;
char name[20] = { 0 };
char num[20] = { 0 };
Welcome();
while (c!='#')
{
printf("请输入命令:\n");
scanf_s("%c",&c,1);
switch (c)
{
case '1':i = InitLinklit(StaticLinklist);
if (i == Error)
{
printf("Error\n");
exit(0);
}
printf("初始化成功\n");
break;
case '2':
printf("请输入新增联系人的名字 :\n");
scanf_s("%s", name,20);
printf("请输入新增联系人的号码 :\n");
scanf_s("%s", num, 20);
i=InsertList(1,name,num);
if (i == Error)
{
printf("Error\n");
exit(0);
}
printf("新增联系人成功\n");
break;
case '3':
printf("请输入删除联系人的名字/号码:\n");
scanf_s("%s",name,20);
i=DeleteList(name);
if (i == Error)
{
break;
}
printf("删除成功\n");
break;
case '4':
i=Printlist(StaticLinklist);
if (i == Error)
{
printf("Error\n");
exit(0);
}
break;
case '5':c = '#'; break;
}
getchar();
}
}
运行结果如下: