1.线性表的顺序存储结构————顺序表(包含C语言和C++版本的完整程序)

1.顺序表的定义

   将表中元素一个接一个的存入一组连续的存储单元中,这种存储结构是顺序结构,采用顺序存储结构的线性表简称为“ 顺序表”。
   顺序表的存储特点是:只要确定了起始位置,表中任一元素的地址都通过下列公式得到:

Loc(ai)=Loc(a1)+(i1)L,1in L o c ( a i ) = L o c ( a 1 ) + ( i − 1 ) ∗ L , 1 ≤ i ≤ n
其中,L是元素占用存储单元的长度。

2.顺序表的基本操作

(1)初始化:建立一个空的顺序表;
(2)新建:新建一个顺序表;
(3)合并顺序表:将两个顺序表合并,并去掉重复元素;
(4)按元素查找:查找顺序表中是否含有指定元素;
(5)按位置查找:查找指定位置的元素;
(6)求顺序表的长度:计算顺序表的元素个数;
(7)指定位置插入:在指定位置插入元素;
(8)删除元素:删除指定位置的元素;
(9)判空:判断是否是空的顺序表;
(10)清空顺序表;
(11)显示:显示当前顺序表的所有数据。

3.顺序表的编程实现

  • 3.1 C++实现顺序表

(1)顺序表的头文件 sequencelist.h

#ifndef SEQUENCELIST_H
#define SEQUENCELIST_H

#define MAXSIZE 20//最大存储容量
typedef int ElemType;

class SqList
{
public:
    SqList();//
    SqList(ElemType elems[],int n);//有参构造器
    ~SqList();//
    bool CreatList();//新建一个顺序表
    bool UnionList(SqList L1,SqList L2);
    int LocateElem(ElemType e);//按元素查找:成功则返回元素的序号(从1开始),失败则返回0
    int ListLength();//顺序表的长度
    bool GetElem(int i, ElemType& e);//查找第i个位置的元素
    bool ListInsert(int i,ElemType e);//在第i个位置插入元素
    bool ListDelete(int i,ElemType& e);//删除第i个位置的元素
    bool ListEmpty();//判空
    void clearList();//清空顺序表
    void display();//显示当前的顺序表

private:
    ElemType data[MAXSIZE];//下标从0开始,但是对线性表的操作中的下标从1开始:第1个元素其实就是下标为0的元素
    int length;
};

#endif // SEQUENCELIST_H

(2)顺序表的源文件 sequencelist.cpp

#include "sequencelist.h"
#include <iostream>
using namespace std;

SqList::SqList()//初始化
{
    length=0;//
}

SqList::SqList(ElemType elems[],int n)//有参构造器
{
    if(n>MAXSIZE)
    {
        cout<<"传入的顺序表长度超出最大范围,只接收了前"<<MAXSIZE<<"个元素"<<endl;
        length=MAXSIZE;
    }
    else
        length=n;//

    for(int i=0;i<length;i++)
        data[i]=elems[i];
}

SqList::~SqList()
{

}

bool SqList::CreatList()
{

    cout<<"插入多少个元素(0-20)?"<<endl;
    cin>>length;
    if(length<0||length>MAXSIZE)
    {
        length=0;
        return false;
    }
    for(int i=1;i<=length;i++)
    {
//        cout<<"请输入顺序线性表的第"<<i<<"个元素:";
//        cin>>L->data[i-1];
        data[i-1]=i;
    }
    return true;
}

bool SqList::UnionList(SqList L1,SqList L2)
{
    int i,j;
    for(i=0;i<L1.length;i++)
    {
        data[i]=L1.data[i];
    }

    for(j=0;j<L2.length;j++)
        if(L1.LocateElem(L2.data[j])==0)
        {
            if(i>=MAXSIZE)
                return false;
            data[i]=L2.data[j];
            i++;
        }
    length=i;
    return true;
}

int  SqList::LocateElem(ElemType e)//成功则返回元素的序号(从1开始),失败则返回0
{
    for(int i=0;i<length;i++)
        if(data[i]==e)
            return i+1;
    return 0;
}

int  SqList::ListLength()
{
    return length;
}

bool SqList::GetElem(int i, ElemType& e)
{
    if(length==0 || i<1|| i>length)
        return false;
    e=data[i-1];
    return true;
}

bool SqList::ListInsert(int i,ElemType e)
{
    if(length==MAXSIZE || i<1|| i>length+1)//线性表满,或者i的范围不在合理范围内时返回错误
        return false;
    if(i<=length)//不在表尾
    {
        //插入位置的后续元素后移一位
        for(int k=length-1;k>=i-1;k--)
            data[k+1]=data[k];// 倒序挪动位置,避免覆盖问题
    }
    data[i-1]=e;//插入元素
    length++;
    return true;
}

bool SqList::ListDelete(int i,ElemType& e)
{
    if(length==0 || i<1|| i>length)//线性表满,或者i的范围不在合理范围内时返回错误
        return false;
    e=data[i-1];//取出元素
    if(i<=length)//不在表尾
    {
        //插入位置的后续元素前移一位
        for(int k=i-1;k<length-1;k++)
            data[k]=data[k+1];// 倒序挪动位置,避免覆盖问题
    }
    length--;
    return true;
}

