第一章 链表的应用
线性表是数据结构中最简单、最常用的一种线性结构,也是学习数据结构全部内容的基础,其掌握的好坏直接影响着后继课程的学习。线性表的顺序存储结构,即顺序表的概念相对比较简单,因此,本章的主要任务是使用有关单链表的操作来实现通讯录信息系统的管理。
1.1设计要求
本章的设计实验要求使用有关链表的操作来实现通讯录信息系统的管理。为了验证算法,通讯录管理包括单通讯录链表的建立、通讯者的插入、通讯者的删除、通讯者的查询及通讯录表的输出等。主控菜单的设计要求使用数字0—5来选择菜单项,其他输入则不起作用。
程序运行后,给出6个菜单项的内容和输入提示:
    1.通讯录链表的建立
    2. 通讯者结点的插入
    3. 通讯者结点的查询
    4. 通讯者结点的删除
    5. 通讯录链表的输出
    0. 退出管理系统
请选择0—5:
1.2设计分析
1.2.1主控菜单函数设计分析
1.实现循环和功能选择
    首先编写一个主控菜单驱动程序,输入0—5以进入相应选择项。假设输入选择用变量sn存储,它作为menu_select函数的返回值给switch语句。使用for循环实现重复选择,并在主函数main()中实现。
    实际使用时,只有选择大于5或小于0的值,程序才能结束运行,这就要使用循环控制。这
里使用for循环语句实现菜单的循环选择,为了结束程序的运行,使用了“return”语句,也可以使用“exit(0);”语句。
2.得到sn的合理值
    如前所述,应该设计一个函数用来输出提示信息和处理输入,这个函数应该返回一个数值sn,以便供给switch语句使用。假设函数名为menu_select,对于sn的输入值,在switch中case语句对应数字1—5,对于不符合要求的输入,提示输入错误并要求重新输入。将该函数与主函数合在一起,编译运行程序,即可检查并验证菜单选择是否正确。
1.2.2功能函数设计分析
1.建立通讯录链表的设计
    这里实际上是要求建立一个带头结点的单链表。建立单链表有两种方法,一种称之为头插法,另一种称为尾插法。头插法是每次将新插入的结点插入在链表的表头,而尾插法是将新插入的结点插入在链表的表尾。本次实验用尾插法建立链表的算法设计思想及具体算法实现。
    要建立链表,首先要生成结点,因此,尾插法建立链表的算法描述如下:
    (1)使链表的头尾指针head、rear指向新生成的头结点(也是尾结点);
    (2)置结束标志为0(假);
    (3)While(结束标志不为真)
{
    P指向新生成的结点;
        读入一个通讯者数据至新结点的数据域;
        将新结点链到尾结点之后;
        使尾指针指向新结点;
        提示:是否结束建表,读入一个结束标志;
}
    (4)尾结点指针域置空值NULL。
2.通讯者信息的插入
    链表结点的插入,是要求将一个通讯者数据结点按其编号的次序插入有序通讯录表的相应位置,以保持通讯录表的有序性。插入结点的基本思想是:使用两个指针变量p1和p2分别指向当前刚访问过的结点和下一个待访问的结点,循环顺序查链表,寻插入结点的位置,其中p1指向待插入位置的前一个结点。
(1)用p1指向元链表的头结点,p2指向链表的第一个结点;
(2)while(p2 != NULL && p2->data.num < p->data.num)
{
            P1=p2;//p1指向刚访问过的结点;
            P2=p2->next;//p2指向表的下一个结点;
}
(3)插入新结点。
3.在有序表中查指定结点
在有序链表中查指定结点的算法基本思想是:首先输入要查的通讯者的编号或姓名,从表头顺序访问表中结点。如查成功,则返回一个指向查到的通讯者信息的结点;若查失败,则返回一个空的指针值NULL。
当按编号查时,如果需要查的通讯者编号不在表中,则不一定需要循环比较到表尾,因为表是按编号递增有序的;而当按姓名查时,则要循环比较到表尾,才能确定查不到的情况。
4.通讯者记录的删除
printf函数有返回值吗    链表上结点的删除是比较简单的,先调用查询函数,查询到要删除的结点,若没有查到则提示“没有查到要删除的通讯者”,若查到根据选择删除结点即可。
5.通讯录链表的输出
    通讯录链表的输出只要将表头指针赋给一个指针变量p,然后用p向后扫描,直至表尾,p为空为止。
1.3算法实现
1.菜单选择函数具体算法实现如下:
int menu_select()
{
    int sn;
    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",&sn);
        if (sn<0 || sn>5)
        printf("\n\t输入错误,重选0--5: ");
        else
            break;
    }
    return sn;
}
2.建立通讯录链表具体算法实现如下:
LinkList CreateList(void)
{
    LinkList head=(ListNode *)malloc(sizeof(ListNode));
    ListNode *p,*rear;
    int flag=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);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。