第二章 线性表 2.4线性表的顺序表示和实现(2.1——2.4)

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

前面的内容都是铺垫,到2.4是应用。前面就简单提一下。

数据结构中线性结构是1对1的,比较简单。咱们柿子先挑着软的捏。

线性结构的定义:

在这里插入图片描述

例如:
在这里插入图片描述
在这里插入图片描述
特点(其实就是把定义又强调了一遍)
在这里插入图片描述
废话少说,上代码!

#include <iostream>

using namespace std;
//定义存储表示
typedef int ElemType;           //定义int的别名ElemType
typedef int Status;
# define  MAXSIZE   100         // 初始化长度
# define  OK   1
//定义一个SqList结构体
typedef struct
{
    ElemType *elem;             //定义一个指针表示存储空间基址
    int  length;               //当前表长(特指元素个数)
} SqList;

//初始化
Status   InitList_Sq(SqList &L)
{
    //构造一个空的顺序表L。
    L.elem = new ElemType[MAXSIZE];//开辟一个存放整型数字,大小为100的数组空间,并返回首元素的地址
    if  ( ! L.elem )
        cout<<"内存空间分配失败"<<endl;
    L.length = 0;                    // 空表长度为0
    return   OK;
}

//销毁顺序表
void DestroyList(SqList &L)
{
    if (L.elem)
        delete[ ] L.elem;    //释放存储空间
    L.length=0;
    L.elem = NULL;
}


//求顺序表的长度
int GetLength(SqList L)
{
    return L.length;
}

//判断顺序表是否为空
bool IsEmpty(SqList L)
{
    if (L.length==0)
        return true;
    else
        return false;
}
//给顺序表赋值
void fuzhi(SqList &L)
{
    int n,m;
    cout<<"请输入赋值的数据元素个数"<<endl;
    cin>>n;
    for(int i=0; i<n; i++)
    {
        cout<<"请输入第"<<i+1<<"的数据元素的值"<<endl;
        cin>>m;
        L.elem[i]=m;
        L.length++;
    }
    cout<<"赋值成功"<<endl;
}

//清空顺序表
void ClearList(SqList &L)
{
    L.length=0;
    cout<<"顺序表清空成功"<<endl;
}

//获取顺序表指定位置元素
void Getelem(SqList L,int i)
{
    ElemType e;
    if(i<1||i>L.length)
    {
        cout<<"输入的查找参数错误"<<endl;
    }
    else
    {
        e=L.elem[i-1];
        cout<<"查找成功"<<endl;
        cout<<"顺序表中第"<<i<<"个数据元素是"<<e<<endl;
    }
}

//获取顺序表指定位置元素的后继
Status Next_elem(SqList L,int i)
{
    ElemType e;
    if(i<1||i>L.length)
    {
        cout<<"输入的查找参数错误"<<endl;
        return -1;
    }
    if (i==L.length)
    {
        cout<<"最后一个元素没有后继"<<endl;
        return -1;
    }

    e=L.elem[i];
    cout<<"查找成功"<<endl;
    cout<<"顺序表中第"<<i<<"个数据元素的后继是"<<e<<endl;
    return OK;

}

//获取顺序表指定位置元素的前驱
Status pre_elem(SqList L,int i)
{
    ElemType e;
    if(i<1||i>L.length)
    {
        cout<<"输入的查找参数错误"<<endl;
        return -1;
    }
    if (i==1)
    {
        cout<<"第一个元素没有前驱"<<endl;
        return -1;
    }

    e=L.elem[i-2];
    cout<<"查找成功"<<endl;
    cout<<"顺序表中第"<<i<<"个数据元素的前驱是"<<e<<endl;
    return OK;

}


//显示顺序表
void display(SqList L)
{
    for(int i=0; i<L.length; i++)
    {
        cout<<"第"<<i+1<<"的数据元素的值:";
        cout<<L.elem[i]<<endl;
    }
    cout<<"顺序表输出完成"<<endl;
}