bool SqList::ListEmpty()
{
    if (length==0)
        return true;
    return false;
}

void SqList::clearList()
{
    length=0;
}

void SqList::display()
{
    for(int i=0;i<length;i++)
        cout<<data[i]<<"  ";
    cout<<endl;
}

(3)主函数 main.cpp

#include <iostream>
#include "sequencelist.h"
using namespace std;

int main()
{
    SqList list;
    int num;
    ElemType elem;
    bool flag;

    cout<<"            1.顺序表的创建和显示"<<endl;
    if(!list.CreatList())
        cout<<"顺序表创建失败!"<<endl;
    else
        cout<<"顺序表创建成功!    "<<endl;
    //顺序表的显示
    list.display();
    cout<<endl<<endl;

    cout<<"            2.按元素查找"<<endl;
    num=list.LocateElem(3);
    cout<<"3是顺序表的第"<<num<<"个元素"<<endl<<endl<<endl;

    cout<<"            3.按位置查找"<<endl;
    list.GetElem(4,elem);
    cout<<"顺序表的第4个元素是:"<<elem<<endl<<endl<<endl;

    cout<<"            4.顺序表的插入"<<endl;
    if(list.ListInsert(2,10))
        cout<<"插入成功!在第2个位置插入10后:    "<<endl;
    else
        cout<<"插入失败!"<<endl;
    list.display();
    cout<<endl<<endl;

    cout<<"            5.删除元素"<<endl;
    list.ListDelete(5,elem);
    cout<<"删掉第5个元素:"<<elem<<endl;
    cout<<"该表的长度为:"<<list.ListLength()<<endl;
    list.display();
    cout<<endl<<endl;

    cout<<"            6.清空顺序表"<<endl;
    cout<<"清空顺序表前-----";
    if(!list.ListEmpty())
    {
        cout<<"当前顺序表不是空表!"<<endl;
        list.clearList();
        cout<<"清空顺序表后-----";
        if(list.ListEmpty())
            cout<<"当前顺序表是空表!"<<endl;
    }
    cout<<endl<<endl;

    cout<<"            7.合并顺序表"<<endl;
    ElemType elems1[8]={0,1,2,3,4,5,6,7};
    ElemType elems2[9]={5,6,7,8,9,10,11,1,12};

    SqList list1={elems1,8};
    SqList list2={elems2,9};
    SqList list3;
    cout<<"合并前的两个表为:"<<endl;
    list1.display();
    list2.display();
    flag=list3.UnionList(list1,list2);
    if(!flag)
        cout<<"合并后,顺序表的长度超过最大范围"<<endl;
    cout<<"该表的长度为:    "<<list3.ListLength()<<endl;
    list3.display();
    return 0;
}
  • 3.2 C语言实现顺序表


    (1)顺序表的头文件 sequencelist.h
#ifndef SEQUENCELIST_H
#define SEQUENCELIST_H

#define MAXSIZE 20//最大存储容量
typedef int ElemType;
typedef struct
{
    ElemType data[MAXSIZE];//下标从0开始,但是对线性表的操作中的下标从1开始:第1个元素其实就是下标为0的元素
    int length;
}SqList;

typedef enum Bool
{
    FALSE,TRUE//枚举默认值从0开始,依次加1
}Bool;

Bool CreatList(SqList* L);//)新建一个顺序表
Bool UnionList(SqList* L1,SqList* L2,SqList* L);
int LocateElem(SqList L,ElemType e);//成功则返回元素的序号(从1开始),失败则返回0
int ListLength(SqList L);//顺序表的长度
Bool GetElem(SqList L, int i, ElemType* e);//查找第i个位置的元素
Bool ListInsert(SqList* L,int i,ElemType e);//在第i个位置插入元素
Bool ListDelete(SqList* L,int i,ElemType* e);//删除第i个位置的元素
Bool ListEmpty(SqList L);//判空
void clearList(SqList* L);//清空顺序表
void display(SqList L);//显示当前的顺序表
#endif // SEQUENCELIST_H

(2)顺序表的源文件 sequencelist.c

#include "sequencelist.h"
#include <stdio.h>

Bool GetElem(SqList L, int i, ElemType* e)
{
    if(L.length==0 || i<1|| i>L.length)
        return FALSE;
    *e=L.data[i-1];
    return TRUE;
}

Bool ListInsert(SqList* L,int i,ElemType e)
{
    int k;
    if(L->length==MAXSIZE || i<1|| i>L->length+1)//线性表满,或者i的范围不在合理范围内时返回错误
        return FALSE;
    if(i<=L->length)//不在表尾
    {
        //插入位置的后续元素后移一位
        for(k=L->length-1;k>=i-1;k--)
            L->data[k+1]=L->data[k];// 倒序挪动位置,避免覆盖问题
    }
    L->data[i-1]=e;//插入元素
    L->length++;
    return TRUE;
}

