C++数据结构之线性表——顺序表

一、线性表

概念

1.线性表是最简单的一类线性数据结构

2.线性表是由n个数据元素组成的有限序列,相邻数据元素之间存在着序偶关系,可以写成:

(a1, a2,…ai-1, ai, ai+1,…an-1, an)

其中,ai是表中元素,i表示元素ai的位置,n是表的长度

特性

线性表中的元素具有相同的特性,属于同一数据对象,如:
1.26个字母的字母表: (A,B,C,D,…,Z)
2.近期每天的平均温度:(30℃, 28℃, 29℃,…)

ADT定义

ADT List

{
    数据对象:数据元素同属一个集合
    数据关系:序偶关系
    基本操作:
        Init创建、Destroy销毁、
        Clear清空、Empty是否为空、
        Length取表长度、Get取表元素、Locate查找元素
        Prior取元素前驱、Next取元素后继
        Insert插入元素、Delete删除元素
        Traverse遍历表
}

 二、顺序表

概念

i.顺序表的构成

1.顺序表是线性表的顺序存储表示

2.顺序表采用一组地址连续的存储单元依次存储线性表的数据元素

 ii.顺序表的元素位置

顺序表数据元素的位置:
        location(a_i) = location( a_(i-1) ) + l
        location(a_i) = location(a_1)+(i-1)*l    ( l表示元素占用的内存单元数 )

 举例:

一个线性表第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是( )
(A)110 (B)108(C)100 (D)120

根据上面的元素位置公式我们可以知道第五个元素的位置location(a_5)=100+(5-1)*2=108,故选B

实现

顺序表类

#define initsize 100//初始化表的存储容量
#define sizeincrease 10//单次增加容量的大小
class sqlist
{
    public:
    int length;//顺序表的当前长度
    int listsize;//为顺序表分配的储存空间大小
    int *element;//指向顺序表的第一个元素(即存储空间基址)
    int initelement[initsize];//顺序用于表初始化后的各个存储单元的初始值
    void init();//创建顺序表
    void destroy();//销毁顺序表
    void clear();//清空顺序表
    bool empty();//检测是否为空
    int getlength();//获取顺序表的长度
    int get(int index);//获取下标为index的元素
    int locate(int ele);//查找元素ele所在位置的下标
    int prior(int index);//取下标为index的元素的前驱元素
    int next(int index);//取下标为index的元素的后继元素
    void insert(int ele,int index);//在下标为index的元素位置插入元素ele,原位置的元素依次后移一位
    void remove(int index);//删除下标为index的元素,下标index后的元素依次向前移动一位
    void traverse();//遍历表
    void print();//打印表
    void push(int ele);//从表尾插入元素
    void batchpush();//批量压入数据
};

初始化顺序表

void sqlist::init()
{
    element=(int*)malloc(initsize*sizeof(int));//分配内存大小为initsize的空间
    for (int i = 0; i < initsize; i++)//将各存储单元的初始值赋值给initelement[]
    {
        initelement[i]=element[i];  
    }
    
    if (!element)
    {
        cout<<"内存空间分配失败!"<<endl;
    }
    else
    {
        length=0;//初始化后顺序表是空的,故当前长度为0
        listsize=initsize;//初始化的存储容量就等于initsize
        cout<<"存储空间分配成功!"<<endl;
    }
}

销毁顺序表

void sqlist::destroy()
{
    if (!element)//如果分配内存空间失败则无需销毁
    {
        cout<<"无需销毁顺序表!"<<endl;   
    }
    else//分配成功就销毁顺序表
    {
        delete element;
        cout<<"顺序表销毁成功!"<<endl;
    }
}

清空顺序表

void sqlist::clear()
{
    for (int i = 0; i < length; i++)//将各个元素值赋值为初始化时的值即为清空
    {
        element[i]=initelement[i];
    }
    length=0;//此时顺序表的长度为0     
}

判断顺序表是否为空

bool sqlist::empty()
{
    return length==0?true:false;
}

得到顺序表长度

int sqlist::getlength()
{
    return length;
}

获取下标为index的元素

int sqlist::get(int index)
{
    return element[index];
}

定位到第一个数据为ele的元素下标

int sqlist::locate(int ele)
{
    int i;
    for (; i < length; i++)
    {
        if (ele==element[i])
        {
            break;  
        }  
    }
    return i;
}

取下标为index的元素的前驱元素

int sqlist::prior(int index) 
{
    if (index==0)
    {
        cout<<"第一个元素没有前驱元素!"<<endl;
        return 0;
    }
    else
    {
        return element[index-1];
    }    
}

