基于单链表的通讯录

还记得当时刚接触C语言不久,当时就感觉学的已经可以了,就试着自己做了一个基于链表的通讯录小项目,这个过程真的不堪回首。原本以为自己已经学的不错了,真正进行实战的时候才发现自己还有很多不足之处。做通讯录的这个过程中,遇到了很多问题,不过最后还是通过各种查资料完成了。做完之后真的很爽,对自己所学东西的一个融汇。里面用到了关于链表的各种操作,插入、删除、查询、修改等,关于文件的读取和保存,还有多种排序算法(主要是快速排序和堆排序)。

下面通讯录的源代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define T 1
#define F 0

typedef int ElementType;
typedef int Status;

struct xinxi
{
char name[20];
char tel[20];
char ID[20];
char address[20];
char hometel[20];
struct xinxi *next;
};
typedef struct xinxi Xinxi;


Status init(Xinxi **p);
Status shuru(Xinxi *p);
void xianshi(Xinxi *p,char *a[],char *b[],int low,int high,int len,int len1);
Status chaxun(Xinxi *p);
Status IDsearch(Xinxi *p);
Status namesearch(Xinxi *p);
Status telsearch(Xinxi *p);
Status shanchu(Xinxi *p);
Status IDdelete(Xinxi *p);
Status namedelete(Xinxi *p);
Status teldelete(Xinxi *p);
Status xiugai(Xinxi *p);
Status baocun(Xinxi *p);
Status read_file(Xinxi *p);
int length(Xinxi *P,char *a[]);
Status pivokey1(char *a[],int low,int high);
void quicksort(char *a[],int low,int high);
void print(Xinxi *p,char *a[],int len);
int length1(Xinxi *p,char *b[]);
void heapadjust(char *b[],int n,int m);
void heap(char *b[],int len1);
void print1(Xinxi *p,char *b[],int len1);


int main()
{
Xinxi *head;
init(&head);
read_file(head);
char *a[100];
char *b[100];
int len;
int len1;
//printf("%d\n",len);
char ch;
while(1)
{
printf("\n\n");
printf("                             ☆ 通讯录管理系统☆\n");
printf("             ***********************************************\n");
printf("             *              1. 通讯录信息输入                       *\n");
printf("             *              2. 显示通讯录信息                       *\n");
printf("             *              3. 通讯录记录查询                       *\n");
printf("             *              4. 修改通讯录信息                       *\n");
printf("             *              5. 通讯录记录删除                       *\n");
printf("             *              6. 退出通讯录程序                       *\n");
printf("             ***********************************************\n");
printf("                           请输入代码选择(1-6):\n");


ch = getchar();
getchar();


switch(ch)
{
case '1':
shuru(head);
baocun(head);
break;
case '2':
len = length(head,a);
len1 = length1(head,b);
xianshi(head,a,b,0,len - 1,len,len1);
break;
case '3':
chaxun(head);
break;
case '4':
xiugai(head);
baocun(head);
break;
case '5':
shanchu(head);
baocun(head);
break;
case '6':
return;
default:
continue;                
}
}

return 0;
}

Status init(Xinxi **p)
{
Xinxi *newnode = (Xinxi*)malloc(sizeof(Xinxi));
if(NULL == newnode)
{
return F;
}
newnode->next = NULL;
*p = newnode;
return T;
}


Status shuru(Xinxi *p)
{
Xinxi *newnode = (Xinxi*)malloc(sizeof(Xinxi));
if(NULL == newnode)
{
return F;
}
while(NULL != p->next)
{
p = p->next;
}
printf("请输入联系人ID\n");
gets(newnode->ID);
printf("请输入联系人姓名\n");
gets(newnode->name);
printf("请输入联系人手机:\n");
gets(newnode->tel);
printf("请输入联系人家庭电话\n");
gets(newnode->hometel);
printf("请输入联系人地址\n");
gets(newnode->address);
if(strlen(newnode->tel) != 11 || strlen(newnode->hometel) != 7)
{
printf("输入错误!\n");
return F;
}
newnode->next = NULL;
p->next = newnode;
printf("输入成功!\n");
return T;
}


Status chaxun(Xinxi *p)
{
char n;
while(1)
{
printf("\n");
printf("1. 按ID查询\n");
printf("2. 按姓名查询\n");
printf("3. 按手机查询\n");
printf("4. 查询结束\n");
printf("请选择:\n");


n = getchar();
getchar();


switch(n)
{
case '1':
IDsearch(p);
break;
case '2':
namesearch(p);
break;
case '3':
telsearch(p);
break;
case '4':
return;
default:
continue;                
}
}
}


Status IDsearch(Xinxi *p)
{
char a[20];
int flag = 0;
printf("请输入联系人ID:\n");
gets(a);
while(NULL != p->next)
{
if(strcmp(p->next->ID,a) == 0)
{
printf("ID:%s\t姓名:%s\t手机:%s\t家庭电话:%s\t地址:%s\t\n",p->next->ID,p->next->name,p->next->tel,p->next->hometel,p->next->address);
flag = 1;
}
p = p->next;
}
if(flag == 0)
{
printf("没有此联系人!\n");
return F;
}
return T;
}


