| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2488 人关注过本帖, 1 人收藏
标题:基于链表的通讯录简单程序
只看楼主 加入收藏
linpinjin
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2007-12-30
收藏(1)
 问题点数:0 回复次数:3 
基于链表的通讯录简单程序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct address{                         /*定义结构*/
 char name[30];
 char street[40];
 char city[20];
 char state[3];
 char zip[11];
 struct address *next;                  /*后继指针*/
 struct address *prior;                 /*前导指针*/
 };

 struct address *start;                 /*首结点*/
 struct address *last;                  /*尾结点*/
 struct address *find(char *);          /*声明查找函数*/

 void enter(void),search(void),save(void);                    /*函数声明*/
 void load(void),list(void);
 void mldelete(struct address **,struct address **);
 void dls_store(struct address *i,struct address **start,
                struct address **last);
 void inputs(char *,char *,int),display(struct address *);
 int menu_select(void);



 int main(void)
  {
   start = last = NULL;
   for(;;)
    {switch(menu_select())
     {case 1:enter();
       continue;
      case 2:mldelete(&start,&last);
       continue;
      case 3:list();
       continue;
      case 4:search();
       continue;
      case 5:save();
       continue;
      case 6:load();
       continue;
      case 7:exit(0);
     }
    }
   }

int menu_select(void)                /*主目录*/
{
 char s[80];
 int c;
 printf("1.Enter a name \n");
 printf("2.Delete a name \n");
 printf("3.List the file \n");
 printf("4.Search \n");
 printf("5.Save the file \n");
 printf("6.Load the file \n");
 printf("7.Quit \n");

  do{
   printf("\nEnter your choice:");
   gets(s);
   c = atoi(s);
  }while(c<0||c>7);                 /*超出选项范围时,提示重新输入*/

 return c;                          /*返回输入值*/
}

void enter(void)                           /*输入函数,本函数循环输入资料,当输入姓名为空时退出*/
{struct address *info;                     /*定义当前结点*/

 for(;;){
  info=(struct address *)malloc(sizeof(struct address));   /*为当前结点分配空间*/
  if(!info)
   {printf("\n Out of memory");
    exit(0);                                               /*如果分配空间失败,退出程序*/
   }

  inputs("Enter name:",info->name,30);
  if(!info->name[0])break;                                /*如果输入姓名为空,结束循环*/
  inputs("Enter street:",info->street,40);
  inputs("Enter city:",info->city,20);
  inputs("Enter state:",info->state,3);
  inputs("Enter zip:",info->zip,10);

  dls_store(info,&start,&last);           /*调用结点插入函数*/
 }
}

void inputs(char *prompt,char *s,int count)         /*输入函数,有越界检测功能*/
{
 char p[255];
 do{
  printf(prompt);
  fgets(p,254,stdin);
  if(strlen(p)>count)printf("\nToo Long\n");
 }while(strlen(p)>count);

 p[strlen(p)-1]=0;
 strcpy(s,p);
}

void dls_store(                    /*数据插入函数,也是本例的关键函数*/
           struct address *i,          /*接受传入的当前输入结点地址*/
           struct address **start,     /*接受传入的首结点地址*/
           struct address **last       /*接受传入的尾结点地址*/
          )
 {
  struct address *old,*p;              /*定义临时指针*/

  if(*last==NULL)                      /*如果尾结点为空,意味着当前链表为空*/
   {i->next=NULL;                      /*当前结点的后驱赋空*/
    i->prior=NULL;                     /*当前结点的前驱赋空*/
    *last=i;                           /*尾结点定义为当前结点*/
    *start=i;                          /*首结点定义为当前结点*/
    return;                            /*返回调用函数*/
   }
                                       /*如果链表不为空*/
  p=*start;                            /*p取入口地址(也就是首结点地址)*/

  old=NULL;                            /*old赋空*/
  while(p){                            /*如果p不为空时,执行特循环体,查找比当前结点应该插入的位置*/
   if(strcmp(p->name,i->name)<0)       /*如果当前结点的name域比p(首结点)大时(实现以name域升序排序)*/
    {old=p;                            /*old暂存p地址*/
     p=p->next;                        /*p取下一结点*/
    }
   else                                /*如果当前输入数据中的name域比p小时,把数据插入结点p之前*/
    {if(p->prior)                      /*如果p的前驱不为空时*/
     {p->prior->next=i;                /*令p的前驱的next域指向当前结点*/
      i->next=p;                       /*令当前结点的后继指向p*/
      i->prior=p->prior;               /*令当前结点的前驱指向p的前驱*/
      p->prior=i;                      /*令p的前驱为当前结点*/
      return;                          /*插入完成,返回调用函数*/
     }
     i->next=p;                        /*如果p的前驱为空时,把当前结点作为首结点,并令当前结点的后驱为p*/
     i->prior=NULL;                    /*定义当前结点的前驱为空*/
     p->prior=i;                       /*p的前驱为当前结点*/
     *start=i;                         /*首结点(入口)为当前结点*/
     return;                           /*插入完成,返回调用函数*/
    }
   }                                   /*循环体结束*/
   old->next=i;                        /*如果在整个链表都找不到name域比当前数据的name域大的结点,
                                        *把当前数据放在作为尾结点放在最后*/
   i->next=NULL;                       /*令链表尾结点后驱批向当前结点,当前结点的后驱为空*/
   i->prior=old;                       /*令当前结点的前驱为之前的最后结点*/
   *last=i;                            /*尾结点取i地址*/
}

