`

线性表的顺序存储—顺序表

阅读更多

      线性表的顺序存储结构:把线性表中的所有元素按照其逻辑顺序依次存储到从计算机存储器中指定存储位置开始的一块连续的存储空间中。

      这样,线性表中第一个元素的存储位置就是指定的存储位置,第i+1个元素(1≤i≤n-1)的存储位置紧接在第i个元素的存储位置的后面。

      说明:由于C中数组的下标从0开始,线性表的第i个元素ai存放顺序表的第i-1位置上。为了清楚,将ai在逻辑序列中的位置称为逻辑位序,在顺序表中的位置称为物理位序。

线性表<----> 逻辑结构

顺序表 <---> 存储结构

 

优点:

无须为表示表中元素之间的逻辑关系而增加额外的存储空间。

可以快速地存取表中任意位置的元素。

 

缺点:

插入和删除操作需要移动大量元素。

当线性表长度变化较大时,难以确定存储空间的容量。

容易造成存储空间的“碎片”。

 

 

#define LIST_INIT_SIZE 100  // 线性表存储空间的初始分配量
#define LISTINCREMENT 10    // 线性表存储空间的分配增量
#define OK 0
#define ERROR 1
#define OVERFLOW 0
typedef int ElemType;

/** 线性表的动态分配顺序存储结构 */
typedef struct
{
    ElemType *elem;  // 存储空间基址
    int length;  // 当前长度
    int listsize;  //当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;

/*************************************************
 * Function: InitList
 * Description: 初始化空间
 * param: L SqList* 顺序表
 * Return: int
 * Others: 时间复杂度为O(1)
 *************************************************/
int InitList(SqList *L)
{
    L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
    if(!L->elem)
        exit(OVERFLOW);  //存储分配失败
    L->length = 0;  // 空表长度为0
    L->listsize = LIST_INIT_SIZE;  // 初始存储容量
    return OK;
}
/*************************************************
 * Function: AddListSize
 * Description: 为顺序表增加空间
 * param: L SqList* 顺序表
 * Return: int
 * Others: 时间复杂度为O(1)
 *************************************************/
int AddListSize(SqList *L)
{
    ElemType *newbase = (ElemType *)realloc(L->elem,(L->listsize + LISTINCREMENT) * sizeof(ElemType));
    if(!newbase)
    {
        exit(OVERFLOW);
    }
    L->elem = newbase;
    L->listsize += LISTINCREMENT;
    return OK;
}
/*************************************************
 * Function: CreateList
 * Description: 为顺序表赋值
 * param: L SqList* 顺序表
          a[] ElemType 数组
          n int 长度
 * Others: 时间复杂度为O(n)
 *************************************************/
void CreateList(SqList *L, ElemType a[], int n)
{
    int i;

    /** 如果顺序表没有容量,初始化容量 */
    if(L->listsize == 0)
    {
        InitList(L);  //调用初始化函数
    }

    /** 如果顺序表的容量小于长度,增加容量 */
    if(L->listsize < n)
    {
        AddListSize(L);  // 调用增加容量函数
    }

    /** 顺序表赋值 */
    for(i = 0; i < n; i++)
    {
        L->elem[i] = a[i];
    }
    L->length = n;  // 线性表长度赋值
}

 /*************************************************
 * Function: ListInSert
 * Description: 在顺序表中第i个位置前插入新元素e,
 * param: L SqList* 顺序表
 *        i int 插入的位置
 *        e ElemType 插入的元素
 * Return: int
 * Others: 时间复杂度为O(n)
 *************************************************/
int ListInSert(SqList *L, int i, ElemType e)
{
    int k;

    /** 如果顺序表的长度大于或等于现象表的容量,增加容量 */
    if(L->length >= L->listsize)
    {
        AddListSize(L);  // 调用增加容量函数
    }

    /** 位置应该从1开始到表长+1,位置i如果小于1或者大于顺序表的长度,函数结束 */
    if(i < 1 || i > L->length+1)
    {
        return ERROR;
    }

    /** 插入位置以及之后的元素后移 */
    for(k = L->length-1; k >= i-1; k--)  //
    {
        L->elem[k+1] = L->elem[k];
    }
    L->elem[i-1] = e;  // 插入元素
    L->length +=1;  //表长加1
    return OK;
}

/*************************************************
 * Function: ListDelete
 * Description: 删除顺序表中第i个位置的元素并将删除的元素赋值给e
 * param: L SqList* 顺序表
 *        i int 删除的位置
 *        e ElemType 删除的元素
 * Return: int
 * Others: 时间复杂度为O(n)
 *************************************************/
int ListDelete(SqList *L, int i, ElemType *e)
{
    int k;

    /** 如果顺序表的长度为零,顺序表中没有元素,函数结束 */
    if(L->length == 0)
    {
        return ERROR;
    }

    /** 位置应该从1开始到表长+1,位置i如果小于1或者大于顺序表的长度,函数结束 */
    if(i < 1 || i > L->length)
    {
        return ERROR;
    }

    *e = L->elem[i-1];  // 将删除的元素给e

    /** 删除位置之后的元素前移 */
    for(k = i; k < L->length; k++)
    {
        L->elem[k-1] = L->elem[k];
    }
    L->length--;  // 线性表的长度-1
    return OK;
}

/*************************************************
 * Function: DestroyList
 * Description: 删除顺序表,释放存储空间
 * param: L SqList* 顺序表
 * Return: int
 * Others: 时间复杂度为O(1)
 *************************************************/
void DestroyList(SqList *L)
{
    L->length = 0; // 长度0
    L->listsize = 0; // 容量0
    free(L);  // 释放空间
}

/*************************************************
 * Function: ClearList
 * Description: 清空顺序表中的元素
 * param: L SqList* 顺序表
 * Return: int
 * Others: 时间复杂度为O(1)
 *************************************************/
int ClearList(SqList *L)
{
    L->length = 0;  // 线性表的长度设置为0
    return OK;
}

/*************************************************
 * Function: ListEmpty
 * Description: 顺序表是否为空
 * param: L SqList* 顺序表
 * Return: int 0代表顺序表为空,1代表顺序表不为空
 * Others: 时间复杂度为O(1)
 *************************************************/
int ListEmpty(SqList *L)
{
    if(L->length >0)
    {
        return ERROR;
    }
    else
    {
        return OK;
    }
}

/*************************************************
 * Function: ListLength
 * Description: 顺序表的长度
 * param: L SqList* 顺序表
 * Return: int 顺序表的长度
 * Others: 时间复杂度为O(1)
 *************************************************/
int ListLength(SqList *L)
{
    return L->length;
}

/*************************************************
 * Function: GetElem
 * Description: 获取顺序表中第i个位置的元素,并赋值给e
 * param: L SqList* 顺序表
 *        i int 元素的位置
 *        e ElemType 元素
 * Return: int
 * Others: 时间复杂度为O(1)
 *************************************************/
int GetElem(SqList *L,int i, ElemType *e)
{
    /** 位置应该从1开始到表长+1,位置i如果小于1或者大于顺序表的长度,函数结束 */
    if(i <1 || i > L->length)
    {
        return ERROR;
    }
    *e = L->elem[i-1];  // 逻辑位置i 物理位置应为i-1
    return OK;
}

/*************************************************
 * Function: LocateElem
 * Description: 获取顺序表中元素所在的位置
 * param: L SqList* 顺序表
 *        e ElemType 元素
 * Return: int 元素所在的位置
 * Others: 时间复杂度为O(n)
 *************************************************/
int LocateElem(SqList *L, ElemType e)
{
    int i = 0;

    /** 循环顺序表的长度,找出元素。 */
    while(i < L->length && L->elem[i] != e)
    {
        i++;
    }

    /** 循环结束后,i大于或等于顺序表的长度,说明没有找到,函数结束 */
    if(i >= L->length)
    {
        return ERROR;
    }

    return i+1;  // 逻辑位置i从1开始,物理位置从0开始,返回逻辑位置。
}

/*************************************************
 * Function: DispList
 * Description: 输出显示显示顺序表
 * param: L SqList* 顺序表
 * Others: 时间复杂度为O(n)
 *************************************************/
void DispList(SqList *L)
{
    int i;

    /** 如果顺序表的长度为零,顺序表中没有元素,函数结束 */
    if(L->length == 0)
    {
        return ERROR;
    }

    /** 循环顺序表,输出元素。 */
    for(i = 0; i < L->length; i++)
    {
        printf("%d,",L->elem[i]);
    }
    printf("\n");
}

/*************************************************
 * Function: unionList
 * Description: 合并两个顺序表,将说有在顺序表LB中但不在LA中的元素插入到LA中
 * param: LA SqList* 顺序表
 * param: LB SqList* 顺序表
 * Others: 时间复杂度为O(ListLength(LA)*ListLength(LB))
 *************************************************/
void unionList(SqList *LA, SqList *LB)
{
    int lalen = LA->length;  // 获得顺序表LA的长度
    int lblen = LB->length;  // 获取顺序表LB的长度
    int i;
    ElemType e;

    /** 循环顺序表LB 找出在LB中但不在LA中的元素插入到LA中 */
    for(i = 1; i <= lblen; i++)
    {
        GetElem(LB,i,e);  // 调用GetElem函数,取LB中第i个数据元素赋给e

        /** LA中不存在和e相同者,插入到LA中 */
        if(!LocateElem(LA,e))
        {
            ListInSert(LA,++lalen,e);
        }
    }
}

/*************************************************
 * Function: Inverse
 * Description: 顺序表的逆置
 * param: L SqList* 顺序表
 * Others: 时间复杂度为O(n)
 *************************************************/
void Inverse(SqList *L)
{
    int low=0,high=L->length-1;
    ElemType temp;
    int i;
    for(i=0; i<L->length/2; i++)
    {
        temp=L->elem[low];
        L->elem[low++]=L->elem[high];
        L->elem[high--]=temp;
    }
}
int main()
{
    SqList L;
    int length,a,i,pos;
    ElemType temp;
    InitList(&L);
    printf("请先初始化顺序表\n");
    printf("输入顺序表的长度:");
    scanf("%d",&length);
    printf("输入顺序表的元素:");
    for(i=0; i<length; i++)
    {
        scanf("%d",&temp);
        ListInSert(&L,i+1,temp);
    }
    printf("创建好的顺序表L=");
    DispList(&L);
    while(1)
    {
        printf("功能:\n");
        printf("\t【1】显示顺序表元素\n\t【2】插入元素\n\t【3】删除元素\n\t【4】查找元素\n\t【5】显示顺序表长度\n\t【6】倒置顺序表\n\t【0】退出\n");
        printf("请选择功能:");
        scanf("%d",&a);
        if(a == 0)
        {
            return 0;
        }
        else if(a == 1)
        {
            printf("创建好的顺序表La=");
            DispList(&L);
        }
        else if(a == 2)
        {
            printf("请输入插入位置:");
            scanf("%d",&pos);
            printf("请输入插入元素:");
            scanf("%d",&temp);
            int is = ListInSert(&L,pos,temp);
            if( is == 0)
            {
                printf("插入成功!\n");
            }
            else
            {
                printf("插入失败!\n");
            }
        }
        else if(a == 3)
        {
             printf("请输入删除元素的位置:");
             scanf("%d",&pos);
             int is = ListDelete(&L, pos, &temp);
             if(is == 0)
             {
                 printf("删除的元素为%d!\n",temp);
             }
             else
             {
                 printf("删除失败!\n");
             }
        }
        else if(a == 4)
        {
            printf("请输入要查找的元素:");
            scanf("%d",&temp);
            printf("要查找的元素在:%d\n",LocateElem(&L,temp));
        }
        else if(a == 5)
        {
            printf("顺序表的长度为:%d\n",ListLength(&L));
        }
        else if(a == 6)
        {
            Inverse(&L);
            printf("倒置后的顺序表L=");
            DispList(&L);
        }
    }
    return 0;
}

 

 

2
1
分享到:
评论

相关推荐

    线性表顺序存储运算的算法实现

    在计算机科学中,线性表的顺序存储是常用的数据组织方式,其特点是元素在内存中按顺序连续存放。本话题将深入探讨线性表的顺序存储结构及其在C语言中的算法实现,包括线性表的输入输出、插入、删除以及长度和置空...

    线性表顺序存储的实现

    本文将深入探讨线性表顺序存储的实现,以及与其相关的算法和数据结构知识。 首先,顺序存储结构通常采用数组来实现。数组是一种在内存中连续存储的数据结构,每个元素可以通过下标访问。线性表的元素在数组中依次...

    数据结构实验指导书,线性表顺序存储结构的操作

    数据结构实验指导书,线性表顺序存储结构的操作 本资源提供了一个关于线性表顺序存储结构的操作实验指导书,涵盖了线性表的基本运算、顺序存储结构的实现、主程序设计等内容。实验的目的是掌握用 VC++ 调试程序的...

    线性表顺序存储实现

    线性表顺序存储实现,学习数据结构的链表中较为基础的顺序链表存储,实现对应的。h文件的函数实现

    线性表的顺序存储与实现

    线性表是计算机科学中一种基础的数据结构,它是由n(n≥0)个相同...提供的文件"02-线性表的顺序存储与实现"很可能是关于如何在具体编程语言中实现这些操作的示例代码,可以作为学习和理解线性表顺序存储的参考资料。

    线性表顺序存储结构实现通讯录

    C++数据结构 线性表顺序存储结构实现通讯录

    数据结构 线性表 顺序表基本操作

    线性表的顺序表的建立、插入、删除、输出等操作。

    数据结构——vc6对话框编程,线性表顺序存储操作

    4. **四_线性表顺序存储**: 这个文件名可能指的是一个示例项目或源代码文件,包含了实现上述操作的具体代码。这个文件可能会定义一个线性表类,包含追加、插入和删除方法,以及可能的辅助函数,如显示当前线性表...

    线性表顺序存储结构的运算

    在文件`sqlist`中,可能包含了关于如何在SQL环境中实现线性表的顺序存储结构以及相关的操作示例,如创建表、插入数据、更新数据和删除数据等。 对于学习和理解线性表的顺序存储结构,不仅要知道基本概念,还要掌握...

    线性表的顺序存储 线性表的顺序存储

    在顺序存储结构中,线性表的元素被存储在一个一维数组中,按照它们在表中的相对位置来表示数据之间的逻辑关系。这种方式简单直观,易于理解和操作。 线性表的顺序存储具有以下特点: 1. **连续存储**:所有元素存储...

    关于线性表的顺序存储和链式存储结构的实验报告

    在这个实验报告中,顺序存储结构通过定义一个结构体来表示线性表,包括三个字段:elem表示线性表首元素的地址,length表示线性表的长度,listsize表示线性表的最大容量。顺序存储结构的优点是随机访问速度快,因为...

    线性表的顺序存储的实现

    线性表的顺序存储的实现

    线性表顺序存储(C语言)

    数据结构课程中的线性表顺序存储,使用C语言实现。

    线性表顺序存储C语言实现

    在IT领域,数据结构是计算机科学中的核心概念,它研究如何高效地组织和管理数据。线性表是一种基本且常用的数据结构,它是由n(n...在DEV环境下,你可以使用这些函数来创建和操作线性表,并通过EDV顺序表文件进行实践。

    实验一 线性表的顺序存储实验

    ### 实验一 线性表的顺序存储实验 #### 实验目的 1. **掌握在Visual C++ 6.0环境下调试顺序表的基本方法**:通过本实验,学生能够熟悉Visual C++ 6.0集成开发环境,并学会如何在这个环境中进行程序的编写、编译与...

    MFC线性表顺序存储

    这个例子可能包含了一个使用CArray实现线性表顺序存储的代码实例,通过学习和实践,你可以更好地理解数据结构在实际编程中的应用。无论你是初学者还是有经验的开发者,理解并掌握这些基本数据结构及其操作都是非常有...

    dm02_线性表顺序存储设计与实现.rar_bound7nd_cake165_数据结构

    《线性表顺序存储设计与实现》 在计算机科学中,数据结构是研究如何组织、存储和处理数据的科学。线性表是最基础且广泛使用的一种数据结构,它由n(n≥0)个相同类型元素构成的有限序列。本资料“dm02_线性表顺序...

Global site tag (gtag.js) - Google Analytics