通讯录管理
题目要求:
通讯录管理系统一般包括通讯录结点信息的插入、查询、删除、更新以及通信录信息的输出等功能。而通讯录的信息一般包括编号、姓名、性别、电话以及地址等项。本题主要考查用链式结构来实现通讯录管理系统(链表的操作)。
需求分析:
将通讯录设置为6个模块:1建立.2插入.3查询.4删除.5输出.6退出系统。在开始菜单对应的选择功能键为1-5;对于插入是通过序号来升序插入的;查找则是提供了俩种方式1序号.2姓名;删除是在查找的基础上来对节点的释放;输出就是通过指针p来指向head节点再next一一输出。
流程图:
设计:
1.尾插法建立列表;使用链表头尾指针head和real指向新生成的节点;
再用一个flag来创建一个结束标志。
2.插入通讯信息
链表节点的插入为方便查询和输出,就要将一个通讯者的数据按编号来有序的插入,在这里使用两个指针变量p1和p2,p1指向原链表的头节点,p2指向链表的第一个节点。并通过while(p2!=NULL&&p2->data.numdata.num)来判断插的位置。
3.通讯者的查找
首先输入要查找的通讯者的编号或者是姓名,从表头顺序访问表中的节点,成功则返回一指向查找到通讯者信息的节点,失败则返回NULL,输出查找失败。使用strcmp函数来实现俩个学号或者姓名的比较。
4通讯信息的删除
调用之前的查找函数,来找到要删除的节点,找到了以后释放空间就完成了。
5.通讯录的输出
将一个头指针赋给一个变量p;依次输出,直至表尾p为空为止。
源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | #include<stdio.h> #include<string.h> #include<stdlib.h> typedef struct{ //通讯录结点类型 char num[5]; //编号 char name[9]; //姓名 char sex[3]; //性别 char phone[13]; //电话 char addr[31]; //地址 }datatype; typedef struct node{ //结点类型定义 datatype data; //结点数据域 struct node*next; //结点指针域 }listnode; typedef listnode*linklist; linklist head; listnode *p; //函数说明 int menu_select(); linklist createlist(void); void insertnode(linklist head,listnode *p); listnode *listfind(linklist head); void delnode(linklist head); void printlist(linklist head); //主函数 void main() { for( ; ; ){ switch(menu_select()) { case 1: printf("++++++++++++++++++++++++++++\n"); printf("* 通讯录链表的建立 *\n"); printf("+++++++++++++++++++++++++++++\n"); head=createlist(); break; case 2: printf("+++++++++++++++++++++++++++++\n"); printf("* 通讯者信息的添加 *\n"); printf("+++++++++++++++++++++++++++++++\n"); printf("编号(4) 姓名(8) 性别 电话(11) 地址(31)\n"); printf("+++++++++++++++++++++++++++++++++++++++++++\n"); p=(listnode *)malloc(sizeof(listnode)); scanf("%s%s%s%s%s",p->data.num,p->data.name,p->data.sex,p->data.phone,p->data.addr); insertnode(head,p); break; case 3: printf("+++++++++++++++++++++++++++++++++++++\n"); printf("* 通讯录信息的查询 *\n"); printf("++++++++++++++++++++++++++++++++++++++\n"); p=listfind(head); if(p!=NULL){ printf("编号 姓 名 性别 联系电话 地 址\n"); printf("----------------------------------------------------------------------------------\n"); printf("%s,%s,%s,%s,%s\n",p->data.num,p->data.name,p->data.sex,p->data.phone,p->data.addr); printf("----------------------------------------------------------------------------------\n"); } else printf("没查到要查询的通讯者!\n"); break; case 4: printf("+++++++++++++++++++++++++++++++++++++\n"); printf("* 通讯录信息的删除 *\n"); printf("*************************************\n"); delnode(head); break; case 5: printf("+++++++++++++++++++++++++++++++++++++\n"); printf("* 通讯录链表的输出 *\n"); printf("+++++++++++++++++++++++++++++++++++++\n"); printlist(head); break; case 0: printf("\t 退出系统!\n"); return; } } } int menu_select() { int A; printf(" 通讯录管理系统\n"); printf("============================\n"); printf(" 1.通讯录链表的建立\n"); printf(" 2.通讯录结点的插入\n"); printf(" 3.通讯录结点的查询\n"); printf(" 4.通讯录结点的删除\n"); printf(" 5.通讯录链表的输出\n"); printf(" 0.退出管理系统\n"); printf("============================\n"); printf(" 请选择0-5: "); for( ; ; ) { scanf("%d",&A); if(A<0 || A>5) printf("\n\t输入错误,重选0-5: "); else break; } return A; } /******************************/ /*用尾插法建立通讯录链表函数*/ /*****************************/ linklist createlist(void) { //尾插法建立带头结点通讯录链表算法 linklist head=(listnode *)malloc(sizeof(listnode)); listnode *p,*rear; int flag=0; //结束标志置0 rear=head; //尾指针初始指向头结点 while(flag==0) { p=(listnode *)malloc(sizeof(listnode)); //申请新结点 printf("编号(4) 姓名(8) 性别 电话(11) 地址(31)\n"); printf("----------------------------------------------------------------\n"); scanf("%s%s%s%s%s",p->data.num,p->data.name,p->data.sex,p->data.phone,p->data.addr); rear->next=p; //新结点连接到尾结点之后 rear=p; //尾指针指向新结点 printf("结束建表吗? (1/0):"); scanf("%d",&flag); //读入一个标志数据 } rear->next=NULL; //终端结点指针域置空 return head; //返回链表头指针 } void insertnode(linklist head,listnode *p) { listnode *p1,*p2; p1=head; p2=p1->next; while(p2!=NULL && strcmp(p2->data.num,p->data.num)<0) { p1=p2; //p1指向刚访问过的结点 p2=p2->next; //p2指向表的下一个结点 } p1->next=p; //插入p所指向的结点 p->next=p2; //连接表中剩余部分 } listnode *listfind(linklist head) { listnode *p; char num[5]; char name[9]; int xz; printf("=====================\n"); printf("1.按编号查询 \n"); printf("2.按姓名查询 \n"); printf("=====================\n"); printf(" 请选择: "); p=head->next; //假定通讯录表带头结点 scanf("%d",&xz); if(xz==1){ printf("请输入要查找者的编号: "); scanf("%s",num); while(p && strcmp(p->data.num,num)<0) p=p->next; if(p==NULL || strcmp(p->data.num,num)>0) p=NULL; //没有查到要查找的通讯者 } else if(xz==2){ printf("请输入要查找者的姓名:"); scanf("%s",name); while(p && strcmp(p->data.name,name)!=0) p=p->next; } return p; } void delnode(linklist head) { char jx; listnode *p,*q; p=listfind(head); //调用查找函数 if(p==NULL){ printf("没有查到要删除的通讯者!\n"); return; } printf("要删除该结点吗?(y/n)"); getchar(); scanf("%c",&jx); if(jx=='y'||jx=='Y'){ q=head; while(q!=NULL && q->next!=p) q=q->next; q->next=p->next; //删除结点 free(p); //释放被删除的结点空间 printf("通讯者已被删除!\n"); } } void printlist(linklist head) { listnode *p; p=head->next; //因为链表带头接点,使P指向链表开始结点 printf("编号 姓 名 姓别 联系电话 地 址\n"); printf("-----------------------------------------------------------------------\n"); while(p!=NULL) { printf("%s,%s,%s,%s,%s\n",p->data.num,p->data.name,p->data.sex,p->data.phone,p->data.addr); printf("-------------------------------------------------------\n"); p=p->next; } } |