//在顺序表指定位置插入元素
Status  ListInsert(SqList &L,int i,ElemType e)
{
    int j=0;
    if(i<1||i>L.length)
    {
        cout<<"输入的查找参数错误"<<endl;
        return -1;
    }
    if(L.length==MAXSIZE)
    {
        cout<<"当前储存空间已满,无法插入"<<endl;
        return -1;
    }

    for(j=L.length-1; j>=i-1; j--)
    {
        L.elem[j+1]=L.elem[j];
    }
    L.elem[i-1]=e;
    ++L.length;
    cout<<"插入顺序表中第"<<i<<"个数据元素成功"<<endl;
    return OK;


}

//删除顺序表指定位置元素
void ListDelete(SqList &L,int i)
{
    int j=0;
    if(i<1||i>L.length)
    {
        cout<<"输入的查找参数错误"<<endl;
    }
    else
    {
        for(j=i; j<=L.length-1; j++)
        {
            L.elem[j-1]=L.elem[j];
        }
        --L.length;
        cout<<"删除顺序表中第"<<i<<"个数据元素成功"<<endl;
    }
}

//根据顺序表中的值,查找其位置
void Locateelem(SqList L,ElemType e)
{
    int i=0;
    int flag=0;
    for(i=0; i<L.length; i++)
    {
        if(L.elem[i]==e)
        {
            cout<<"查找成功"<<endl;
            cout<<e<<"位于顺序表中第"<<i+1<<"个数据元素"<<endl;
            flag=1;
        }
    }
    if(flag==0)
        cout<<"查找失败"<<endl;
}
void show_help()
{
    cout<<"******* Data Structure ******"<<endl;
    cout<<"1----清空顺序表"<<endl;
    cout<<"2----判断顺序表是否为空"<<endl;
    cout<<"3----求顺序表长度"<<endl;
    cout<<"4----获取顺序表指定位置元素"<<endl;
    cout<<"5----求前驱"<<endl;
    cout<<"6----求后继"<<endl;
    cout<<"7----在顺序表指定位置插入元素"<<endl;
    cout<<"8----删除顺序表指定位置元素"<<endl;
    cout<<"9----显示顺序表"<<endl;
    cout<<"10----给顺序表赋值"<<endl;
    cout<<"11----根据数据元素查询在顺序表中位置"<<endl;
    cout<<"     退出,输入0"<<endl;

}
int main()
{
    int operate_code;
    show_help();
    //定义顺序表变量,如SqList L;
    SqList L;
    //调用初始化顺序表函数,如Init_List(L);
    InitList_Sq(L);
    while(1)
    {
        cout<<"";
        cin>>operate_code;
        if(operate_code==1)
        {
            ClearList(L);

        }
        else if (operate_code==2)
        {
            if(IsEmpty(L))
                cout<<"顺序表为空表"<<endl;
            else
                cout<<"顺序表非空表"<<endl;
        }
        else if (operate_code==3)
        {
            cout<< "顺序表的长度是:"<< GetLength(L)<<endl;
        }
        else if (operate_code==4)
        {
            int c;
            cout<< "请输入你要查找的数据元素的位置"<<endl;
            cin>>c;
            Getelem(L,c);
        }
        else if (operate_code==5)
        {
            int c;
            cout<< "请输入你要查找的数据元素的位置"<<endl;
            cin>>c;
            pre_elem(L,c);
        }
        else if (operate_code==6)
        {
            int c;
            cout<< "请输入你要查找的数据元素的位置"<<endl;
            cin>>c;
            Next_elem(L,c);
        }
        else if (operate_code==7)
        {
            int a;
            ElemType e;
            cout<<"请输入你要插入的数据元素位置"<<endl;
            cin>>a;
            cout<<"请输入你要插入的数据元素"<<endl;
            cin>>e;
            ListInsert(L,a,e);
        }
        else if (operate_code==8)
        {
            int b;
            cout<<"请输入你要删除的数据元素位置"<<endl;
            cin>>b;
            ListDelete(L,b);
        }
        else if (operate_code==9)
        {
            display(L);
        }
        else if (operate_code==10)
        {
            fuzhi(L);
        }
        else if (operate_code==11)
        {
            ElemType f;
            cout<<"请输入你要查找的数据元素"<<endl;
            cin>>f;
            Locateelem(L,f);
        }
        else if (operate_code==0)
        {
            break;
        }
        else
        {
            cout<<"\n操作码错误!!!"<<endl;
            show_help();
        }
    }
    //调用销毁顺序表函数,如Destroy_List(L);
    DestroyList(L);
    return 0;
}