Bool ListDelete(SqList* L,int i,ElemType* e)
{
    int k;
    if(L->length==0 || i<1|| i>L->length)//线性表满,或者i的范围不在合理范围内时返回错误
        return FALSE;
    *e=L->data[i-1];//取出元素
    if(i<=L->length)//不在表尾
    {
        //插入位置的后续元素前移一位
        for(k=i-1;k<L->length-1;k++)
            L->data[k]=L->data[k+1];// 倒序挪动位置,避免覆盖问题
    }
    L->length--;
    return TRUE;
}

Bool CreatList(SqList* L)
{
    int i;
    printf("插入多少个元素(0-20)?\n");
    scanf("%d",&(L->length));
    if(L->length<0||L->length>MAXSIZE)
        return FALSE;
    for(i=1;i<=L->length;i++)
    {
//        cout<<"请输入顺序线性表的第"<<i<<"个元素:";
//        cin>>L->data[i-1];
        L->data[i-1]=i;
    }
    return TRUE;
}
Bool ListEmpty(SqList L)
{
    if (L.length==0)
        return TRUE;
    return FALSE;
}

void clearList(SqList* L)
{
    L->length=0;
}
int  LocateElem(SqList L,ElemType e)//成功则返回元素的序号(从1开始),失败则返回0
{
    int i=0;
    for(i=0;i<L.length;i++)
        if(L.data[i]==e)
            return i+1;
    return 0;
}
int  ListLength(SqList L)
{
    return L.length;
}

void display(SqList L)
{
    int i;
    for(i=0;i<L.length;i++)
        printf("%d  ",L.data[i]);
    printf("\n");
}


//不调用底层程序,直接编程实现顺序表合并,这种方法较为复杂
Bool UnionList1(SqList* L1,SqList* L2,SqList* L)
{
    int i,j,k;
    L->length=0;
    for(i=0;i<L1->length;i++)
    {
        L->data[i]=L1->data[i];
    }

    for(j=0;j<L2->length;j++)
    {
        for(k=0;k<L1->length;k++)
        {
           if(L2->data[j]==L1->data[k])
               break;
        }

        if(k==L1->length)
        {
            if(i>=MAXSIZE)
                return FALSE;
            L->data[i]=L2->data[j];
            i++;
        }
    }
    L->length=i;
    return TRUE;
}

//调用底层程序来查找元素,减轻了工作量
Bool UnionList(SqList* L1,SqList* L2,SqList* L)
{
    int i,j;
    L->length=0;
    for(i=0;i<L1->length;i++)
    {
        L->data[i]=L1->data[i];
    }

    for(j=0;j<L2->length;j++)
        if(LocateElem(*L1,L2->data[j])==0)
        {
            if(i>=MAXSIZE)
                return FALSE;
            L->data[i]=L2->data[j];
            i++;
        }

    L->length=i;
    return TRUE;
}

(3)主函数 main.c

#include <stdio.h>
#include "sequencelist.h"

int main()
{
    SqList list;
    int num;
    ElemType elem;
    Bool flag;

    printf("            1.顺序表的创建和显示\n");
    if(!CreatList(&list))
        printf("顺序表创建失败!\n");
    else
        printf("顺序表创建成功!\n    ");
    //顺序表的显示
    display(list);
    printf("\n\n");

    printf("            2.按元素查找\n");
    num=LocateElem(list,3);
    printf("3是顺序表的第%d个元素",num);
    printf("\n\n\n");

    printf("            3.按位置查找\n");
    GetElem(list,4,&elem);
    printf("顺序表的第4个元素是%d",elem);
    printf("\n\n\n");

    printf("            4.顺序表的插入\n");
    ListInsert(&list,2,10);
    printf("在第2个位置插入10后:\n    ");
    display(list);
    printf("\n\n");

    printf("            5.删除元素\n");
    ListDelete(&list,5,&elem);
    printf("删掉第5个元素:%d\n",elem);
    printf("该表的长度为:%d\n    ",ListLength(list));
    display(list);
    printf("\n\n");

    printf("            6.清空顺序表\n");
    printf("清空顺序表前-----");
    if(!ListEmpty(list))
    {
        printf("当前顺序表不是空表!\n");
        clearList(&list);
        printf("清空顺序表后-----");
        if(ListEmpty(list))
            printf("当前顺序表是空表!\n");
    }
    printf("\n\n");

    printf("            7.合并顺序表\n");
    SqList list1={{0,1,2,3,4,5,6,7},8},list2={{5,6,7,8,9,10,11,1,12},9},list3;
    flag=UnionList(&list1,&list2,&list3);
    if(!flag)
        printf("合并后,顺序表的长度超过最大范围");
    printf("该表的长度为:%d\n    ",ListLength(list3));
    display(list3);
    printf("\n\n");
    return 0;
}
  • 3.3 测试结果


    这里写图片描述
评论 1 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:技术工厂 设计师:CSDN官方博客 返回首页

打赏作者

老王回归

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值