首页 > 代码库 > 线性表的动态内存分配顺序存储结构

线性表的动态内存分配顺序存储结构

1.线性表是最简单的一种数据结构,很容易实现其中单个元素的存取操作,但是对于插入和删除操作需要大量的移动。比较适用于相对稳定的线性表。

2.数据元素

struct SqList
{
    ElemType * elem ;        //存储空间基址
    int length ;             //当前长度
    int listsize ;           //当前分配的存储容量
};

3.创建一个空的线性表

void InitList(SqList &L)
{
    //构造一个空的顺序线性表L
    L.elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
    if(NULL==L.elem)
        exit(OVERFLOW);        //分配失败
    L.length = 0;        //暂时只有0个内容
    L.listsize = LIST_INIT_SIZE;
}

4.销毁一个线性表

void DestroyList(SqList &L)
{
    //销毁顺序表L
    free(L.elem);
    L.elem = NULL;
    L.length = 0;
    L.listsize = 0;
}

5.清空一个线性表

void ClearList(SqList &L)
{
    L.length = 0;         //有效内容为0个
}

6.判断表是否为空

Status ListEmpty(SqList L)
{
    //空表?
    if(L.length==0)
        return TRUE;
    else
        return FALSE;
}

7.求表的有效元素数据个数

int ListLength(SqList L)
{
    return L.length;
}

8.取得表中的某个元素

Status GetElem(SqList L, int i, ElemType &e)
{
    if(i<1||i>L.length)
        return ERROR;
    e = *(L.elem + i - 1);
    return OK;
}

9.查找特定的元素

int LocateElem(SqList L,ElemType e, Status (*compare)(ElemType,ElemType))
{
    //返回L中第一个与元素e满足compare()的数据元素的位序
    //Status (*compare)(ElemType,ElemType) 这里定义的一个函数指针,使用它来作为参数,称为回调
    //compare 是一个函数指针
    int i = 1;
    ElemType *p = L.elem ;
    while(i<=L.length && !compare(*p++,e))
        i++ ;
    if(i<=L.length)
        return i ;
    else
        return 0;
}

10.获取某个元素的前驱后继

Status PriorElem(SqList L, ElemType cur_e, ElemType &pre_e)
{
    //返回cur_e 的前驱,用pre_e
    int i = 2;
    ElemType* p = L.elem+1;        //指向第2个
    while(i<=L.length && *p != cur_e)
    {
        p++;
        i++;
    }
    if(i>L.length)
        return ERROR;
    else
    {
        pre_e = *(--p);
        return OK;
    }    
}

Status NextElem(SqList L,ElemType cur_e,ElemType &next_e)
{
    int i=1;
    ElemType* p = L.elem;
    while(i<=L.length && *p !=cur_e)
    {
        p++;
        i++;
    }
    if(i>L.length)
        return ERROR;
    else
    {
        next_e = *(++p);
        return OK ;
    }
}

11. 向表中插入一个元素

Status ListInsert(SqList &L, int i, ElemType e)
{
    ElemType * newbase,*p,*q;
    if(i<1||i>L.length+1)
        return ERROR;
    if(L.length == L.listsize)    //分配的空间都有数据
    {
        newbase = (ElemType*)realloc(L.elem, (L.listsize+LIST_INCREMENT)*sizeof(ElemType));
        if(!newbase)
            exit(OVERFLOW);
        L.elem = newbase;
        L.listsize += LIST_INCREMENT;
    }
    q = L.elem + i-1;
    for(p = L.elem+L.length-1; p>=q; p--)        //从后往前挪
    {
        *(p+1) = *p ;
    }
    *q = e;
    ++L.length;
    return OK;
}

12.删除一个元素

Status ListDelete(SqList &L,int i, ElemType &e)
{
    ElemType *p, *q;
    if(i<1||i>L.length)
        return ERROR;
    p = L.elem +i-1;
    e = *p;
    q = L.elem +L.length -1;
    for(++p;p<=q;++p)
    {
        *(p-1)=*p;
    }
    L.length--;
    return OK ;
}

13.遍历表中的元素

void ListTraverse(SqList L,void (*visit)(ElemType &))
{
    ElemType *p = L.elem;
    int i;
    for(i=1; i<=L.length; i++)
    {
        visit(*p++);
        printf("\n");
    }
}

 

最终的测试代码

技术分享
//线性表的动态分配顺序存储结构

//内存分配 malloc()
#include<malloc.h>        //malloc()
#include<stdlib.h>        //atoi(),exit()
#include<math.h>        //OVERFLOW==3
#include<stdio.h>

