数据结构(04)— 线性顺序表实战

1. 设计思路

本实战的实质是完成对学生成绩信息的建立、查找、插入、修改、删除等功能,可以首先定义项目的数据结构,然后将每个功能写成一个函数来完成对数据的操作,最后完成主函数以验证各个函数功能并得出运行结果。

2. 数据结构

本项目的数据是一组学生的成绩信息,每条学生的成绩信息由学号、姓名和成绩组成,这组学生的成绩信息具有相同特性,属于同一数据对象,相邻数据元素之间存在序偶关系。由此可以看出,这些数据具有线性表中数据元素的性质,所以该系统的数据采用线性表来存储。

顺序表是线性表的顺序存储结构,是指用一组连续的内存单元依次存放线性表的数据元素。在顺序存储结构下,逻辑关系相邻的两个元素在物理位置上也相邻,这是顺序表的特点。本项目可以采用顺序表的线性表顺序存储结构。

若一个数据元素仅占一个存储单元,则其存储方式参见下图。
线性表存储结构

从图中可见,第 i个数据元素的地址为
Loc(ai)=loc(a1)+(i-1)

假设线性表中每个元素占用 k个存储单元,那么在顺序表中,线性表的第 i个元素的存储位置与第 1 个元素的存储位置的关系是
Loc(ai)=loc(a1)+(i-1)*k

这里 Loc(ai)是第 i个元素的存储位置,loc(a1)是第 1 个元素的存储位置,也称为线性表的基址。显然,顺序表便于进行随机访问,故线性表的顺序存储结构是一种随机存储结构。

顺序表适宜于做查找这样的静态操作;顺序存储的优点是存储密度大,存储空间利用率高。缺点是插入或删除元素时不方便。

用结构体类型定义每个学生数据,故该数组中的每个数据的结构可描述为:

typedef struct StudentTag
{
    std::string id;
    std::string name;
    int age;
    float score;
}Student;

3. 程序清单

project.h文件:

#include <iostream>
#include <string>

typedef struct StudentTag
{
    std::string id;
    std::string name;
    int age;
    float score;
    // 结构体初始化
    StudentTag(std::string i="", std::string n="", int a=0, float s=0.0) 
    {
        id = i;
        name = n;
        age = a;
        score = s;
    }
}Student;

class LinearList
{
public:
    LinearList(int size);
    ~LinearList();
    void init_list();
    void clear_list();
    bool is_empty();
    bool is_full();
    int print_list();
    int get_list_length();
    int get_element(int i, Student &data);
    int insert_element(int i, Student data);
    int delete_element(int i, Student &data);
    int update_element(int i, Student data);
    

private:
    Student *stu;
    int length;
    int cap;
};

project.cpp

#include "project.h"

LinearList::LinearList(int size)
{
    stu = new Student[size];
    if(stu == NULL)
    {
        std::cout << " new error" << std::endl;
    }
    length = 0;
    cap = size;
    std::cout << "constructor done" << std::endl;
}

LinearList::~LinearList()
{
    if(stu != NULL)
    {
        delete[] stu;
        stu = NULL;
        length = 0;
        cap = 0;
    }
    std::cout << "destructor done" << std::endl;
}

void LinearList::init_list()
{
    std::cout << "init_list start" << std::endl;
    stu->id = "00001";
    stu->name = "Tom";
    stu->age = 18;
    stu->score = 99.5;

    (stu+1)->id = "00002";
    (stu+1)->name = "Jack";
    (stu+1)->age = 19;
    (stu+1)->score = 98;

    length += 2;
    std::cout << "init_list done" << std::endl;
}

void LinearList::clear_list()
{
    std::cout << "clear_list start" << std::endl;
    for(int i=0; i<length; ++i)
    {
        (stu+i)->id = "";
        (stu+i)->name = "";
        (stu+i)->age = 0;
        (stu+i)->score = 0;

    }
    length = 0;
    cap = 0;
    std::cout << "clear_list done" << std::endl;
}

bool LinearList::is_empty()
{
    return length == 0 ? true : false;
}

bool LinearList::is_full()
{
    return length == cap && length != 0 ? true : false;
}


int LinearList::print_list()
{
    for(int i=0; i<length; ++i)
    {
        std::cout   << "id:" << (stu+i)->id << " "
                    << "name:" << (stu+i)->name << " "
                    << "age:" << (stu+i)->age << " "
                    << "score:" << (stu+i)->score << " "
                    << std::endl;
    }
    return 0;
}

int LinearList::get_list_length()
{
    return length;
}

int LinearList::get_element(int i, Student &data)
{
    if(i < 1 || i > length)
    {
        std::cout << "i is not in (1, " << length << ")" << std::endl;
        return -1;
    }
    data = *(stu + i - 1);
    return 0;
}

int LinearList::insert_element(int i, Student data)
{
    if(i < 1 || i > cap)
    {
        std::cout << "i is not in (1, " << cap << ")" << std::endl;
        return -1;
    }

    // 要插入的元素在原始线性表最后一个元素之后
    if(i >= length)
    {
        *(stu + length) = data;   
    }
    else // 要插入的元素在原始线性表第一个元素和最后一个元素之间
    {
        for(int j=length; j>=i; --j)
        {
            *(stu + j + 1) = *(stu + j);
        }
        *(stu + i) = data;
    }
    length += 1;
    return 0;
}


int LinearList::delete_element(int i, Student &data)
{
    if(is_empty() || (i < 1 || i > length))
    {
        return -1;
    }

    data = *(stu + i - 1);

    for(int j=i; j<length; ++j)
    {
        *(stu + j - 1 ) = *(stu + j);
    }
    length -= 1;
    return 0;
}

int LinearList::update_element(int i, Student data)
{
    if(i < 1 || i >= length)
    {
        std::cout << "i is not in (1, " << length << ")" << std::endl;
        return -1;
    }

    *(stu + i - 1) = data;
    return 0;
}

main.cpp

#include "project.cpp"

int main()
{
    LinearList L(10);
    L.init_list();
    L.print_list();
    // L.clear_list();
    // L.print_list();
    bool is_empty = L.is_empty();
    std::cout << "is_empty: " << is_empty << std::endl; 
    bool is_full = L.is_full();
    std::cout << "is_full: " << is_full << std::endl;    
    std::cout << "length: " << L.get_list_length() << std::endl;  

    Student s;
    L.get_element(2, s);
    std::cout << "第 2 个元素为 "  << "id:" << s.id << " "
                    << "name:" << s.name << " "
                    << "age:" << s.age << " "
                    << "score:" << s.score << " "
                    << std::endl;
    
    Student si("00003", "wohu", 18, 97);
    L.insert_element(2, si);
    std::cout << "插入元素之后的结果" << std::endl;
    L.print_list();
    Student sd;
    L.delete_element(1, sd);
    std::cout << "要删除的元素为 "  << "id:" << sd.id << " "
                    << "name:" << sd.name << " "
                    << "age:" << sd.age << " "
                    << "score:" << sd.score << " "
                    << std::endl;
    std::cout << "删除元素之后的结果" << std::endl;
    
    L.print_list();
    Student su("00004", "kuku", 20, 94);
    std::cout << "要更改的元素为 "  << "id:" << su.id << " "
                    << "name:" << su.name << " "
                    << "age:" << su.age << " "
                    << "score:" << su.score << " "
                    << std::endl;
    L.update_element(1, su);
    std::cout << "更新元素之后的结果" << std::endl;
    L.print_list();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值