剖析:

<1>

typedef int ElemType;           //定义int的别名ElemType
typedef int Status;
  • 这个是用来定义int的别名Elemtype和Status。人们喜欢这样做是因为使程序更容易明白,因为用int的时候不知道他是干嘛的

<2>

typedef struct
{
    ElemType *elem;             //定义一个指针表示存储空间基址
    int  length;               //当前表长(特指元素个数)
} SqList;
  • 定义一个叫做SqList的结构体。
  • 通过定义顺序表存储空间基址和其长度来把顺序表确定下来。

<3>

//初始化
Status   InitList_Sq(SqList &L)
{
    //构造一个空的顺序表L。
    L.elem = new ElemType[MAXSIZE]//开辟一个存放整型数字,大小为100的数组空间,并返回首元素的地址
    if  ( ! L.elem )
        cout<<"内存空间分配失败"<<endl;
    L.length = 0;                    // 空表长度为0
    return   OK;
}
  • Status其实就是int。所以这个函数的类型是int型。
  • 因为初始化要对顺序表进行改变,所以这里用引用(&L)
  • 之前定义的是*elem这个指针,现在我们要往里面传地址。而new ElemType[MAXSIZE]的作用就是:开辟一个存放整型数字,大小为100的数组空间,并返回首元素的地址
  • 之后让顺序表长度为0,完成初始化。

<4>

//销毁顺序表
void DestroyList(SqList &L)
{
    if (L.elem)
        delete[ ] L.elem;    //释放存储空间
    L.length=0;
    L.elem = NULL;
}
  • 最开始初始化,最后结束要销毁顺序表。使用new [ ]申请的内存释放时要用delete [ ]才行。
  • 长度变0,数据清空。欧了。

<5>

扫描二维码关注公众号,回复: 11153108 查看本文章
//求顺序表的长度
int GetLength(SqList L)
{
    return L.length;
}
  • 用int类型函数直接return 长度即可。
  • 这里因为不需要对顺序表进行修改所以直接传入L即可,不用引用。

<6>

bool IsEmpty(SqList L)
{
    if (L.length==0)
        return true;
    else
        return false;
}
  • 因为return值是true or false ,所以函数类型为bool型。

<7>

//给顺序表赋值
void fuzhi(SqList &L)
{
    int n,m;
    cout<<"请输入赋值的数据元素个数"<<endl;
    cin>>n;
    for(int i=0; i<n; i++)
    {
        cout<<"请输入第"<<i+1<<"的数据元素的值"<<endl;
        cin>>m;
        L.elem[i]=m;
        L.length++;
    }
    cout<<"赋值成功"<<endl;
}
  • 修改顺序表用引用,位置从0开始赋值。

<8>

//清空顺序表
void ClearList(SqList &L)
{
    L.length=0;
    cout<<"顺序表清空成功"<<endl;
}
  • 直接让长度为0即可,不用像销毁那样用delete [ ].

<9>

//获取顺序表指定位置元素
void Getelem(SqList L,int i)
{
    ElemType e;
    if(i<1||i>L.length)
    {
        cout<<"输入的查找参数错误"<<endl;
    }
    else
    {
        e=L.elem[i-1];
        cout<<"查找成功"<<endl;
        cout<<"顺序表中第"<<i<<"个数据元素是"<<e<<endl;
    }
}
  • 要先判断要查询的位置是不是在顺序表里面
  • 因为存储是从0这个位置开始的,所以要返回第 i 1 i - 1 个的值

<10>