typedef int Status;
typedef int Boolean;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0


typedef int ElemType ;        //以整型为例
#define    LIST_INIT_SIZE 10        //线性表存储空间的初始分配量
#define LIST_INCREMENT 2        //分配增量

struct SqList
{
    ElemType * elem ;        //存储空间基址
    int length ;            //当前长度
    int listsize ;             //当前分配的存储容量
};

void InitList(SqList &L)
{
    //构造一个空的顺序线性表L
    L.elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
    if(NULL==L.elem)
        exit(OVERFLOW);        //分配失败
    L.length = 0;        //暂时只有0个内容
    L.listsize = LIST_INIT_SIZE;
}

void DestroyList(SqList &L)
{
    //销毁顺序表L
    free(L.elem);
    L.elem = NULL;
    L.length = 0;
    L.listsize = 0;
}
void ClearList(SqList &L)
{
    L.length = 0;         //有效内容为0个
}

Status ListEmpty(SqList L)
{
    //空表?
    if(L.length==0)
        return TRUE;
    else
        return FALSE;
}

int ListLength(SqList L)
{
    return L.length;
}

Status GetElem(SqList L, int i, ElemType &e)
{
    if(i<1||i>L.length)
        return ERROR;
    e = *(L.elem + i - 1);
    return OK;
}


int LocateElem(SqList L,ElemType e, Status (*compare)(ElemType,ElemType))
{
    //返回L中第一个与元素e满足compare()的数据元素的位序
    //Status (*compare)(ElemType,ElemType) 这里定义的一个函数指针,使用它来作为参数,称为回调
    //compare 是一个函数指针
    int i = 1;
    ElemType *p = L.elem ;
    while(i<=L.length && !compare(*p++,e))
        i++ ;
    if(i<=L.length)
        return i ;
    else
        return 0;
}


Status PriorElem(SqList L, ElemType cur_e, ElemType &pre_e)
{
    //返回cur_e 的前驱,用pre_e
    int i = 2;
    ElemType* p = L.elem+1;        //指向第2个
    while(i<=L.length && *p != cur_e)
    {
        p++;
        i++;
    }
    if(i>L.length)
        return ERROR;
    else
    {
        pre_e = *(--p);
        return OK;
    }    
}

Status NextElem(SqList L,ElemType cur_e,ElemType &next_e)
{
    int i=1;
    ElemType* p = L.elem;
    while(i<=L.length && *p !=cur_e)
    {
        p++;
        i++;
    }
    if(i>L.length)
        return ERROR;
    else
    {
        next_e = *(++p);
        return OK ;
    }
}

Status ListInsert(SqList &L, int i, ElemType e)
{
    ElemType * newbase,*p,*q;
    if(i<1||i>L.length+1)
        return ERROR;
    if(L.length == L.listsize)    //分配的空间都有数据
    {
        newbase = (ElemType*)realloc(L.elem, (L.listsize+LIST_INCREMENT)*sizeof(ElemType));
        if(!newbase)
            exit(OVERFLOW);
        L.elem = newbase;
        L.listsize += LIST_INCREMENT;
    }
    q = L.elem + i-1;
    for(p = L.elem+L.length-1; p>=q; p--)        //从后往前挪
    {
        *(p+1) = *p ;
    }
    *q = e;
    ++L.length;
    return OK;
}

Status ListDelete(SqList &L,int i, ElemType &e)
{
    ElemType *p, *q;
    if(i<1||i>L.length)
        return ERROR;
    p = L.elem +i-1;
    e = *p;
    q = L.elem +L.length -1;
    for(++p;p<=q;++p)
    {
        *(p-1)=*p;
    }
    L.length--;
    return OK ;
}

void ListTraverse(SqList L,void (*visit)(ElemType &))
{
    ElemType *p = L.elem;
    int i;
    for(i=1; i<=L.length; i++)
    {
        visit(*p++);
        printf("\n");
    }
}

Status equal(ElemType a,ElemType b)
{
    if(a==b)
        return TRUE;
    else
        return FALSE;
}

int comp(ElemType a,ElemType b)
{
    if(a==b)
        return 0;
    else
        return (a-b)/abs(a-b);
}
void printdec(ElemType dec)
{
    printf("%d",dec);
}

void printref(ElemType &ref)
{
    printf("%d",ref);
}

void printchar(ElemType ch)
{
    printf("%c",ch);
}

Status sq(ElemType a,ElemType b)
{
    //判定平方关系
    if(a==b*b)
        return TRUE;
    else
        return FALSE;
}

