• 链表-C语言实现


    链式存储线性表的结构体:

    typedef int ElemType;        //元素类型
    
    typedef struct Node            //链表结构体
    {
        ElemType date;            //链表结点数据域
        struct Node *next;        //链表结点指针域
    }Node,*LinkList;

    创建链表:

    /*
    链表的创建操作
    使用srand()时,需要引入头文件stdlib.h,即在头文件处添加 #include<stdlib.h>
    使用time()时,需要引入头文件time.h,即在头文件处添加 #include<time.h>
    使用malloc()时,需要引入头文件malloc.h,即在头文件处添加 #include<malloc.h>
    */ void CreatList(LinkList *L, int n) { LinkList p,r; int i; srand(time(0)); //初始化随机数种子 *L = (LinkList)malloc(sizeof(Node)); //创建链表空间 //不是表空间,是头结点 2018.8.13/于瑞 r = *L; //r为指向L尾部的指针 for(i = 0; i < n; i++) { p = (Node *)malloc(sizeof(Node)); //创建新结点p //Node *与LinkList等价 2018.8.13/于瑞 p->date = rand() % 100 +1; //为新结点的数据域赋值 r->next = p; //使r指针指向p r = p; //将p结点赋值给r,使r继续为表尾结点 } r->next = NULL; //表尾结点指针域为空 }

    链式存储的插入函数:

    /*
    链表的插入操作
    */
    Status InsertList(LinkList *L, int i, ElemType e)
    {
        int j = 1;        //记录当前位置
        LinkList p,s;
        p = *L;            //将p指向L的头结点
        while(p && j < i)        //判断p是否不为空  且  计数器j是否小于插入的位置i
        {
            p = p->next;        //若是,将指针后移
            j++;                //计数器加1
        }
        if(!p || j > i)            //判断p是否为空  或  计数器j是否大于插入位置i
            return ERROR;        //若是,说明链表为空   或   索引位置有误、
    
                                                //运行到这,说明已找到需要插入的位置
        s = (LinkList)malloc(sizeof(Node));        //创建新结点s
        s->date = e;                            //将e值赋值给新结点s的数据域
        s->next = p->next;                        //将p结点的指针域赋值给新结点s的指针域
        p->next = s;                            //将新结点s赋值给p结点的指针域
        return OK;                                //操作成功
    }

    链式存储的删除函数:

    /*
    链表的删除操作
    */
    Status ListDel(LinkList *L, int i, ElemType *e)
    {
        int j = 1;            //计数器j
        LinkList p = *L;    //创建指针p指向L
        LinkList q;            //用于记录找到的结点信息,,必须有q,否则无法释放
        while(p->next && j < i)    //判断p是否不为空  且  计数器j是否小于插入的位置i
        {
            p = p->next;    //若是,将指针后移
            j++;            //计数器加1
        }
        if(!(p->next) || j > i)        //判断p是否为空  或  计数器j是否大于插入位置i
            return ERROR;    //若是,说明链表为空   或   索引位置有误
    
                                    //运行到这,说明已找到需要插入的位置
        q = p->next;                //将要删除的结点p->next赋值给q
        *e = q->date;                //将p结点的数据域内容赋值给e
        p->next = q->next;            //将p->next的指针域赋值给p的指针域
        free(q);                    //释放结点q
        return OK;                    //操作成功
    }

    链式存储的索引查找函数:

    /*
    线性链表的查询操作
    */
    Status GetElem(LinkList L, int i, ElemType *e)
    {
        int j = 1;                    //
        LinkList p = L->next;        //声明指针p指向L的计数器第一个节点
        while(p && j < i)                //判断链表是否不为空  并且  计数器j是不是小于所需位置i的大小
        {
            p = p->next;            //若是,是p指向下一节点
            j++;                    //是计数器加1
        }
        if (!p || j>i)                //判断p是否为空  或   计数器j是不是大于所需位置i的大小
            return ERROR;            //若是,说明链表为空或位置索引有误
        *e = p->date;                //若运行此句,说明已找到i位置的元素,将此结点的数据域内容赋值给e
        return OK;                    //返回操作成功
    }

    链式存储的修改函数:

    /*
    链表的修改操作
    */
    Status UpdateList(LinkList *L, int i, ElemType e)
    {
        LinkList p = (*L) ->next;        //使p指向L的第一个结点
        int j = 1;                        //计数器j
        while(p && j < i)                //判断p非空   计数器小于所需位置
        {
            p = p->next;                //指针后移
            j++;                        //计数器加1
        }
        if(!p || j > i)                    //判断p为空    计数器大于所需位置
            return ERROR;                //返回失败
        p->date = e;                    //使p的数据域为e
        return OK;                        //操作成功
    }

    链式存储的遍历打印函数:

    /*
    链表的遍历操作
    */
    void PrintList(LinkList L)
    {
        int j = 1;            //计数器
        LinkList p = L->next;        //使p指向L
        if(!p)
            printf("表空
    ");
        while(p)
        {
            printf("第%d个元素为%d
    ",j,p->date);
            p = p->next;
            j++;
        }
        printf("
    ");
    }

    整表删除函数:

    /*
    链表的整表删除操作
    */
    Status ClearList(LinkList *L)
    {
        int j = 1;            //计数器1
        LinkList p,q;
        p = (*L)->next;                //让p指向L
        while(p)
        {
            q = p->next;            //使q指向p
            free(p);                //释放p
            p = q;                    //使p指向q
        }
        (*L)->next = NULL;            //使头指针为空
        return OK;                    //操作成功
    }

    主函数:

    void main()
    {
        LinkList L;            //创建链表L
        int i, e;            //i为元素位置,e为元素内容
    
        while(true)
        {
            printf("请选择对线性链表的操作:
    ");
            printf("1.创建
    ");
            printf("2.插入
    ");
            printf("3.删除
    ");
            printf("4.查找
    ");
            printf("5.修改
    ");
            printf("6.输出
    ");
            printf("7.整表删除
    ");
            printf("8.退出
    ");
            int a;
            scanf("%d", &a);
            switch(a)
            {
                case 1:
                    printf("请输入需要创建元素的个数:");
                    scanf("%d", &i);
                    if(CreatList(&L, i))
                        printf("创建成功
    ");
                    else
                        printf("创建失败
    ");
                    break;
                case 2:
                    printf("请输入需要插入的位置:");
                    scanf("%d", &i);
                    printf("请输入需要插入的元素:");
                    scanf("%d", &e);
                    if(InsertList(&L, i, e))
                        printf("插入成功
    ");
                    else
                        printf("插入失败
    ");
                    break;
                case 3:
                    printf("请输入需要删除的位置:");
                    scanf("%d", &i);
                    if(ListDel(&L, i, &e))
                        printf("删除成功
    ");
                    else
                        printf("删除失败
    ");
                    break;
                case 4:
                    printf("请输入需要查找的位置:");
                    scanf("%d", &i);
                    GetElem(L, i, &e);
                    printf("第%d个元素为%d
    ",i,e);
                    break;
                case 5:
                    printf("请输入需要修改的位置:");
                    scanf("%d", &i);
                    printf("请输入新的的元素:");
                    scanf("%d", &e);
                    if(UpdateList(&L, i, e))
                        printf("修改成功
    ");
                    else
                        printf("修改失败
    ");
                    break;
                case 6:
                    PrintList(L);
                    break;
                case 7:
                    if(ClearList(&L))
                        printf("清空成功
    ");
                    else
                        printf("清空失败
    ");
                    break;
                case 8:
                    return;
                default:
                    printf("选择错误
    ");
                    break;
            }
        }
    }

    经检测,所有代码均可执行!

  • 相关阅读:
    BUUCTF-[GYCTF2020]Blacklist 1 思路
    [强网杯 2019]随便注 WriteUp(three way)思路
    [GXYCTF2019]Ping Ping Ping 1思路
    [ACTF2020 新生赛]Include 思路
    [极客大挑战 2019]Secret File 思路
    [SUCTF 2019]EasySQL 思路
    java环境变量配置 详细
    [极客大挑战 2019]Upload 思路
    [极客大挑战 2019]Http 思路
    [ACTF2020 新生赛]Exec 思路
  • 原文地址:https://www.cnblogs.com/yurui/p/9498868.html
Copyright © 2020-2023  润新知