//获取顺序表指定位置元素的后继
Status Next_elem(SqList L,int i)
{
    ElemType e;
    if(i<1||i>L.length)
    {
        cout<<"输入的查找参数错误"<<endl;
        return -1;
    }
    if (i==L.length)
    {
        cout<<"最后一个元素没有后继"<<endl;
        return -1;
    }

    e=L.elem[i];
    cout<<"查找成功"<<endl;
    cout<<"顺序表中第"<<i<<"个数据元素的后继是"<<e<<endl;
    return OK;

}

//获取顺序表指定位置元素的前驱
Status pre_elem(SqList L,int i)
{
    ElemType e;
    if(i<1||i>L.length)
    {
        cout<<"输入的查找参数错误"<<endl;
        return -1;
    }
    if (i==1)
    {
        cout<<"第一个元素没有前驱"<<endl;
        return -1;
    }

    e=L.elem[i-2];
    cout<<"查找成功"<<endl;
    cout<<"顺序表中第"<<i<<"个数据元素的前驱是"<<e<<endl;
    return OK;

}
  • 求前驱后继挺像的,搞清楚位置就可了。
  • if语句中记得写return -1.要不后面的语句还是会执行的。
  • 因为有返回值所以函数类型不可为void。用int型即Status

<11>

//显示顺序表
void display(SqList L)
{
    for(int i=0; i<L.length; i++)
    {
        cout<<"第"<<i+1<<"的数据元素的值:";
        cout<<L.elem[i]<<endl;
    }
    cout<<"顺序表输出完成"<<endl;
}
  • 用个for循环去输出即可。

<12>

//在顺序表指定位置插入元素
Status  ListInsert(SqList &L,int i,ElemType e)
{
    int j=0;
    if(i<1||i>L.length)
    {
        cout<<"输入的查找参数错误"<<endl;
        return -1;
    }
    if(L.length==MAXSIZE)
    {
        cout<<"当前储存空间已满,无法插入"<<endl;
        return -1;
    }

    for(j=L.length-1; j>=i-1; j--)
    {
        L.elem[j+1]=L.elem[j];
    }
    L.elem[i-1]=e;
    ++L.length;
    cout<<"插入顺序表中第"<<i<<"个数据元素成功"<<endl;
    return OK;


}
  • 插在表外面不可,插都满了再查不可。
  • 如果直接从前面插队还得定义一个Temp来防止覆盖。干脆用个for循环让所有元素先往后移动一个。L.length-1是最后一个元素的地址,变成L.length,以此类推。
  • 插入后别忘了让顺序表的长度加1。

<13>

//删除顺序表指定位置元素
void ListDelete(SqList &L,int i)
{
    int j=0;
    if(i<1||i>L.length)
    {
        cout<<"输入的查找参数错误"<<endl;
    }
    else
    {
        for(j=i; j<=L.length-1; j++)
        {
            L.elem[j-1]=L.elem[j];
        }
        --L.length;
        cout<<"删除顺序表中第"<<i<<"个数据元素成功"<<endl;
    }

}
  • 这里只有查询位置不在顺序表这一个可能错误。所有用if……else就可以应付过来。不用return -1来中途结束这个函数了。
  • 删除的话直接让要删的那个位置后面的元素覆盖掉他就ok了。

<14>

void Locateelem(SqList L,ElemType e)
{
    int i=0;
    int flag=0;
    for(i=0; i<L.length; i++)
    {
        if(L.elem[i]==e)
        {
            cout<<"查找成功"<<endl;
            cout<<e<<"位于顺序表中第"<<i+1<<"个数据元素"<<endl;
            flag=1;
        }
    }
    if(flag==0)
        cout<<"查找失败"<<endl;
}
  • 用for循环内置if判断就ok了。
  • flag是用来标志是否查到的小旗子。

<15>

    //定义顺序表变量,如SqList L;
    SqList L;
  • 主函数就比较常规了,就这个说下。之前我们定义了一个结构体的蓝图,现在L是那个结构体的实例。

性能分析:

在这里插入图片描述
同样,查找也是平均下来要过 n 2 \frac{n}{2} 个元素。

so ~

在这里插入图片描述

原创文章 85 获赞 46 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Deam_swan_goose/article/details/104496764