纵横数据结构:数组描述的线性之旅

本文详细介绍了C++中的数据对象和数据结构,特别是线性表的抽象数据类型linearList和抽象类实现,展示了数组描述(包括固定和变长数组),vector容器,自定义迭代器,以及如何在数组中实现多重表。还涉及了性能测量的方法,如使用chrono库测量代码执行时间。
摘要由CSDN通过智能技术生成

1 数据对象和数据结构

数据对象和数据结构是在算法和程序设计中非常重要的概念。数据对象是我们希望操作和处理的实体,而数据结构则是数据对象之间的关系和组织方式。

2 线性表数据结构

线性表是一种常见的数据结构,它是n个具有相同数据类型的数据元素的有限序列。

2.1 抽象数据类型linearList

//抽象数据类型linearList
template <class T>
class linearList
{
public:
    virtual ~linearList() {}
    virtual bool empty() const = 0;                 // 判断线性表是否为空
    virtual int size() const = 0;                   // 返回线性表的大小
    virtual T& get(int index) const = 0;            // 返回线性表指定位置的元素
    virtual int indexOf(const T& element) const = 0;// 返回线性表指定元素的索引
    virtual void insert(int index, const T& element) = 0; // 在指定位置插入元素
    virtual void remove(int index) = 0;             // 删除指定位置的元素
    virtual void output() const = 0;                // 输出线性表中的所有元素
};

2.2 抽象类linearList

抽象类linearList是线性表数据结构的一个抽象表示,它定义了一系列对线性表进行操作的公共接口和方法。

// 抽象类linearList
template <class T>
class linearList
{
public:
    virtual ~linearList() {}                                // 虚析构函数
    virtual bool empty() const = 0;                         // 判断线性表是否为空
    virtual int size() const = 0;                           // 返回线性表的大小
    virtual T& get(int index) const = 0;                    // 返回线性表指定位置的元素
    virtual int indexOf(const T& element) const = 0;        // 返回线性表指定元素的索引
    virtual void insert(int index, const T& element) = 0;    // 在指定位置插入元素
    virtual void remove(int index) = 0;                     // 删除指定位置的元素
    virtual void output() const = 0;                        // 输出线性表中的所有元素
};

当然,我将为您提供一个完整的C++数据结构学习笔记,包含实际代码案例和代码解析,并且所有代码都会有详细的注释。这是关于第5章 “线性表——数组描述” 的部分:

3. 数组描述

在线性表中,数组是一种常见的数据结构,它使用连续的存储空间来存储线性表的元素。在C++中,我们可以使用数组来描述线性表。

3.1 描述

数组的描述包括数组的定义和基本操作,比如访问元素、插入元素、删除元素等。

以下是一个简单的数组示例:

#include <iostream>
using namespace std;

int main() {
    int numbers[5]; // 创建一个具有5个整数元素的数组
    numbers[0] = 1; // 访问数组的第一个元素,并设置值为1
    numbers[1] = 2; // 访问数组的第二个元素,并设置值为2
    numbers[2] = 3; // 访问数组的第三个元素,并设置值为3
    numbers[3] = 4; // 访问数组的第四个元素,并设置值为4
    numbers[4] = 5; // 访问数组的第五个元素,并设置值为5

    // 打印数组中的所有元素
    for (int i = 0; i < 5; i++) {
        cout << numbers[i] << " ";
    }

    return 0;
}

上述代码创建了一个具有5个整数元素的数组,并分别赋值为1、2、3、4、5。之后,通过循环遍历数组中的元素,并输出到控制台。

3.2 变长一维数组

在C++中,数组的长度是固定的,一旦定义之后就无法改变。然而,在某些情况下,我们需要创建一个可变长度的一维数组。这可以通过使用指针和动态内存分配来实现。

以下是一个创建可变长度一维数组的示例:

#include <iostream>
using namespace std;

int main() {
    int length;
    cout << "Enter the length of the array: ";
    cin >> length;

    int* numbers = new int[length]; // 使用new运算符创建一个长度为length的整数数组
    
    // 向数组中插入数据
    for (int i = 0; i < length; i++) {
        numbers[i] = i + 1;
    }

    // 打印数组中的所有元素
    for (int i = 0; i < length; i++) {
        cout << numbers[i] << " ";
    }

    delete[] numbers; // 释放动态分配的内存

    return 0;
}

