线性表-顺序存储结构

线性表-顺序存储结构


下面是用c语言实现的线性表,顺序存储结构,是用一维数组实现的,即把第一个数据元素存到数组下标为0的位置中,接着把线性表相邻的元素存储在数组相邻的位置。这种顺序存储方式优点是可以快速的存取表中任一位置的元素,但是插入和删除需要移动大量元素,当线性表变化较大时,难以确定存储空间的容量,因为这种存储方式需要提前确定数组的长度,下面的MAXSIZE就是提前指定的数组长度。
正如上面介绍,线性表顺序存储结构是利用数组实现的,那么该线性表的基本操作,无非是对数组中元素的操作,那么我们很容易想到操作有:给数组特定位置添加元素、删除特定位置元素、确定线性表当前长度、清空线性表、初始化线性表等等,可以参考下面程序学习。

注:详细内容可以参考程杰的《大话数据结构》,下面代码是这本书提供的源代码


//
//  main.c
//  线性表-顺序存储
//
//


#include "stdio.h"

#include "stdlib.h"

#include "math.h"
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 20 /*线性表最大长度 */

typedef int Status;
typedef int ElemType;


Status visit(ElemType c)
{
    printf("%d ",c);
    return OK;
}

typedef struct
{
    ElemType data[MAXSIZE];        /*  数组,存储数据元素 */
    int length;                                /* 线性表当前长度 */
}SqList;                           

/* 初始化线性表*/
Status InitList(SqList *L)
{
    L->length=0;    /* L是指向链表的指针,L->length是指该指针指向链表中的length元素 */
    return OK;
}

/* 判断线性表是否为空 */
Status ListEmpty(SqList L)
{
    if(L.length==0)
        return TRUE;
    else
        return FALSE;
}

/* 清空线性表 */
Status ClearList(SqList *L)
{
    L->length=0;
    return OK;
}

/* 返回线性表当前长度 */
int ListLength(SqList L)
{
    return L.length;
}

/* 获取线性表第i个元素,并用e返回*/
Status GetElem(SqList L,int i,ElemType *e)
{
    if(L.length==0 || i<1 || i>L.length)
        return ERROR;
    *e=L.data[i-1];
    
    return OK;
}


/* 判断线性表中是否存在值为e的元素,若存在,返回它的位置 */
int LocateElem(SqList L,ElemType e)
{
    int i;
    if (L.length==0)
        return 0;
    for(i=0;i<L.length;i++)
    {
        if (L.data[i]==e)
            break;
    }
    
    if(i>=L.length)//不存在该元素,返回0
        return 0;
    
    return i+1;
}



/* 将e元素插入到线性表的第i个位置 */
Status ListInsert(SqList *L,int i,ElemType e)
{
    int k;
    if (L->length==MAXSIZE)  /* 链表最大长度 */
        return ERROR;
    if (i<1 || i>L->length+1)/* 插入位置大于表长,或者小于1,报错 */
        return ERROR;
    
    if (i<=L->length)        /* 插入位置不在表尾 */
    {
        for(k=L->length-1;k>=i-1;k--)  /*将第i个位置至最后元素都向后移动一位 */
            L->data[k+1]=L->data[k];
    }
    L->data[i-1]=e;          /* 将数据e插入到第i个位置 */
    L->length++;
    
    return OK;
}


/* 删除线性表中第i个元素,并用e返回被删除的元素 */
Status ListDelete(SqList *L,int i,ElemType *e)
{
    int k;
    if (L->length==0)
        return ERROR;
    if (i<1 || i>L->length)
        return ERROR;
    *e=L->data[i-1];
    if (i<L->length)
    {
        for(k=i;k<L->length;k++)
            L->data[k-1]=L->data[k];
    }
    L->length--;
    return OK;
}

/* 打印线性表中每个元素 */
Status ListTraverse(SqList L)
{
    int i;
    for(i=0;i<L.length;i++)
        visit(L.data[i]);
    printf("\n");
    return OK;
}
/*  */
void unionL(SqList *La,SqList Lb)
{
    int La_len,Lb_len,i;
    ElemType e;
    La_len=ListLength(*La);
    Lb_len=ListLength(Lb);
    for (i=1;i<=Lb_len;i++)
    {
        GetElem(Lb,i,&e);   //获取链表Lb中第i个元素,并用e返回
        if (!LocateElem(*La,e))   //判断条件,若链表La中不存在值为e的元素,执行下面操作
            ListInsert(La,++La_len,e);//将e插入到链表La的表尾
    }
}