Status namesearch(Xinxi *p)
{
char a[20];
int flag = 0;
printf("请输入联系人姓名!\n");
gets(a);
while(NULL != p->next)
{
if(strcmp(p->next->name,a) == 0)
{
printf("ID:%s\t姓名:%s\t手机:%s\t家庭电话:%s\t地址:%s\t\n",p->next->ID,p->next->name,p->next->tel,p->next->hometel,p->next->address);
flag = 1;
}
p = p->next;
}
if(flag == 0)
{
printf("没有此联系人!\n");
return F;
}
return T;
}


Status telsearch(Xinxi *p)
{
char a[20];
int flag = 0;
printf("请输入联系人手机!\n");
gets(a);
while(NULL != p->next)
{
if(strcmp(p->next->tel,a) == 0)
{
printf("ID:%s\t姓名:%s\t手机:%s\t家庭电话:%s\t地址:%s\t\n",p->next->ID,p->next->name,p->next->tel,p->next->hometel,p->next->address);
flag = 1;
}
p = p->next;
}
if(flag == 0)
{
printf("没有此联系人!\n");
return F;
}
return T;
}


Status shanchu(Xinxi *p)
{
char n;
while(1)
{
printf("\n");
printf("1. 按ID删除\n");
printf("2. 按姓名删除\n");
printf("3. 按手机删除\n");
printf("4. 删除结束\n");
printf("请选择:\n");


n = getchar();
getchar();


switch(n)
{
case '1':
IDdelete(p);
break;
case '2':
namedelete(p);
break;
case '3':
teldelete(p);
break;
case '4':
return;
default:
continue;                
}
}
}


Status IDdelete(Xinxi *p)
{
char a[20];
int flag = 0;
printf("请输入要删除联系人ID:\n");
gets(a);
while(NULL != p->next)
{
if(strcmp(p->next->ID,a) == 0)
{
flag = 1;
Xinxi *temp = p->next;
p->next = temp->next;
free(temp);
printf("删除成功!\n");
}
else
{
p = p->next;
}
}
if(flag == 0)
{
printf("无此联系人!\n");
return F;
}
return T;
}


Status namedelete(Xinxi *p)
{
char a[20];
int flag = 0;
printf("请输入要删除联系人姓名:\n");
gets(a);
while(NULL != p->next)
{
if(strcmp(p->next->name,a) == 0)
{
flag = 1;
Xinxi *temp = p->next;
p->next = temp->next;
free(temp);
printf("删除成功!\n");
}
else
{
p = p->next;
}
}
if(flag == 0)
{
printf("无此联系人!\n");
return F;
}
return T;
}


Status teldelete(Xinxi *p)
{
char a[20];
int flag = 0;
printf("请输入要删除联系人手机:\n");
gets(a);
while(NULL != p->next)
{
if(strcmp(p->next->tel,a) == 0)
{
flag = 1;
Xinxi *temp = p->next;
p->next = temp->next;
free(temp);
printf("删除成功!\n");
}
else
{
p = p->next;
}
}
if(flag == 0)
{
printf("无此联系人!\n");
return F;
}
return T;
}


Status xiugai(Xinxi *p)
{
int flag = 0;
char a[20];
printf("请输入要修改人姓名:\n");
gets(a);
while(NULL != p->next)
{
if(strcmp(p->next->name,a) == 0)
{
flag = 1;
printf("请修改信息:\n");
printf("请输入ID:\n");
gets(p->next->ID);
printf("请输入姓名:\n");
gets(p->next->name);
printf("请输入手机:\n");
gets(p->next->tel);
printf("请输入家庭电话:\n");
gets(p->next->hometel);
printf("请输入地址:\n");
gets(p->next->hometel);
printf("修改信息成功!\n");
}
p = p->next;
}
if(flag == 0)
{
printf("没有此联系人!\n");
return F;
}
return T;
}


Status baocun(Xinxi *p)
{
FILE *fp = fopen("/mnt/hgfs/share/xiangmu/tongxunlu.txt","w+");
if(NULL == fp)
{
perror("fopen");
return F;
}
int i = 1;
while(NULL != p->next)
{
fprintf(fp,"%d ",i);
fprintf(fp,"%s\t%s\t%s\t%s\t%s\r\n",p->next->ID,p->next->name,p->next->tel,p->next->hometel,p->next->address);
p = p->next;
i++;
}
fprintf(fp,"%d ",0);
fclose(fp);
return T;
}


