线性表Linear List-线性表的顺序表示和实现

Deadly 提交于 2019-12-03 01:54:52

线性表Linear List

线性表:线性表(Linear List)是由n(n≥0)个数据元素(结点)a[0],a[1],a[2]…,a[n-1]组成的有限序列

其中:

  • 数据元素的个数n定义为表的长度 = "list".length() ("list".length() = 0(表里没有一个元素)时称为空表)

  • 将非空的线性表(n>=0)记作:(a[0],a[1],a[2],…,a[n-1])

  • 数据元素a[i](0≤i≤n-1)只是个抽象符号,其具体含义在不同情况下可以不同

 

线性表的顺序存储结构

//线性表的顺序存储结构
typedef struct{
    int *elem; //存储空间基址,即线性表的起始位置,elem指向int的指针
    int length; //当前长度
    int listsize; //当前分配的存储容量
}SqList;

 

线性表的顺序表示和实现

线性表的顺序表示指的是一组地址连续的存储单元依次存储线性表的数据元素。

线性表的顺序存储结构是一种随机存储的存储结构。

因为内存中的地址空间是线性的,因此,用物理上的相邻实现数据元素之间的逻辑相邻关系是既简单,又自然的。

由于数组类型也有随机存储的特性,因此通常用数组来描述数据结构中的顺序存储结构。

由于线性表的长度可变,且所需最大存储空间随问题不同而不同,则在C语言中可用动态分配的一维数组。

线性表的起始位置=基地址,每个数据元素占1个存储地址

线性表的顺序表示和实现:

//Sequence List
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

#define LIST_INIT_SIZE 10
#define LISTINCREMENT 2
#define OVERFLOW -2
#define OK 1
#define ERROR 0

//为内置类型int创建两个别名,新的名字
typedef int Status;
typedef int ElemType;

//线性表的顺序存储结构
typedef struct{
    int *elem; //存储空间基址,即线性表的起始位置
    int length; //当前长度
    int listsize; //当前分配的存储容量
}SqList;

//初始化顺序表
Status InitList_Sq(SqList* L);
//顺序表中插入元素
Status ListInsert_Sq(SqList* L,int i,ElemType e);
//顺序表的合并
Status MergeList_Sq(SqList La,SqList Lb,SqList* Lc);
//顺序表元素的输出
Status ListPrint_Sq(SqList* L);
//顺序表元素的删除
//删除第i个位置上的元素,并用e返回其值
Status ListDelete_Sq(SqList* L,int i,ElemType *e);

int main()
{
    SqList La,Lb,Lc;
    int i = 1;
    ElemType num = 0;
    //初始化顺序表La
    InitList_Sq(&La);
    //初始化顺序表Lb
    InitList_Sq(&Lb);

    printf("Please input the number(end by -1):\n");
    while(1)
    {
        scanf("%d",&num);
        if(num == -1)
            break;
        ListInsert_Sq(&La,i,num);
        i++;
    }
    ListPrint_Sq(&La);

    i = 1;
    printf("Please input the number(end by -1):\n");
    while(1)
    {
        scanf("%d",&num);
        if(num == -1)
            break;
        ListInsert_Sq(&Lb,i,num);
        i++;
    }
    ListPrint_Sq(&Lb);

    //顺序表合并的算法函数
    MergeList_Sq(La,Lb,&Lc);

    printf("MergeList OK\n");
    ListPrint_Sq(&Lc);\
    int dl=0;
    ListDelete_Sq(&Lc,4,&dl);
    printf("Delete OK  %d\n",dl);
    ListPrint_Sq(&Lc);
}

Status MergeList_Sq(SqList La,SqList Lb,SqList* Lc)
{
    ElemType *pa=La.elem,*pb=Lb.elem,*pc;
    ElemType *pa_last,*pb_last;
    Lc->listsize = Lc->length = La.length+Lb.length;
    pc= Lc->elem = (ElemType*)malloc(Lc->listsize*sizeof(ElemType));//为pc顺序表分配内存空间
    if(!Lc->elem)
        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){ //插入La的剩余元素
        *pc++ = *pa++;  //====>>*pc=*pa;pc++;pa++;//真的不推荐写成*pc++ = *pa++;
    }
    while(pb<=pb_last) //插入Lb的剩余元素
    {
        *pc++ = *pb++;
    }
    return OK;
}

/*
顺序表的初始化操作就是为顺序表分配一个预定义大小的数组空间,并将线性表的当前长度设为0
malloc分配指定的字节,并返回指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)
*/
Status InitList_Sq(SqList* L)
{
    //
    L->elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
    if(!L->elem) //如果顺序表分配失败
        exit(OVERFLOW);
    L->length = 0;//顺序表的当前长度为零
    L->listsize = LIST_INIT_SIZE;
    return OK;
}

/*
(ElemType*)realloc(L->elem,(L->listsize + LISTINCREMENT)*sizeof(ElemType));
realloc函数的作用:第一参数是指针,指向现有的一块内存区域,第二个参数为新的内存区域的大小
如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL
该函数功能:在顺序表L第i个位置插入元素e
*/
Status ListInsert_Sq(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 + LISTINCREMENT)*sizeof(ElemType));
        if(!newbase)
            exit(OVERFLOW);
        L->elem = newbase;
        L->listsize += LISTINCREMENT;
    }
    q = &(L->elem[i-1]); //q为元素的插入位置,是一个指针
    //&(L->elem[L->length-1])获取线性表中最后一个元素的指针
    for(p=&(L->elem[L->length-1]);p>=q;--p)
    {
        *(p+1) = *p; //元素的位置右移
    }
    *q = e; //把元素e插入位置q
    ++L->length; //把当前顺序表的长度加一

    return OK;
}



Status ListPrint_Sq(SqList* L)
{
    int i = 0;
    ElemType num = 0;
    for(i=0;i<L->length;i++)
    {
        num = L->elem[i];
        printf("No.%d\t%d\n",i,num);
    }

    return OK;
}

//在顺序表L中删除第i个元素,并用e返回其值
Status ListDelete_Sq(SqList* L,int i,ElemType *e)
{
    ElemType *p,*q;
    if(i<0||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;
}

 

运行结果:

Please input the number(end by -1):
1
2
3
4
-1
No.0    1
No.1    2
No.2    3
No.3    4
Please input the number(end by -1):
5
6
7
8
-1
No.0    5
No.1    6
No.2    7
No.3    8
MergeList OK
No.0    1
No.1    2
No.2    3
No.3    4
No.4    5
No.5    6
No.6    7
No.7    8
Delete OK  4
No.0    1
No.1    2
No.2    3
No.3    5
No.4    6
No.5    7
No.6    8

Process returned 1 (0x1)   execution time : 11.704 s
Press any key to continue.

====END====

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!