数据结构线性表的动态分配顺序存储结构算法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构造失败!\n");
            exit(OVERFLOW);//存储分配失败
        }
    L.length=0;//空表的长度为0
    L.listsize=LIST_INIT_SIZE;//初始的存储容量
    printf("线性表L构造成功!\n");
    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成功\n");
        return OK;
    }else
    {
        printf("线性表L不存在\n");    
    }
    return ERROR;
}//DestroyList_Sq
//将L重置为空表
//O(1)
Status ClearList_Sq(SqlList &L)
{
    if(L.elem!=NULL)
    {
        L.length=0;
        printf("已将线性表重置为空表!\n");
        return OK;
    }else
    printf("线性表重置为空表失败!\n");
    return ERROR;
}//ClearList_Sq
//若L为空表,则返回TRUE,否则返回FALSE
//O(1)
Status ListEmpty_Sq(SqlList L)
{
    if(L.elem!=NULL&&L.length==0)
    {
        printf("线性表L为空表\n");
        return TRUE;
    }else if(L.elem!=NULL)
    {
        printf("线性表L不为空表\n");
        return FALSE;
    }else{
        printf("线性表L不存在\n");
        return FALSE;
    }
}//ListEmpty_Sq
//返回L中数据元素的个数
//o(1)
Status ListLength_Sq(SqlList L)
{
    if(L.elem!=NULL)
    {
        printf("线性表L的长度为%d\n",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("线性表为空\n");
        }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不存在\n");
    }
}//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("赋值在线性表中的位置非法\n");
            return ERROR;
        }else{
            L.elem[i-1]=e;
            return OK;
        }
    }
    else
    {
        printf("线性表L不存在\n");
        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("\n线性表La中的元素为:");
    for(i=1;i<=Lb.length;i++)
    {
        GetElem_Sq(Lb,i,e);
        printf("%d,",e);
    }
    printf("\n线性表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;
}

时间: 2024-08-05 18:43:40

数据结构线性表的动态分配顺序存储结构算法c语言具体实现和算法时间复杂度分析的相关文章

数据结构-线性表的链式结构

线性表的链式结构,与之前说过的线性表的顺序结构差不多,区别在于存储结构和方式的不一样. 在链式中,来一个数据就去寻找一个空间存储一个结点有多少数据占多大的地方,是动态的存储方式.另外顺序表如果存储1MB就只占1MB存储空间,但是链式表不一样,它会有额外的空间去存储对应结点的指针. 这样一分析结构就出来了,链式结构为两部分:1.结点域.2.指针域.实现方法用动态存储. 1 #include "stdio.h" 2 #include "stdlib.h" 3 4 typ

[大话数据结构]线性表之单链表结构和顺序存储结构

线性表定义: 零个或者多个数据元素的有限序列.元素之间是有顺序的,如果元素存在多个,则第一个元素无前驱,最后一个元素无后继.其他每个元素都有且只有一个前驱和后继.并且数据元素的类型要相同. 线性表的抽象数据类型: ADT 线性表(List) Data 线性表的数据对象集合为{a1,a2,...,an},每个元素的类型均为DataType. 其中,除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素. 数据元素之间的关系是一对一的关系.

动态分配的顺序线性表的十五种操作—C语言实现

线性表 定义:是最常用的,也是最简单的数据结构,是长度为n个数据元素的有序的序列. 含有大量记录的线性表叫文件 记录:稍微复杂的线性表里,数据元素为若干个数据项组成,这时把一个数据元素叫记录 结构特点:在非空有限的条件下,存在唯一的一个表头结点,唯一的一个表尾结点,除去第一个元素之外,每个数据元素都只有一个前驱,除去最后一个元素之外,每一个数据元素都只有一个后继. 注意:线性表中的数据元素可以是各种各样的,但同一线性表中的元素必定具有相同特性(属于同一数据对象,类似数组).线性表的数据元素间有序

数据结构(三)——基于顺序存储结构的线性表

数据结构(三)--基于顺序存储结构的线性表 一.基于顺序存储结构的线性表实现 1.顺序存储的定义 线性表的顺序存储结构是用一段地址连续的存储单元依次存储线性表中的数据元素. 2.顺序存储结构的操作 使用一维数组实现顺序存储结构. template <typename T> class SeqList:public List<T> { protected: T* m_array;//顺序存储空间 int m_length;//当前线性表的长度 }; 一维顺序存储结构可以是原生数组或是

线性表之顺序存储结构(C语言动态数组实现)

线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链式存储结构:是用一段一段连续的内存空间存储表中每一行的数据,段与段之间通过一个引用(指针)相互连接来,形成一个链式的存储结构 看到顺序存储结构的图示,我们可能会马上联想到C语言的数组.是的,数组就是一种典型的顺序存储数据结构.下面我通过一个实例,来实现对顺序存储结构中的数据增.删.改.查的操作. 首

数据结构-线性表-顺序表

总括: 线性表是一种最简单的数据结构,线性表的主要操作特点是可以在任意位置插入和删除一个数据元素. 线性表可以用顺序存储结构和链式存储结构存储,用顺序存储结构实现的线性表称为顺序表,用链式存储结构实现线性表称为链表. 1,线性表概述: 线性表:线性表是一种可以在任意位置进行插入和删除数据元素操作的,有n个(n>=0)个相同类型数据元素a0,a1,. . .an组成的线性结构. 线性表抽象数据类型:抽象数据类型是指一个逻辑概念上的类型和这个类型上的操作集合:因此,线性表的抽象数据类型主要包括两个方

数据结构——线性表顺序存储结构

 关于线性表 线性表是零个或者多个数据元素的集合.它主要有以下三个特征: 1:线性表的数据元素之间是有顺序的. 2:线性表中数据元素个数是有限的. 3:线性表中数据元素数据类型是相同的. 关于线性表的操作,主要有 创建线性表.销毁线性表.清空线性表.将元素插入线性表.将元素从线性表中删除.获取线性表中某个位置的元素.获取线性表的长度. 线性表主要有两种存储结构: 1:线性表的顺序存储结构,c语言中的数组及采用这种方式. 2:线性表的链式存储结构. 关于顺序存储结构 定义: 是指用一段地址连续的内

线性表顺序存储结构的c语言实现

线性表顺序存储结构用C实现的操作 <1>声明一个线性表的顺序存储结构 <2> 初始化顺序线性表 <3>判断是否为空 <4>清空列表 <5>返回当前长度(线性表内元素个数) <6>返回L中第i个数据元素的值,注意i是指位置,第1个位置的数组是从0开始 <7>返回L中第1个与e满足关系的数据元素的位序.若这样的数据元素不存在,则返回值为0 <8>在L中第i个位置之前插入新的数据元素e,L的长度加1 <9>

C算法与数据结构-线性表的应用,多项式求和---ShinePans

/*---上机作业作业,二项式加法---*/ /*---By 潘尚 ---*/ /*---日期: 2014-5-8 . ---*/ /*---题目:---*/ //假设有两个稀疏多项式A和B,设计算法完成下列任务 //1.输入并建立多项式A和B; //2.求两个多项式的和多项式C; //3.求两个多项式的积多项式D; //输出4个多项式A,B,C,D; #include <stdio.h> #include <stdlib.h> #include <string.h>