Status read_file(Xinxi *p)
{
int flag;
FILE *fp = fopen("/mnt/hgfs/share/xiangmu/tongxunlu.txt","r+");
if(NULL == fp)
{
perror("fopen");
return F;
}


Xinxi *newnode;
fscanf(fp,"%d",&flag);
while(flag)
{
newnode = (Xinxi*)malloc(sizeof(Xinxi));
if(NULL == newnode)
{
return F;
}
while(NULL != p->next)
{
p = p->next;
}
fscanf(fp,"%s%s%s%s%s",newnode->ID,
newnode->name,newnode->tel,newnode->hometel,newnode->address);
newnode->next = p->next;
p->next = newnode;
fscanf(fp,"%d",&flag);

fclose(fp);
return T;   
}


void xianshi(Xinxi *p,char *a[],char *b[],int low,int high,int len,int len1)
{
char n;
while(1)
{
printf("1. 按姓名排序显示\n");
printf("2. 按ID排序显示\n");
printf("3. 退出显示\n");
printf("请选择:\n");


n = getchar();
getchar();
switch(n)
{
case '1':
quicksort(a,0,len - 1);
print(p,a,len);
break;
case '2':
heap(b,len1);
print1(p,b,len1);
break;
case '3':
return;
default:
continue;            
}
}
}


int length(Xinxi *p,char *a[])
{
int i = 0;
while(NULL != p->next)
{
a[i] = (char*)malloc(sizeof(char));
a[i] = p->next->name;
p = p->next;
i++;
}
return i;
}


int pivokey1(char *a[],int low,int high)
{
char *pivot = a[low];
while(low < high)
{
while(low < high && strcmp(a[high],pivot) >= 0)
high--;
a[low] = a[high];
while(low < high && strcmp(a[low],pivot) <= 0)
low++;
a[high] = a[low];
}


a[low] = pivot;
return low;
}


void quicksort(char *a[],int low,int high)
{
if(low < high)
{
int pivotkey = pivokey1(a,low,high);
quicksort(a,low,pivotkey-1);
quicksort(a,pivotkey+1,high);
}    
}


void print(Xinxi *p,char *a[],int len)
{
Xinxi *head = p;
int i;
for(i = 0;i < len;i++)
{
while(NULL != p->next)
{
if(strcmp(a[i],p->next->name) == 0)
{
printf("ID:%s\t姓名:%s\t手机:%s\t家庭电话:%s\t地址:%s\n"
,p->next->ID,p->next->name,p->next->tel,p->next->hometel,p->next->address);
}
p = p->next;
}
p = head;
}
}


int length1(Xinxi *p,char *b[])
{
int i = 0;
while(NULL != p->next)
{
b[i] = (char*)malloc(sizeof(char));
b[i] = p->next->ID;
p = p->next;
i++;
}
return i;
}


void heapadjust(char *b[],int n,int m)
{
int i;
char *temp = b[n];
for(i=2*n+1;i <= m;i = 2*i+1)
{
if(i < m && strcmp(b[i],b[i + 1]) == -1)
i++;
if(strcmp(b[i],temp) == -1)
break;
b[n] = b[i];
n = i;
}
b[n] = temp;
}


void heap(char *b[],int len1)
{
int i;
char *temp;
for(i = (len1-2)/2;i>=0;i--)
{
heapadjust(b,i,len1-1);
}
for(i = len1-1;i >= 0;i--)
{
//swap(arr,0,i);
temp = b[i];
b[i] = b[0];
b[0] = temp;
heapadjust(b,0,i-1);
}
}


void print1(Xinxi *p,char *b[],int len1)
{
Xinxi *head = p;
int i;
for(i = 0;i < len1;i++)
{
while(NULL != p->next)
{
if(strcmp(b[i],p->next->ID) == 0)
{
printf("ID:%s\t姓名:%s\t手机:%s\t家庭电话:%s\t地址:%s\n"
,p->next->ID,p->next->name,p->next->tel,p->next->hometel,p->next->address);
}
p = p->next;
}
p = head;
}
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
将全班同学的通讯信息存入一个单链表。元素中的通讯信息包括每一位同学的:学号、姓名、性别、宿舍、联系电话等。要求能够利用姓名和序号进行有关查找、插入、删除、更新等操作。 (1)以单链表作为存储班级通讯录的存储结构,首先需要定义一个单链表数据结构,其中每个元素是一条同学通讯信息,包括学号、姓名、性别、宿舍、联系电话等字段。 (2)将本班的通讯信息输入文本文件“通讯录.txt”中,需要实现文件读写功能。当程序启动时,需要将文件中的信息读入单链表中,当程序结束时,需要将内存中的通讯录单链表中的信息重新写入文件。 (3)需要实现向单链表中追加一条通讯录记录的功能,即单链表的插入功能。通过提示信息,让用户将一条通讯录记录的各个字段信息输入内存,构成一个单链表元素,然后将其作为一个整体插入单链表最后一条记录之后,该功能在读取文件信息,创建单链表是也需要用到。 (4)需要实现查询功能,包括通过姓名查询:给定一个姓名,返回其通讯信息和在表中的位置;通过序号查询:给定一个姓名,返回其通讯信息和在表中的位置。 (5)需要实现在给定位置增加一条记录的功能,该位置可以直接设定,也可以通过查询得到,比如先查到姓名为“XXX”的学生的通讯信息在表中的位置,然后在该记录的后面插入一条新的记录。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值