zoukankan      html  css  js  c++  java
  • 数据结构线性表的动态分配顺序存储结构算法c语言具体实现和算法时间复杂度分析

    #include<stdio.h>
    #include<stdlib.h>
    //线性表的动态分配顺序存储结构
    #define LIST_INIT_SIZE 100//线性表存储空间的初始分配量
    #define LISTINCREMENT 10//线性表存储空间的分配增量
    //函数结果状态代码
    #define TRUE 1
    #define FALSE 0
    #define OK 1
    #define ERROR 0
    #define INFEASIBLE -1
    #define OVERFLOW -2
    typedef int Status;//Status是函数的类型,其值是函数结果状态代码
    typedef int ElemType;
    //线性表的动态分配顺序存储结构
    typedef struct{
        ElemType *elem;//存储空间基址
        int length;//当前长度
        int listsize;//当前分配的存储容量的(以sizeof(ElemType)为单位)
    }SqlList;

    //构造一个空的线性表L
    //O(1)
    Status InitList_Sq(SqlList &L)
    {
        //构造一个空的线性表
        L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
        if(!L.elem)
            {
                printf("线性表L构造失败! ");
                exit(OVERFLOW);//存储分配失败
            }
        L.length=0;//空表的长度为0
        L.listsize=LIST_INIT_SIZE;//初始的存储容量
        printf("线性表L构造成功! ");
        return OK;
    }//InitList_Sq
    //销毁线性表L
    //O(1)
    Status DestroyList_Sq(SqlList &L)
    {
        if(L.elem!=NULL)
        {
            free(L.elem);
            L.elem=NULL;
            L.length=0;
            L.listsize=0;
            printf("销毁线性表L成功 ");
            return OK;
        }else
        {
            printf("线性表L不存在 ");    
        }
        return ERROR;
    }//DestroyList_Sq
    //将L重置为空表
    //O(1)
    Status ClearList_Sq(SqlList &L)
    {
        if(L.elem!=NULL)
        {
            L.length=0;
            printf("已将线性表重置为空表! ");
            return OK;
        }else
        printf("线性表重置为空表失败! ");
        return ERROR;
    }//ClearList_Sq
    //若L为空表,则返回TRUE,否则返回FALSE
    //O(1)
    Status ListEmpty_Sq(SqlList L)
    {
        if(L.elem!=NULL&&L.length==0)
        {
            printf("线性表L为空表 ");
            return TRUE;
        }else if(L.elem!=NULL)
        {
            printf("线性表L不为空表 ");
            return FALSE;
        }else{
            printf("线性表L不存在 ");
            return FALSE;
        }
    }//ListEmpty_Sq
    //返回L中数据元素的个数
    //o(1)
    Status ListLength_Sq(SqlList L)
    {
        if(L.elem!=NULL)
        {
            printf("线性表L的长度为%d ",L.length);
            return L.length;
        }else
        printf("线性表L不存在");
        return -1;
    }//ListLength_Sq
    //用e返回L中第i个元素的值
    //O(1)
    void GetElem_Sq(SqlList L,int i,ElemType &e)
    {
        if(L.elem!=NULL)
        {
            if(i<1||i>L.length)
                printf("访问位置非法");
            else
            {
                e=L.elem[i-1];
            }
        }else
        printf("线性表L不存在");    
    }//GetElem_Sq
    //返回L中第一个与e满足关系compare()的元素的位序。若这样的数据元素不存在,则返回值为0
    //O(n)
    Status LocateElem_Sq(SqlList L,ElemType e,Status (*compare)(ElemType,ElemType))
    {
        int i=1;
        ElemType *p=L.elem;
        if(L.elem!=NULL)
        {
            while(i<=L.length&&!(*compare)(*p++,e))
            {
                ++i;
            }
            if(i<=L.length)
            {
                printf("找到元素e在线性表L的位置为第%d个",i);
                return i;
            }else
            {
                printf("线性表L中不存在元素e");
                return 0;
            }
        }else
        printf("线性表L不存在");
        return 0;
    }//LocateElem_Sq
    //若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则失败,pre_e无定义
    //O(n)
    Status PriorElem_Sq(SqlList L,ElemType cur_e,ElemType *pre_e)
    {
        int i=2;
        if(L.elem!=NULL)
        {
            while(i<=L.length)
            {
                if(cur_e==L.elem[i-1])
                    *pre_e=L.elem[i-2];
                    ++i;
                    return OK;

            }
            return ERROR;
        }else
        printf("线性表L不存在");
        return ERROR;
    }//PriorElem_Sq
    //若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义
    //O(n)
    Status NextElem_Sq(SqlList L,ElemType cur_e,ElemType *next_e)
    {
        int i=1;
        if(L.elem!=NULL)
        {
            while(i<=L.length-1)
            {
                if(cur_e==L.elem[i-1])
                    *next_e=L.elem[i];
                    ++i;
                    return OK;
            }
            return ERROR;
        }else
        printf("线性表L不存在");
        return ERROR;
    }//NextElem_Sq
    //在L中第i个位置之前插入新的数据元素e,L的长度加1
    //一般情况下,在第i(1<=i<=n)个元素之前插入一个元素时,需要将第n至第i(共n-i+1)个元素向后移动一个位置
    //假如pi是在第i个元素之前插入一个元素的概率,则在长度为n线性表中插入一个元素时所需移动元素的期望值(平均次数)为E(is)=pi(n-i+1),(i从1到n+1的和式)。
    //不失一般性,我们可以假定在线性表的任何位置上插入,即,pi=1/(1+n),则上式可简化为,E(is)=n/2。可见在顺序存储结构的线性表插入一个元素,平均约移动表中一半元素。若表长为n,则这个算法的时间复杂度为O(n)。
    Status ListInsert_Sq(SqlList &L,int i,ElemType e)
    {
        if(L.elem!=NULL)
        {
            if(i<1||i>L.length+1) return ERROR;
            if(L.length>=L.listsize)
            {
                ElemType *newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
                if(!newbase)
                {
                    exit(OVERFLOW);//存储分配失败
                }
                L.elem=newbase;//新基址
                L.listsize+=LISTINCREMENT;//增加存储容量
            }
            ElemType *q,*p;
            q=&L.elem[i-1];
            for(p=&L.elem[L.length-1];p>=q;p--) *(p+1)=*p;//插入位置及以后元素后移
            *q=e;//插入e
            ++L.length;//表长增1
            return OK;
        }else
        printf("线性表L不存在");
        return ERROR;
    }//ListInsert_Sq
    //删除L的第i个数据元素,并用e返回其值,L的长度减1
    //一般情况下,删除第(1<=i<=n)个元素时需从第i+1至第n个(共n-i)个元素依次向前移动一个位置
    //假如qi是在第i个删除第i个元素的概率,则在长度为n的线性表中删除一个元素时所需移动元素的次数的期望(平均次数为)E(dl)=qi(n-i),(i从n的和式)。
    //不失一般性,我们可以假定在线性表的任何位置上删除元素都是等概率的,即qi=1/n,则上式可简化为,E(dl)=(n-1)/2。可见在顺序存储结构的线性表删除一个元素,平均约移动表中一半元素。若表长为n,则这个算法的时间复杂度为O(n)。
    Status ListDelete_Sq(SqlList &L,int i,ElemType &e)
    {
        if(L.elem!=NULL)
        {
            if(i<1||i>L.length) return ERROR;//i的位置不合法
            ElemType *p,*q;
            p=&L.elem[i-1];//p为被删除元素的位置
            e=*p;//被删除的元素赋给e
            q=L.elem+L.length-1;//表尾元素的位置
            for(++p;p<=q;++p) *(p-1)=*p;//被删除元素之后的元素左移
            --L.length;
            return OK;
        }else
        printf("线性表L不存在");
        return ERROR;
    }//ListDelete_Sq
    //依次对L的每个数据元素调用函数visit().一旦visit失败,则操作失败
    //O(n)
    void ListTraverse_Sq(SqlList L,Status (*visit)(ElemType))
    {
        if(L.elem!=NULL)
        {
            if(L.length==0)
            {
                printf("线性表为空 ");
            }else
            {
                for(int i=1;i<=L.length;i++)
                {
                    if((*visit)(L.elem[i-1]))
                    {
                    
                    }
                    else
                    {
                        printf("数据遍历失败");
                        return;
                    }
                }
                printf("线性表为:");
                for(int i=1;i<=L.length;i++)
                {
                    printf("%d,",L.elem[i-1]);
                }
            }
        }else
        {
            printf("线性表L不存在 ");
        }
    }//ListTraverse_Sq
    //L中第i个元素赋值同e的值
    //O(1)
    Status PutElem_Sq(SqlList L,int i,ElemType &e)
    {
        if(L.elem!=NULL)
        {
            if(i<1||i>L.length)
            {
                printf("赋值在线性表中的位置非法 ");
                return ERROR;
            }else{
                L.elem[i-1]=e;
                return OK;
            }
        }
        else
        {
            printf("线性表L不存在 ");
            return ERROR;
        }
    }//PutElem_Sq
    //两个顺序表合并
    //O(La.length+Lb.length)
    void MergeList_Sq(SqlList La,SqlList Lb,SqlList &Lc)
    {
        //已知顺序线性表La和Lb的元素按值非递减排列
        //归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列
        ElemType *pa=La.elem;
        ElemType *pb=Lb.elem;
        Lc.listsize=Lc.length=La.length+Lb.length;
        ElemType *pc=Lc.elem=(ElemType *)malloc(Lc.listsize*sizeof(ElemType));
        if(!Lc.elem) exit(OVERFLOW);//存储分配失败
        ElemType *pa_last=La.elem+La.length-1;
        ElemType *pb_last=Lb.elem+Lb.length-1;
        while(pa<=pa_last&&pb<=pb_last)
        {
            if(*pa<=*pb)*(pc++)=*(pa++);
            else *(pc++)=*(pb++);
        }
        while(pa<=pa_last) *(pc++)=*(pa++);//插入La的剩余元素
        while(pb<=pb_last) *(pc++)=*(pb++);//插入Lb的剩余元素
    }//MergeList_Sq
    int main()
    {
        SqlList L,La,Lb,Lc;
        ElemType i,e;
        //初始化线性表
        InitList_Sq(L);
        InitList_Sq(La);
        InitList_Sq(Lb);
        for(i=1;i<=LISTINCREMENT;i++)
        {
            ListInsert_Sq(La,i,i);
            ListInsert_Sq(Lb,i,i+1);
        }
        MergeList_Sq(La,Lb,Lc);
        printf("线性表La中的元素为:");
        for(i=1;i<=La.length;i++)
        {
            GetElem_Sq(La,i,e);
            printf("%d,",e);
        }
        printf(" 线性表La中的元素为:");
        for(i=1;i<=Lb.length;i++)
        {
            GetElem_Sq(Lb,i,e);
            printf("%d,",e);
        }
        printf(" 线性表Lc中的元素为:");
        for(i=1;i<=Lc.length;i++)
        {
            GetElem_Sq(Lc,i,e);
            printf("%d,",e);
        }
        DestroyList_Sq(La);
        DestroyList_Sq(Lb);
        DestroyList_Sq(Lc);
        /*for(i=1;i<=LISTINCREMENT;i++)
        {
            L.elem[i-1]=i;
            L.length++;
        }*/
        //给线性表赋值
        /*for(i=1;i<=LISTINCREMENT;i++)
        {
            ListInsert_Sq(L,i,i);
        }*/
        /*printf("线性表中的元素为:");
        for(i=1;i<=LISTINCREMENT;i++)
        {
            GetElem_Sq(L,i,e);
            printf("%d,",e);
        }*/
        /*printf("线性表L元素为:");
        //直接给线性表赋值,有可能会产生溢出现象,如果下标超出内存分配上届
        for(i=1;i<=LISTINCREMENT;i++)
        {
            printf("%d,",L.elem[i-1]);
        }*/
        //遍历整个线性表L
        //ListTraverse_Sq(L);
        //得到线性表长度
        ListLength_Sq(L);
        //判断线性表是否为空
        ListEmpty_Sq(L);
        //清空线性表中的数据
        ClearList_Sq(L);
        //销毁整个线性表
        DestroyList_Sq(L);
        //清空线性表中的数据
        ClearList_Sq(L);
        getchar();
        getchar();
        return 0;
    }

  • 相关阅读:
    MySQL-索引和磁盘操作的关系
    P6033 合并果子 加强版
    电子海图开发第三十二篇 , s57,s52标准电子海图,绘图指令的解析(共一百篇)
    电子海图开发第三十一篇 , s57,s52标准电子海图,面物标区域的图案填充,符号,边界(共一百篇)
    电子海图开发第三十篇 , s57,s52标准电子海图,面物标区域的图案填充(共一百篇)
    电子海图开发第二十九篇 , s57,s52标准电子海图,面物标对象中心图标的绘制(共一百篇)
    电子海图开发第二十八篇 , s57,s52标准电子海图,面物标对象的绘制(共一百篇)
    电子海图开发第二十七篇 , s57,s52标准电子海图,复杂矢量线型符号的渲染续(共一百篇)
    电子海图开发第二十六篇。s57,s52标准电子海图,复杂矢量线型符号的渲染(共一百篇)
    电子海图开发第二十五篇,s52显示标准,海图的符号绘制方法(共一百篇)
  • 原文地址:https://www.cnblogs.com/likewithyou/p/5838893.html
Copyright © 2011-2022 走看看