取下标为index的元素的后继元素

int sqlist::next(int index)
{
    if (index==length-1)
    {
        cout<<"最后一个元素没有后继元素!"<<endl;
        return length-1;
    }
    else
    {
        return element[index+1];
    }  
}

在下标为Index的位置插入元素ele

注意,在插入的时候我们要注意的是是否超出了顺序表的容量,如果超过容量就需要进行扩容,因此我们在头文件需要导入<malloc.h>,并使用里面的realloc函数来进行扩容

void sqlist::insert(int ele,int index)
{
    if (length==listsize)
    {
        cout<<"顺序表空间已满,自动扩容!"<<endl;
        listsize+=sizeincrease;
        element=(int*)realloc(element,sizeof(listsize));
    }
    for (int i = length; i > index; i--)
    {
        element[i]=element[i-1];    
    }
    element[index]=ele;
    length+=1;  
}

删除下标为index的元素

void sqlist::remove(int index)
{
    if (length==0)
    {
        cout<<"顺序表为空无法移除元素!"<<endl;
    }
    else
    {
    for (int i = index; i < length-index; i++)
    {
        element[i]=element[i+1];    
    }
    element[length-1]=initelement[length-1];//将顺序表最后一个元素赋值为该位置初始值
    length-=1;   
    }
}

遍历顺序表

void sqlist::traverse()
{
    if (length==0)
    {
        cout<<"顺序表为空无法遍历!"<<endl;
    }
    else
    {
        for (int i = 0; i < length; i++)
        {
            //遍历要做的操作
        }
    }
}

打印顺序表

void sqlist::print()
{
    cout<<"============sqlist==========="<<endl;
    for (int i = 0; i < length; i++)
    {
        cout<<"element["<<i<<"]:"<<element[i]<<endl;
    }
    cout<<"============================="<<endl;
}

从表尾插入元素ele

void sqlist::push(int ele)
{
    if (length==0)
    {
        element[0]=ele;
    }
    else
    {
        element[length]=ele;
    }
    length++;
}

批量压入数据

void sqlist::batchpush()
{
    int symbol=0;
    int tempele;
    while (symbol==0)
    {
        cin>>tempele;
        if (tempele!=-1)
        {
            push(tempele);
        }
        else
        {
            symbol=1;
        }
    }
    cout<<"批量数据压入完毕!"<<endl;
}

全部代码

#include<stdio.h>
#include<iostream>
#include<malloc.h>
#define initsize 10
#define sizeincrease 10
using namespace std;

class sqlist
{
    public:
    int length;//顺序表的当前长度
    int listsize;//为顺序表分配的储存空间大小
    int *element;//指向顺序表的第一个元素(即存储空间基址)
    int initelement[initsize];//顺序用于表初始化后的各个存储单元的初始值
    void init();//创建顺序表
    void destroy();//销毁顺序表
    void clear();//清空顺序表
    bool empty();//检测是否为空
    int getlength();//获取顺序表的长度
    int get(int index);//获取下标为index的元素
    int locate(int ele);//查找元素ele所在位置的下标
    int prior(int index);//取下标为index的元素的前驱元素
    int next(int index);//取下标为index的元素的后继元素
    void insert(int ele,int index);//在下标为index的元素位置插入元素ele,原位置的元素依次后移一位
    void remove(int index);//删除下标为index的元素,下标index后的元素依次向前移动一位
    void traverse();//遍历表
    void print();//打印表
    void push(int ele);//从表尾插入元素
};

void sqlist::init()
{
    element=(int*)malloc(initsize*sizeof(int));//分配内存大小为initsize的空间
    for (int i = 0; i < initsize; i++)//将各存储单元的初始值赋值给initelement[]
    {
        initelement[i]=element[i];  
    }
    
    if (!element)
    {
        cout<<"内存空间分配失败!"<<endl;
    }
    else
    {
        length=0;//初始化后顺序表是空的,故当前长度为0
        listsize=initsize;//初始化的存储容量就等于initsize
        cout<<"存储空间分配成功!"<<endl;
    }
}

void sqlist::destroy()
{
    if (!element)//如果分配内存空间失败则无需销毁
    {
        cout<<"无需销毁顺序表!"<<endl;   
    }
    else//分配成功就销毁顺序表
    {
        delete element;
        cout<<"顺序表销毁成功!"<<endl;
    }
}

