静态链表写通讯录

静态链表写通讯录

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();
	}
}

运行结果如下:在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值