上述代码中,我们首先从用户处获取数组的长度,然后使用new运算符动态创建一个长度为length的整数数组。之后,使用循环向数组中插入数据,然后再次使用循环打印数组中的元素。最后,通过delete[]运算符释放动态分配的内存。

3.3 类arrayList

类arrayList是一种使用数组来实现的线性表的数据结构,它提供了一系列对线性表进行操作的方法。

以下是一个类arrayList的示例:

#include <iostream>
#include <stdexcept>
using namespace std;

template <class T>
class arrayList {
private:
    T* elements; // 数组来存储线性表的元素
    int maxSize; // 线性表的最大容量
    int length;  // 线性表的实际长度

public:
    arrayList(int size) {
        maxSize = size;
        elements = new T[maxSize];
        length = 0;
    }

    ~arrayList() {
        delete[] elements;
    }

    bool empty() const {
        return length == 0;
    }

    int size() const {
        return length;
    }

    T& get(int index) const {
        if (index < 0 || index >= length) {
            throw out_of_range("Invalid index");
        }
        return elements[index];
    }

    int indexOf(const T& element) const {
        for (int i = 0; i < length; i++) {
            if (elements[i] == element)
                return i;
        }
        return -1;
    }

    void insert(int index, const T& element) {
        if (index < 0 || index > length) {
            throw out_of_range("Invalid index");
        }
        if (length >= maxSize) {
            throw out_of_range("Exceeded maximum size");
        }
        for (int i = length - 1; i >= index; i--) {
            elements[i + 1] = elements[i];
        }
        elements[index] = element;
        length++;
    }

    void remove(int index) {
        if (index < 0 || index >= length) {
            throw out_of_range("Invalid index");
        }
        for (int i = index + 1; i < length; i++) {
            elements[i - 1] = elements[i];
        }
        length--;
    }

    void output() const {
        for (int i = 0; i < length; i++) {
            cout << elements[i] << " ";
        }
        cout << endl;
    }
};

int main() {
    arrayList<int> list(5); // 创建一个最大容量为5的线性表

    // 向线性表中插入数据
    list.insert(0, 1);
    list.insert(1, 5);
    list.insert(2, 3);
    list.insert(3, 7);
    list.insert(4, 2);

    // 打印线性表中的所有元素
    list.output();

    return 0;
}

上述代码中,我们定义了一个类arrayList,其中包含了线性表的各种操作方法。在main函数中,我们创建了一个最大容量为5的线性表,并向其中插入一些数据,然后输出线性表中的所有元素。

3.4 C++迭代器

C++迭代器是一种用于访问容器中元素的对象。它提供了对容器的遍历和访问操作。

以下是一个使用C++迭代器的示例:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> numbers = {1, 2, 3, 4, 5}; // 创建一个包含一些元素的向量

    // 使用迭代器遍历向量中的所有元素
    for (auto it = numbers.begin(); it != numbers.end(); ++it) {
        cout << *it << " ";
    }

    return 0;
}

上述代码中,我们使用了C++标准库的vector容器,并使用迭代器来遍历和访问向量中的元素。

3.5 arrayList的一个迭代器

在类arrayList中,我们可以实现一个自定义的迭代器来遍历和访问线性表中的元素。

以下是一个自定义迭代器的示例:

#include <iostream>
#include <stdexcept>
using namespace std;

template <class T>
class arrayList {
private:
    T* elements; // 数组来存储线性表的元素
    int maxSize; // 线性表的最大容量
    int length;  // 线性表的实际长度

public:
    // 省略其他成员函数

    // 自定义迭代器类
    class iterator {
    public:
        iterator(T* pointer) : ptr(pointer) {}

        T& operator*() const {
            return *ptr;
        }

        iterator& operator++() {
            ptr++;
            return *this;
        }

        bool operator!=(const iterator& other) const {
            return ptr != other.ptr;
        }

    private:
        T* ptr;
    };

    iterator begin() const {
        return iterator(elements);
    }

    iterator end() const {
        return iterator(elements + length);
    }
};