void sqlist::clear()
{
    for (int i = 0; i < length; i++)//将各个元素值赋值为初始化时的值即为清空
    {
        element[i]=initelement[i];
    }
    length=0;//此时顺序表的长度为0     
}

bool sqlist::empty()
{
    return length==0?true:false;
}

int sqlist::getlength()
{
    return length;
}

int sqlist::get(int index)
{
    return element[index];
}

int sqlist::locate(int ele)
{
    int i;
    for (; i < length; i++)
    {
        if (ele==element[i])
        {
            break;  
        }  
    }
    return i;
}

int sqlist::prior(int index) 
{
    if (index==0)
    {
        cout<<"第一个元素没有前驱元素!"<<endl;
        return 0;
    }
    else
    {
        return element[index-1];
    }    
}

int sqlist::next(int index)
{
    if (index==length-1)
    {
        cout<<"最后一个元素没有后继元素!"<<endl;
        return length-1;
    }
    else
    {
        return element[index+1];
    }  
}

void sqlist::insert(int ele,int index)
{
    if (length==listsize)
    {
        cout<<"顺序表空间已满,自动扩容!"<<endl;
        listsize+=sizeincrease;
        element=(int*)realloc(element,sizeof(listsize));
    }
    for (int i = length; i > index; i--)
    {
        element[i]=element[i-1];    
    }
    element[index]=ele;
    length+=1;  
}

void sqlist::remove(int index)
{
    if (length==0)
    {
        cout<<"顺序表为空无法移除元素!"<<endl;
    }
    else
    {
    for (int i = index; i < length-index; i++)
    {
        element[i]=element[i+1];    
    }
    element[length-1]=initelement[length-1];//将顺序表最后一个元素赋值为该位置初始值
    length-=1;   
    }
}

void sqlist::traverse()
{
    if (length==0)
    {
        cout<<"顺序表为空无法遍历!"<<endl;
    }
    else
    {
        for (int i = 0; i < length; i++)
        {
            //遍历要做的操作
        }
    }
}

void sqlist::print()
{
    cout<<"============sqlist==========="<<endl;
    for (int i = 0; i < length; i++)
    {
        cout<<"element["<<i<<"]:"<<element[i]<<endl;
    }
    cout<<"============================="<<endl;
}

void sqlist::push(int ele)
{
    if (length==0)
    {
        element[0]=ele;
    }
    else
    {
        element[length]=ele;
    }
    length++;
}

void sqlist::batchpush()
{
    int symbol=0;
    int tempele;
    while (symbol==0)
    {
        cin>>tempele;
        if (tempele!=-1)
        {
            push(tempele);
        }
        else
        {
            symbol=1;
        }
    }
    cout<<"批量数据压入完毕!"<<endl;
}

int main()
{
    sqlist sl;
    sl.init();
    sl.destroy();
    return 0;
}

三、总结

本文先对线性表进行了介绍,并且对本文的关键顺序表进行了介绍以及实现,在后面的文章还会对更多的线性表进行介绍和实现,如果喜欢本文的话麻烦动动你的小手点点赞哈!

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
使用c++实现的顺序表:多文件编程,层次清晰,函数有注释 SeqList();//构造函数,存储的元素个数设为0 bool setLength(size_t length);//设置已经存储的元素个数 bool addElement(ElemType element);//把某个元素添加到顺序表末尾 bool addElement(ElemType element , size_t n);//插入一个元素,使其成为第n个元素,其余元素后移 bool delElement();//删除所有的元素 bool delElement(size_t n);//删除第n个元素 bool delElement(string elementDetailType,string elementDetail);//通过某个元素细节找到元素,把这个元素删除 bool replaceElement(ElemType element , size_t n);//使用一个元素,替换掉第n个元素 bool swapElement(size_t n1 , size_t n2);//把第n1个元素和第n2个元素交换 ElemType* getElement();//得到数组头的指针 ElemType* getElement(size_t n);//得到第n个元素的指针 size_t getLength();//得到存储的元素个数 size_t getMaxSize();//得到顺序表容量 bool showElementDetail();//输出所有的元素细节 bool showElementDetail(size_t n);//输出第n个元素的细节 bool showElementDetail(string elementDetailType,string elementDetail);//通过某个元素细节找到元素,输出元素所有细节 size_t findElement(string elementDetailType,string elementDetail);//通过某个元素细节找到元素位置 static int inputAInt(int min = 0,int max = 9,int defaultValue = -1);//从键盘读取,限制为一个min到max间的整数,非法情况返回defaultValue void startControlLoop();//打开控制界面 ~SeqList();//析构函数
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

臭刘皮

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值