int main()
{
    
    SqList L;
    ElemType e;
    Status i;
    int j,k;
    i=InitList(&L);
    printf("初始化L后:L.length=%d\n",L.length);
    for(j=1;j<=5;j++)
        i=ListInsert(&L,1,j);
    printf("在L的表头依次插入1~5后:L.data=");
    ListTraverse(L);
    
    printf("L.length=%d \n",L.length);
    i=ListEmpty(L);
    printf("L 是否为空:i=%d(1:是 0:否)\n",i);
    
    i=ClearList(&L);
    printf("清空L后:L.length=%d\n",L.length);
    i=ListEmpty(L);
    printf("L 是否:i=%d(1:是 0:否)\n",i);
    
    for(j=1;j<=10;j++)
        ListInsert(&L,j,j);
    printf("在L的表尾依次插入1~10后:L.data=");
    ListTraverse(L);
    
    printf("L.length=%d \n",L.length);
    
    ListInsert(&L,1,0);
    printf("在L的表头插入0后:L.data=");
    ListTraverse(L);
    printf("L.length=%d \n",L.length);
    
    GetElem(L,5,&e);
    printf("第5个元素的值为:%d\n",e);
    for(j=3;j<=4;j++)
    {
        k=LocateElem(L,j);
        if(k)
            printf("第%d个元素的值为%d\n",k,j);
        else
            printf("没有值为%d的元素\n",j);
    }
    
    
    k=ListLength(L);
    for(j=k+1;j>=k;j--)
    {
        i=ListDelete(&L,j,&e);
        if(i==ERROR)
            printf("删除第%d个数据失败\n",j);
        else
            printf("删除第%d个的元素值为:%d\n",j,e);
    }
    printf("依次输出L的元素:");
    ListTraverse(L);
    
    j=5;
    ListDelete(&L,j,&e); /* …æ≥˝µ⁄5∏ˆ ˝æ› */
    printf("删除第%d个的元素值为:%d\n",j,e);
    
    printf("依次输出L的元素:");
    ListTraverse(L);
    
    
    SqList Lb;
    i=InitList(&Lb);
    for(j=6;j<=15;j++)
        i=ListInsert(&Lb,1,j);
    
    unionL(&L,Lb);
    
    printf("依次输出合并了Lb的L的元素:");
    ListTraverse(L); 
    
    return 0;
}

运行结果如下:
初始化L后:L.length=0
在L的表头依次插入1~5后:L.data=5 4 3 2 1 
L.length=5 
L 是否为空:i=0(1:是 0:否)
清空L后:L.length=0
L 是否:i=1(1:是 0:否)
在L的表尾依次插入1~10后:L.data=1 2 3 4 5 6 7 8 9 10 
L.length=10 
在L的表头插入0后:L.data=0 1 2 3 4 5 6 7 8 9 10 
L.length=11 
第5个元素的值为:4
第4个元素的值为3
第5个元素的值为4
删除第12个数据失败
删除第11个的元素值为:10
依次输出L的元素:0 1 2 3 4 5 6 7 8 9 
删除第5个的元素值为:4
依次输出L的元素:0 1 2 3 5 6 7 8 9 
依次输出合并了Lb的L的元素:0 1 2 3 5 6 7 8 9 15 14 13 12 11 10 
Program ended with exit code: 0


ps:读这段代码时候,开始有一点不很清楚地方是L->length和L->data这种表达,后来才明白,这中表述中,L是一个指针变量,指向SqList的指针,而L->length的意思就是该指针L指向的SqList结构中的length。
可以通过下面小程序更清晰了解:
#include <iostream>

struct pero{
    char name[20];
    int age;
    int tall;
};
int main(int argc, const char * argv[]) {
    
    pero wang={
        "weiwei",
        26,
        180
    };
    pero* pst=&wang;
    std::cout<<wang.age<<std::endl;
    pst->age=20;
    std::cout<<wang.age<<std::endl;
    return 0;
}

运行结果:26和20
可见,通过pst->age对pst指针指向的wang中的age元素进行了赋值操作。




  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值