int main() {
    arrayList<int> list(5); // 创建一个最大容量为5的线性表

    // 向线性表中插入数据
    list.insert(0, 1);
    list.insert(1, 5);
    list.insert(2, 3);
    list.insert(3, 7);
    list.insert(4, 2);

    // 使用迭代器遍历线性表中的元素
    for (auto it = list.begin(); it != list.end(); ++it) {
        cout << *it << " ";
    }

    return 0;
}

上述代码中,我们在类arrayList中定义了一个自定义迭代器类iterator,并在类的成员函数中实现了begin()end()方法,用于返回迭代器的起始位置和结束位置。然后,我们在main函数中使用自定义迭代器遍历线性表中的元素,并输出到控制台。

4. vector的描述

vector是C++标准库中的容器,提供了动态数组的功能,可以自动调整大小以适应元素的数量变化。下面是一个使用vector的例子:

#include <iostream>
#include <vector>

int main() {
    // 创建一个空的vector
    std::vector<int> nums;

    // 向vector中添加元素
    nums.push_back(1);
    nums.push_back(2);
    nums.push_back(3);

    // 遍历打印vector中的元素
    for(int i = 0; i < nums.size(); i++) {
        std::cout << nums[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

代码解析:

  • 首先,我们包含了<iostream><vector>头文件,分别用于输入输出和使用vector容器。
  • main()函数中,我们创建了一个名为numsvector对象,它的元素类型是int
  • 使用push_back()函数向vector中添加元素,这里我们添加了1、2和3三个元素。
  • 使用size()函数获取vector中元素的数量,并使用[]运算符遍历打印每个元素。
输出结果为:1 2 3

5. 在一个数组中实现的多重表

多重表(Multilist)是一种使用数组实现的数据结构,在实际中有很多应用场景。下面是一个简单的多重表例子:

#include <iostream>

const int MAX_SIZE = 100;  // 多重表的最大大小

struct Node {
    int key;              // 关键字
    Node* nextSibling;    // 下一个兄弟节点
    Node* firstChild;     // 第一个子节点
};

int main() {
    Node multilist[MAX_SIZE];   // 多重表的数组表示

    // 初始化多重表
    for(int i = 0; i < MAX_SIZE; i++) {
        multilist[i].key = i + 1;
        multilist[i].nextSibling = nullptr;
        multilist[i].firstChild = nullptr;
    }

    // 打印多重表节点的关键字
    for(int i = 0; i < MAX_SIZE; i++) {
        std::cout << multilist[i].key << " ";
    }
    std::cout << std::endl;

    return 0;
}

代码解析:

  • 定义了一个常量MAX_SIZE表示多重表的最大大小,这里假设为100。
  • Node结构体表示多重表的节点,包含关键字key、下一个兄弟节点nextSibling和第一个子节点firstChild
  • main()函数中,我们定义了一个名为multilist的数组,表示多重表的存储结构。
  • 使用一个循环初始化多重表,将每个节点的关键字设置为对应下标加1,同时将nextSiblingfirstChild指针设为nullptr
  • 最后,使用另一个循环遍历并打印多重表中每个节点的关键字。
输出结果为:1 2 3 4 5 ... 100

6. 性能测量

在C++中,我们可以使用<chrono>头文件中的时间点和时钟来测量程序的性能。下面是一个性能测量的例子:

#include <iostream>
#include <chrono>

int main() {
    auto startTime = std::chrono::high_resolution_clock::now();

    // 需要测量性能的代码
    for(int i = 0; i < 1000000; i++) {
        // do something
    }

    auto endTime = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(endTime - startTime).count();

    std::cout << "运行时间:" << duration << " 微秒" << std::endl;

    return 0;
}

代码解析:

  • 包含了<iostream><chrono>头文件,前者用于输入输出,后者用于进行性能测量。
  • main()函数中,使用std::chrono::high_resolution_clock::now()获取开始时间点。
  • 在需要测量性能的代码段中,可以放置需要重复执行多次的代码。
  • 使用std::chrono::high_resolution_clock::now()获取结束时间点,然后使用duration_cast函数将时间间隔转换为微秒,并计算时间间隔的毫秒数。
  • 最后,输出测量结果。
输出结果为:运行时间:xxx 微秒,其中xxx表示实际运行的时间。
评论 54
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嵌你一颗小芯芯

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

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

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

打赏作者

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

抵扣说明:

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

余额充值