void mldelete(struct address **start,struct address **last)        /*删除函数*/
{
 struct address *info;
 char s[80];

 inputs("Enter name:",s,30);             /*输入欲删除结点的name域内容*/
 info=find(s);                           /*查找该内容*/
 if(info)                                /*如果找到*/
  {if(*start==info)                      /*如果该结点为首结点,把该结点的下驱作为新的首结点(入口)*/
   {*start=info->next;
    if(*start)(*start)->prior=NULL;      /*如果新入口不为空,把入口的前驱置空*/
    else *last=NULL;                     /*如果新入口为空,把尾结点置空,链表为空*/
   }
   else                                  /*如果欲删除的结点不是首结点*/
    {info->prior->next=info->next;       /*令该结点的前驱的next指针指向该结点的后驱,
                                          *又令该结点的后驱的prior指点指向该结点的前驱*/
     if(info!=*last)                     /*如果该结点是尾结点,则令该结点的前驱为尾结点*/
      info->next->prior=info->prior;
     else
      *last=info->prior;
    }
   free(info);                           /*释放该结点所占用的内存*/
  }
 }

 struct address *find(char *name)         /*查找函数,形参为欲查找结点的name域*/
  {
   struct address *info;
   info=start;
   while(info)
    {
     if(!strcmp(name,info->name))return info;
     info=info->next;
    }
   printf("Name not found.\n");
   return NULL;
  }
                                          /*输出整个链表*/
void list(void)
{
 struct address *info;
 info=start;
 while(info)
  {display(info);
   info=info->next;
  }
 printf("\n\n");
}

void display(struct address *info)         /*输出传入结点函数*/
 {
  printf("%s\n",info->name);
  printf("%s\n",info->street);
  printf("%s\n",info->city);
  printf("%s\n",info->state);
  printf("%s\n",info->zip);
  printf("\n\n");
 }

void search(void)                             /*查找函数*/
 {
  char name[40];
  struct address *info;

  printf("Enter name to find:");             /*输入欲查找的姓名*/
  gets(name);
  info=find(name);
  if(!info)printf("Not found\n");            /*如果没找到,显示Not found*/
  else display(info);                        /*如果找到,显示该结点资料*/
 }

void save(void)                             /*保存函数*/
 {
  struct address *info;
  FILE *fp;
  fp=fopen("mlist","wb");                   /*生成文件*/
   if(!fp)
   {printf("Cannot open file.\n");exit(1);}

  printf("\nSaveing File\n");
  info=start;
  while(info)                                 /*把链表写入文件*/
   {fwrite(info,sizeof(struct address),1,fp);
    info=info->next;
   }
  fclose(fp);                                 /*链表全部写入文件后,关闭文件*/
 }

void load()                               /*调用预存文件函数*/
{struct address *info;
 FILE *fp;                                /*打开文件*/
 fp=fopen("mlist","rb");
 if(!fp){
  printf("Cannot open file.\n");
  exit(1);
 }

 while(start){                           /*释放当前内存链表*/
  info=start->next;
  free(start);
  start=info;
 }
start=last=NULL;                         /*链表为空*/
printf("\nLoading file\n");              /*调用文件*/
while(!feof(fp))                         /*如果文件未到结尾,循环读取文件*/
 {info=(struct address *)malloc(sizeof(struct address));   /*为结点分配内存*/
   if(!info)
   {printf("out of Memory");
   return;
  }
  if(1!=fread(info,sizeof(struct address),1,fp))break;     /*如果读取失败,退出*/
  dls_store(info,&start,&last);                            /*如果读取成败,调用插入函数,把数据插入链表*/
 }                                                         /*文件到结尾,循环结束*/
fclose(fp);                                                /*关闭文件,释放内存*/
}
搜索更多相关主题的帖子: 链表 通讯录 
2008-02-24 12:12
sunkaidong
Rank: 4
来 自:南京师范大学
等 级:贵宾
威 望:12
帖 子:4496
专家分:141
注 册:2006-12-28
收藏
得分:0 
整个结构做得相当好.帮你顶一下...
2008-02-24 13:27
为梦想学习
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2008-2-24
收藏
得分:0 
一个完全不懂的新手 你说学的会么

越堕落〇.Muma,越快
                           frоm:從此.封筆
2008-02-24 14:13
linpinjin
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2007-12-30
收藏
得分:0 
谁都是从完全不懂的新手开始学的。我相信我能学会。
2008-02-24 18:52
快速回复:基于链表的通讯录简单程序
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.014200 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved