线性表(List):零个或多个数据元素的有限序列。有两种存储结构:顺序存储结构和链式存储结构。
顺序存储结构:用一段地址连续的存储单元依次地存储线性表的数据元素。查找的时间复杂度O(1),删除和插入的时间复杂度为
O(n)。优点:无须为表示表中元素之间的逻辑关系而增加额外的存储空间;可以快速的存取(存每次都在最后位置存)表中任一位置的元素。缺点:插入和删除需要移动大量元素;当线性表长度变化较大时,难以确定存储空间的大小;造成存储空间的碎片。
链式存储结构:多个结点链接成的链表。结点(Node):结构体包括数据域和指针域。
链式存储结构一般分:单链表,循环链表,双向链表等。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#define OK 1
#define ERROR 0
#define MAXSIZE 20
#define MAX 17
#define MAXLIST 30
int length=0;
typedef int Status;
typedef char ElemType;
typedef struct Node
{
ElemType name[MAXSIZE];
ElemType number[MAX];
struct Node *next;
}Node;
typedef Node *LinkList;
void Initlist(LinkList *Lp)//指向(指向node的指针)的指针
{
Node *head=(Node *)malloc(sizeof(Node));
head->next=NULL;
*Lp=head;//头结点赋值给
printf("通讯录初始化成功!");
}
Status Insertlist(LinkList *Lp,ElemType name[],ElemType tel[])
{
Node *p=(Node *)malloc(sizeof(Node));
if (NULL==p)
{
printf("malloc failed");
return ERROR;
}
strcpy(p->name,name);
strcpy(p->number,tel);
LinkList l=*Lp;
while(l->next!=NULL)
{
l=l->next;
}
p->next=NULL;
l->next=p;
length++;
return OK;
}
Status Deletlist(LinkList *Lp,ElemType name[])
{
LinkList l=*Lp;
while(strcmp(l->next->name,name)!=0)
{
l=l->next;
if(l->next==NULL)
{
printf("没有该联系人!");
return ERROR;
}
}
LinkList pt=l->next;
l->next=l->next->next;
free(pt);
length--;
return OK;
}
Status Changelist(LinkList *Lp,ElemType name[])
{
LinkList l=*Lp;
while(strcmp(l->next->name,name)!=0)
{
l=l->next;
}
printf("请输入该联系人的新号码:");
gets(l->next->number);
return OK;
}
Status Printlist(const LinkList *Lp)
{
if((*Lp)->next==NULL)
{
printf("nothing in the list\n");
return ERROR;
}
LinkList p=*Lp;
while(p->next!=NULL)
{
int i=0;
p=p->next;
while(p->name[i]!='\0')
{
printf("%c",p->name[i]);
i++;
}
printf(": ");
puts(p->number);
}
printf("\n");
return OK;
}
void Sortlist(LinkList *Lp)
{
Node *p[MAXLIST]={NULL};
int i,j;
LinkList L=*Lp;
for(i=0;i<MAXLIST;i++)
{
p[i]=L->next;
L=L->next;
if(L->next==NULL)
break;
}
for(i=1;i<length;i++)
{
char ch[MAXSIZE]={0};
Node *tmp=p[i];
strcpy(ch,p[i]->name);
for(j=i-1;j>=0;j--)
{
if(strcmp(p[j]->name,ch)>0)
p[j+1]=p[j];
else
break;
}
p[j+1]=tmp;
}
i=0;
while(p[i]!=NULL)
{
j=0;
while(p[i]->name[j]!='\0')
{
printf("%c",p[i]->name[j]);
j++;
}
printf(": ");
puts(p[i]->number);
i++;
}
printf("\n");
}
void readlist(LinkList *Lp)
{
FILE *fp=fopen("addresslist.txt","r+");
char name[MAXSIZE];
char number[MAX];
while(feof(fp)==0)
{
fscanf(fp,"\n%[^\n]",name);
fscanf(fp,"%s",number);
Insertlist(Lp,name,number);
}
Deletlist(Lp,name);
}
void savelist(LinkList *Lp)
{
FILE *fp=fopen("addresslist.txt","w+");
LinkList p=*Lp;
char tmp='\n';
char ch='\n';
while(p->next!=NULL)
{
int i=0;
while(p->next->name[i]!='\0')
{
fputc(p->next->name[i],fp);
i++;
}
fputc(tmp,fp);
i=0;
while(p->next->number[i]!='\0')
{
fputc(p->next->number[i],fp);
i++;
}
fputc(ch,fp);
p=p->next;
}
fclose(fp);
}
int main()
{
LinkList tel;//Node * tel;
Initlist(&tel);
FILE *fp=fopen("addresslist.txt","a");
fclose(fp);
readlist(&tel);
while(1)
{
char name[MAXSIZE],number[MAX];
int sel;
ElemType e;
printf("\t\t欢迎使用通讯录:\n");
printf("\t\t目录\n");
printf("\t\t1:插入联系人\n");
printf("\t\t2:删除联系人\n");
printf("\t\t3:修改联系人\n");
printf("\t\t4:显示通讯录\n");
printf("\t\t5:按姓名排序\n");
printf("\t\t6:保存并退出\n");
scanf("%d",&sel);
getchar();
switch(sel)
{
case 1:
printf("输入插入姓名:\n");
gets(name);
printf("输入电话号码:\n");
gets(number);
Insertlist(&tel,name,number);
break;
case 2:
printf("输入删除联系人的姓名:\n");
gets(name);
Deletlist(&tel,name);
break;
case 3:
printf("输入修改联系人的姓名:");
gets(name);
Changelist(&tel,name);
break;
case 4:
Printlist(&tel);
break;
case 5:
Sortlist(&tel);
break;
case 6:
savelist(&tel);
printf("欢迎下次使用。");
return;
}
}
return OK;
}