void Double(ElemType &c)
{
    c *= 2;
}


int main(void)
{
    SqList L;
    ElemType e,e0;
    Status i;
    int j,k;
    InitList(L);
    printf("初始化后,L.length = %d,L.listsize = %d,L.elem = %#x\n",L.length,L.listsize,L.elem);
    
    for(j=1;j<=5;j++)
        i = ListInsert(L,1,j);
    printf("在L的表头一次插入1,2,3,4,5,后,*L.elem = ");
    for(j=1;j<=L.length;j++)
        printf("%d ",*(L.elem+j-1));
    printf("\n");
    
    ListTraverse(L,printref);
    i = ListEmpty(L);    //是否为空?
    printf("L.length = %d,L.listsize = %d",L.length,L.listsize);
    printf("L.elem = %u,L是否为空? i = %d\n",L.elem,i);
    
    ClearList(L);
    i = ListEmpty(L);    //是否为空?
    printf("L.length = %d,L.listsize = %d",L.length,L.listsize);
    printf("L.elem = %u,L是否为空? i = %d\n",L.elem,i);
    
    for(j=1;j<=10;j++)
        i = ListInsert(L,j,j);        //在表尾插入
    
    printf("在L的表尾一次插入1--10,后,*L.elem = ");
    for(j=1;j<=L.length;j++)
        printf("%d ",*(L.elem+j-1));
    printf("\n");
    ListTraverse(L,printref);
    ListInsert(L,1,0);
    ListTraverse(L,printref);
    
    GetElem(L,5,e);
    printf("第5个元素为:%d\n",e);
    
    for(j=10;j<=11;j++)
    {
        k = LocateElem(L,j,equal);
        if(k)
            printf("第%d个元素的值为%d,",k,j);
        else
            printf("没有元素的值为%d\n",j);
    }
    
    for(j=3;j<=4;j++)
    {
        k = LocateElem(L,j,sq);
        if(k)
            printf("第%d个元素的值的平方为%d,",k,j*j);
        else
            printf("没有元素的值的平方为%d\n",j*j);
    }
    
    for(j=1;j<=2;j++)
    {
        GetElem(L,j,e);
        i = PriorElem(L,e,e0);
        if(i==ERROR)
            printf("元素%d没有前驱,",e);
        else
            printf("元素%d的前驱为%d",e,e0);
    }
    
    k = ListLength(L);
    for(j=k+1;j>=k;j--)
    {
        i = ListDelete(L,j,e);
        if(i==ERROR)
            printf("删除第%d个元素失败!",j);
        else
            printf("删除第%d个元素成功,其值为%d",j,e);
    }
    ListTraverse(L,Double);
    printf("L的元素加倍之后,L = ");
    ListTraverse(L,printref);
    DestroyList(L);
    printf("销毁L后,L.length = %d, L.listsize = %d, L.elem = %u \n",L.length,L.listsize,L.elem);
    
    printf("sizeof(L)=%d",sizeof(L));
    
    return 0;
}



void MergeList(SqList La,SqList Lb,SqList &Lc)
{
    ElemType *pa,*pa_last;
    ElemType *pb,*pb_last;
    ElemType *pc;
    pa = La.elem;
    pb = Lb.elem;
    Lc.listsize = Lc.length = La.length+Lb.length;
    pc = Lc.elem =(ElemType*)malloc(Lc.listsize*sizeof(ElemType));
    if(NULL==pc)
        exit(OVERFLOW);
    pa_last = La.elem + La.length-1;
    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++;
    while(pb<=pb_last)
        *pc++ = *pb++;
    
    
}

/*
int main(void)
{
    SqList La,Lb,Lc;
    int j;
    InitList(La);
    for(j=1;j<=5;j++)    //5个元素
        ListInsert(La,j,j);        //表尾插入
    //printf("La.length = %d,La.listsize = %d\n",La.length,La.listsize);
    printf("La = \n");
    ListTraverse(La,printref);
    
    InitList(Lb);
    for(j=1;j<=5;j++)        //5个元素
        ListInsert(Lb,j,j);    //表尾插入
    ListTraverse(Lb,Double);
    //printf("Lb.length = %d,Lb.listsize = %d\n",Lb.length,Lb.listsize);
    printf("Lb = \n");
    ListTraverse(Lb,printref);
    MergeList(La,Lb,Lc);
    printf("Lc = \n");
    ListTraverse(Lc,printref);
    
    
    
    return 0;
}




*/
View Code

 

线性表的动态内存分配顺序存储结构