单链表重复元素的删除

1.1 问题描述

为了增强对单链表的熟悉,能够更加熟练地运用单链表,编写了一个单链表重复元素的删除程序。通过对该程序的实现,使我更加熟悉单链表的实现原理。

1.2 问题分析

用子函数实现单链表的初始化、尾插法建立单链表、重复元素的删除、输出单链表、置空单链表的功能,主函数其调用功能,功能菜单进行选择。

1.3 设计分析

本次实验设计主要是增强对单链表的熟悉,能够更加熟练地运用单链表。

1.4 设计部分

写出本次实验的详细设计方案。

将学生信息的单链表的初始化、尾插法建立单链表、重复元素的删除、输出单链表、置空单链表分别写五个子函数,每执行完一个功能后,程序将会重新显示菜单。

代码如下:

#include
#include
typedef int elemtype;            //节点的数据类型,设为整型
typedef struct node                //定义单链表节点类型
{
    elemtype data;                //节点的数据域
    struct node *next;            //节点的指针域
}LinkList;                        //单链表的类型名为 LinkList
LinkList *head;                    //head 是指向单链表类型LinkList的指针变量

//初始化单链表
LinkList *Init_LinkList()
{
    LinkList *head;    
    head = (LinkList*)malloc(sizeof(LinkList)); //生成头结点指针
    if (head == NULL)                            //如果申请空间失败,返回空指针
    {
        printf("初始化失败!\n");
        return 0;
    }
    else
    {
        printf("初始化成功!\n");
        return head;
    }
}
//尾插法创建带头结点单链表的函数
LinkList *Create_LinkListR(LinkList*head)                    //尾插法创建带头结点单链表的函数
{
    elemtype ix;
    LinkList *p, *tail;                    //*head,tail分别为头指针和尾指针
    head->next = NULL;                            //置头结点指针域为空
    tail = head;                                //尾指针域指向头结点
    printf("请输入数据直到输入0结束:");        //
    scanf("%d", &ix);                            //输入第一个数据
    while (ix != 0)                                //输入数据,0为结束标志
    {
        p = (LinkList*)malloc(sizeof(LinkList));//生成新结点
        if (p == NULL)                            //如果申请空间失败,返回主调函数
        {
            printf("新结点申请空间失败,无法继续建立单链表!\n");
            return head;
        }
        p->data = ix;                            //为新结点数据域赋值
        tail->next = p;                            //修改尾结点指针域
        tail = p;                                //修改尾指针
        tail->next = NULL;                        //将尾结点的指针域置为空
        scanf("%d", &ix);                        //读入下一个数据
    }
    printf("单链表建立成功!\n");
    return head;                                //返回头结点指针

}
//单链表的删除 删除后继结点
int DeleteAfter_LinkList(LinkList *p)    //单链表的删除 删除后继结点 删除p的后继结点,成功返回1,否则返回0
{
    LinkList *r;
    if (!p)
    {
        return 0;
    }
    r = p->next;
    if (!r)
    {
        return 0;
    }
    p->next = r->next;                    //将结点r从链表上摘除
    free(r);                            //释放结点占用的内存空间
    return 1;
}
//单链表的遍历
int Print_LinkList(LinkList*head)                //单链表的遍历
{
    LinkList *p = head->next;
    if (p == NULL)                                //链表为空,返回值为0
    {
        printf("单链表为空!\n");
        return 0;
    }
    while (p != NULL)                            //当前结点不为空
    {
        printf("%d\n", p->data);                //输出当前结点的数据
        p = p->next;                            //移动指针指向下一个结点
    }
    return 1;
}
//重复元素的删除
void Del_LinkList(LinkList *head)
{
    LinkList *p, *r, *t, *n;
    p = head;
    while (p->next != NULL)
    {
        t = p;
        n = p;
        r = p->next;
        p = p->next;
        while (r != NULL)
        {
            if (t->data == r->data)
            {
                n->next = r->next;
                r = r->next;
            }
            else
            {
                n = r;
                r = r->next;
            }
        }
    }
    printf("重复元素删除成功!\n");
}
//置空表
LinkList *SetNull_LinkList(LinkList *head)        //置空表
{
    while (head->next)
    {
        DeleteAfter_LinkList(head);                //依次删除每个结点
    }
    printf("单链表置空成功!\n");
    return head;
}
//菜单界面
void menu()
{
    system("cls");
    printf("\n");
    printf("\t\t---------------欢迎使用单链表的基本操作------------------\n");
    printf("\t\t|\t\t a 初始化单链表               \t\t|\n");
    printf("\t\t|\t\t b 采用尾插法建立单链表       \t\t|\n");
    printf("\t\t|\t\t c 重复元素的删除             \t\t|\n");;
    printf("\t\t|\t\t d 输出单链表                 \t\t|\n");
    printf("\t\t|\t\t e 置空单链表                 \t\t|\n");
    printf("\t\t|\t\t f 退出系统                   \t\t|\n");
    printf("\t\t---------------------------------------------------------\n");
    printf("\t\t请选择(a-f):");
}
int main()
{
    LinkList *head;
    int quit = 0;
    char select;
    while (1)
    {
        menu();            //调用子函数
        scanf("%c", &select);
        switch (select)
        {
        case 'a': head = Init_LinkList(); break;//初始化单链表
        case 'b': Create_LinkListR(head); break; //采用尾插法建立单链表
        case 'c': Del_LinkList(head); break;//重复元素的删除
        case 'd': Print_LinkList(head); break;//输出单链表
        case 'e': SetNull_LinkList(head); break;//置空单链表
        case 'f': quit = 1; break;
        default:printf("请输入a~f之间的数字\n"); break;
        }
        if (quit == 1)
        {
            break;
        }
        printf("按任意键返回主菜单!\n");
        getchar();                //提取到缓冲区中的回车键
        getchar();                //起到暂停的作用
        printf("程序结束!\n");
    }
    return 0;
}

你可能感兴趣的:(c语言,单链表,数据结构)