zoukankan      html  css  js  c++  java
  • 静态链表-C语言实现

    1.静态链表是在没有指针的编程语言里对链表的一种实现
    2.主要是用数组模拟指针
    3.在这里,使用结构体使数组的每一个空间可以存储一个数据元素(date)和一个游标(cur),游标的作用相当于链表的指针域,用于记录下一元素的下标是多少
    4.在没有结构体(typedef)的语言中,也可以使用两个并行数组实现此功能

    此种结构在编程中不一定能用得到,但是这种思想非常巧妙,非常值得我们学习,不多说,直接上代码,亲测可行,有详细注释

    #include<stdio.h>
    
    #define MAXSIZE 1000                //静态链表最大空间容量
    typedef int ElemType;                //数据类型
    typedef int Status;                    //返回值类型
    #define OK 1                        //操作成功返回值
    #define ERROR 0                        //操作失败返回值
    
    typedef struct                        //静态链表的结构体
    {
        ElemType date;                    //结点数据
        int cur;                        //结点游标(相当于链表中的地址)
    }StaticLinkList[MAXSIZE];            //表名
    
    /*
    静态链表的初始化
    第一个位置space[0]的cur指向第一个没有数据的位置空间
    最后一个位置space[MAXSIZE-1]的cur指向第一个有数据的位置空间,即头结点
    */
    Status InitList(StaticLinkList space)
    {
        for(int i = 0; i < MAXSIZE-1; i++)            //为数组中的每个位置的游标赋值
            space[i].cur = i + 1;
        space[MAXSIZE-1].cur = 0;                    //使最后一个位置的游标为0
        return OK;                                    
    }
    
    /*
    模拟链表中的malloc函数,在数组中寻找空闲位置空间作为新结点
    */
    int malloc_SLL(StaticLinkList space)
    {
        int i = space[0].cur;                        //将备用链表的第一个结点位置赋值给i
        if(space[0].cur)                            //如果space[0].cur不是0,即备用链表非空
            space[0].cur = space[i].cur;                //将备用链表的下一个空闲位置赋值给space[0]
        return i;
    }
    
    /*获得链表的长度*/
    int ListLength(StaticLinkList L)
    {
        int i, l;
        l = 0;                    //记录链表长度
        i = MAXSIZE - 1;        //获得头结点下标
        i = L[i].cur;            //获得头结点位置
        while(i)                //如果此下标 != 0
        {
            l++;                //长度加1
            i = L[i].cur;        //下标后移
        }
        return l;                //返回长度l
    }
    
    /*
    静态链表的插入操作
    */
    Status InsertLinkList(StaticLinkList L, int i, ElemType e)
    {
        int j ,k, l;
        k = MAXSIZE-1;                            //获取头结点的下标
        if(i < 1 || i > ListLength(L)+1)        //判断要插入的位置是否合理
            return ERROR;
        j = malloc_SLL(L);                        //获得备用链表中的第一个位置下标
        if(j)                                    //如果此下标不是0,说明还有空间可用
        {
            L[j].date = e;                        //将此下标对应位置的数据域赋值为e
            for(l = 1; l < i; l++)                //遍历链表,寻找i位置之前的结点
                k = L[k].cur;                    //获得此结点的游标
            L[j].cur = L[k].cur;                //新结点的游标等于i-1位置的游标
            L[k].cur = j;                        //i-1位置的游标等于新结点的游标
            return OK;                            //操作成功
        }
        return ERROR;                            //操作失败
    }
    
    /*模拟free()函数,将删除的结点空间加入备用空间*/
    void free_SSL(StaticLinkList space, int i)
    {
        space[i].cur = space[0].cur;                    //删除位置的游标等于0位置的游标
        space[0].cur = i;                                //0位置的游标等于当前结点
    }
    
    /*静态链表的删除操作*/
    Status DelLinkList(StaticLinkList L, int i)
    {
        int j, k;
        if(i < 1 || i > ListLength(L)+1)                //判断删除的位置是否合理
            return ERROR;
        k = MAXSIZE - 1;                                //获得头结点的游标
        for(j = 1; j < i; j++)                            //寻找i位置
            k = L[k].cur;                                //游标后移
        j = L[k].cur;                                    //将要删除的位置下标赋值给j
        L[k].cur = L[j].cur;                            //使删除结点的前一结点的游标指向删除结点的游标
        free_SSL(L, j);                                    //释放删除的结点
        return OK;
    }
    
    /*静态链表的遍历操作*/
    void PrintLinkList(StaticLinkList L)
    {
        int i;
        int j = MAXSIZE - 1;                        //获得数组最后一个位置的下标
        j = L[j].cur;                                //获得此下标的游标值,即头结点的下标
    //    printf("长度为%d
    ",ListLength(L));
        for(i = 1; i <= ListLength(L); i++)            //遍历此表
        {
            printf("第%d个结点的数据是:%d
    ", i, L[j].date);                //输出每个结点的数据
            j = L[j].cur;                            //获得下一结点的游标
        }
    }
    
    
    void main()
    {
        StaticLinkList L;            //创建链表L
        int i, e;            //i为元素位置,e为元素内容
    
        while(true)
        {
            printf("请选择对静态链表的操作:
    ");
            printf("1.初始化
    ");
            printf("2.插入
    ");
            printf("3.删除
    ");
            printf("4.输出
    ");
            printf("5.退出
    ");
            int a;
            scanf("%d", &a);
            switch(a)
            {
                case 1:
                    if(InitList(L))
                        printf("初始化成功
    ");
                    else
                        printf("初始化失败
    ");
                    break;
                case 2:
                    printf("请输入需要插入的位置:");
                    scanf("%d", &i);
                    printf("请输入需要插入的元素:");
                    scanf("%d", &e);
                    if(InsertLinkList(L, i, e))
                        printf("插入成功
    ");
                    else
                        printf("插入失败
    ");
                    break;
                case 3:
                    printf("请输入需要删除的位置:");
                    scanf("%d", &i);
                    if(DelLinkList(L, i))
                        printf("删除成功
    ");
                    else
                        printf("删除失败
    ");
                    break;
                case 4:
                    PrintLinkList(L);
                    break;
                case 5:
                    return;
                default:
                    printf("选择错误
    ");
                    break;
            }
        }
    }
  • 相关阅读:
    赫尔维茨公式
    从解析几何的角度分析二次型
    Struts 1 Struts 2
    记一次服务器被入侵的调查取证
    契约式设计 契约式编程 Design by contract
    lsblk df
    Linux Find Out Last System Reboot Time and Date Command 登录安全 开关机 记录 帐号审计 历史记录命令条数
    Infrastructure for container projects.
    更新文档 版本控制 多版本并发控制
    Building Microservices: Using an API Gateway
  • 原文地址:https://www.cnblogs.com/yurui/p/9508367.html
Copyright © 2011-2022 走看看