首页 > 其他分享 >【数据结构】线性表的数组描述和链式描述

【数据结构】线性表的数组描述和链式描述

时间:2023-09-30 09:56:13浏览次数:37  
标签:theIndex const 线性表 int listSize element next 数据结构 描述

1. 线性表抽象类

#pragma once
template <class T>
class LinearList
{
public:
    // 线性表是否为空
    virtual bool empty() const = 0;
    // 线性表大小
    virtual int size() const = 0;
    // 根据ID获取线性表元素
    virtual T& get(int theIndex) const = 0;
    // 根据元素获取元素对应ID
    virtual int indexOf(const T& theElement) const = 0;
    // 删除ID处的元素
    virtual void erase(int theIndex) = 0;
    // 在ID处插入元素
    virtual void insert(int theIndex, const T& theElement) = 0;
    // 输出线性表
    virtual void output() = 0;
};

2. 线性表的数组描述

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

template<class T>
class ArrayList :public LinearList<T>
{
protected:
    T* element;                                // 线性表元素指针
    int arrayLength;                        // 容量
    int listSize;                            // 元素个数
    bool checkIndex(int theIndex) const;    // 检查索引是否有效
    void changeLength();                    // 扩充数组长度

public:
    // 构造函数
    ArrayList(int initialCapacity = 10);
    // 拷贝构造函数
    ArrayList(const ArrayList<T>& theList);
    // 析构函数
    ~ArrayList() 
    {
        delete[] element;
    }

    // 线性表是否为空
    bool empty() const { return listSize == 0; }

    // 线性表大小
    int size() const { return listSize; }

    // 线性表容量
    int capacity() const { return arrayLength; }

    // 根据ID获取线性表元素
    T& get(int theIndex) const;

    // 根据元素获取元素对应ID
    int indexOf(const T& theElement) const;

    // 删除ID处的元素
    void erase(int theIndex);

    // 在ID处插入元素
    void insert(int theIndex, const T& theElement);

    // 输出线性表
    void output();

};


// 构造函数
template<class T>
ArrayList<T>::ArrayList(int initialCapacity)
{
    if (initialCapacity < 1) 
    {
        cout << "初始化容量必须大于0" << endl;
        return;
    }
    this->arrayLength = initialCapacity;
    this->element = new T[arrayLength];
    listSize = 0;
}

// 复制构造函数
template<class T>
ArrayList<T>::ArrayList(const ArrayList<T>& theList)
{
    this->arrayLength = theList.arrayLength;
    this->listSize = theList.listSize;
    this->element = new T[arrayLength];
    copy(theList.element, theList.element + listSize, element);
}

// 越界, false 表示越界, true 表示没有越界
template<class T>
bool ArrayList<T>::checkIndex(int theIndex) const
{
    bool ret = !(theIndex < 0 || theIndex > listSize);
    return ret;
}


// 获取元素
template<class T>
T& ArrayList<T>::get(int theIndex) const
{
    if (checkIndex(theIndex))
    {
        return element[theIndex];
    }
}

// 根据元素获取ID
template<class T>
int ArrayList<T>::indexOf(const T& theElement) const
{
    int theIndex = (int)find(element, element + listSize, theElement);
    return theIndex == listSize ? -1 : (theIndex-(int)element)/sizeof(T);
}

// 删除ID处元素
template<class T>
void ArrayList<T>::erase(int theIndex)
{
    if (checkIndex(theIndex))
    {
        copy(element + theIndex + 1, element + listSize, element + theIndex);
        element[--listSize].~T();
    }
}

// 扩充数组长度
template<class T>
void ArrayList<T>::changeLength()
{
    T* temp = new T[arrayLength * 2];
    copy(element, element + arrayLength, temp);
    delete[] element;
    element = temp;
    arrayLength = 2 * arrayLength;
}


// 在ID处插入元素
template<class T>
void ArrayList<T>::insert(int theIndex, const T& theElement)
{
    if (!checkIndex(theIndex))
    {
        cout << "无效索引" << endl;
        return;
    }
    if (listSize == arrayLength)
    {
        changeLength();
    }
    copy_backward(element + theIndex, element + listSize, element + listSize + 1);
    element[theIndex] = theElement;
    listSize++;
}

// 输出线性表
template<class T>
void ArrayList<T>::output()
{
    for (int i = 0; i < listSize; i++)
    {
        cout << element[i] << " ";
    }
    cout << endl;
}

3. 线性表的链式描述

3.1 结点结构体

#pragma once
#include<iostream>
using namespace std;
template <class T>
struct ChainNode
{
    // 数据成员
    T element;
    ChainNode<T>* next;

    // 方法
    ChainNode() {}
    ChainNode(const T& element)
    {
        this->element = element;
    }
    ChainNode(const T& element, ChainNode<T>* next)
    {
        this->element = element;
        this->next = next;
    }
};

3.2 线性表实现

#include"linearList.h"
#include"chianNode.h"
#include<iostream>
using namespace std;
template<class T>
class Chain :public LinearList<T>
{
protected:
    ChainNode<T>* firstNode;
    int listSize;
    bool checkIndex(int theIndex) const;

public:
    Chain(int initialCapacity = 10);
    Chain(const Chain<T>&);
    ~Chain();

    bool empty() const { return listSize == 0; };
    // 线性表大小
    int size() const { return listSize; }
    // 根据ID获取线性表元素
    T& get(int theIndex) const;
    // 根据元素获取元素对应ID
    int indexOf(const T& theElement) const;
    // 删除ID处的元素
    void erase(int theIndex);
    // 在ID处插入元素
    void insert(int theIndex, const T& theElement);
    // 输出线性表
    void output();
};

// 普通的构造函数
template<class T>
Chain<T>::Chain(int initialCapacity)
{
    if (initialCapacity < 1)
    {
        cout << "初始容量设置必须大于0" << endl;
    }
    firstNode = NULL;
    listSize = 0;
}

// 拷贝构造函数
template<class T>
Chain<T>::Chain(const Chain<T>& theList)
{
    listSize = theList.listSize;
    if (listSize == 0)
    {
        firstNode = NULL;
        return;
    }
    ChainNode<T>* sourceNode = theList.firstNode;
    firstNode = new ChainNode<T>(sourceNode->element);
    sourceNode = sourceNode->next;
    ChainNode<T>* targetNode = firstNode;
    while (sourceNode != NULL)
    {
        targetNode->next = new ChainNode<T>(sourceNode->element);
        targetNode = targetNode->next;
        sourceNode = sourceNode->next;
    }
    targetNode->next = NULL;
}

// 析构函数
template<class T>
Chain<T>::~Chain()
{
    while (firstNode != NULL)
    {
        ChainNode<T>* nextNode = firstNode->next;
        delete firstNode;
        firstNode = nextNode;
    }
}

template<class T>
T& Chain<T>::get(int theIndex) const
{
    if (checkIndex(theIndex))
    {
        ChainNode<T>* currentNode = firstNode;
        for (int i = 0; i < theIndex; i++)
        {
            currentNode = currentNode->next;
        }
        return currentNode->element;
    }
}

template<class T>
int Chain<T>::indexOf(const T& theElement) const
{
    ChainNode<T>* currentNode = firstNode;
    int index = 0;
    while (currentNode->element != theElement && currentNode != NULL)
    {
        currentNode = currentNode->next;
        index++;
    }
    return currentNode == NULL ? -1 : index;
}

template<class T>
void Chain<T>::erase(int theIndex)
{
    if (checkIndex(theIndex))
    {
        ChainNode<T>* deleteNode;
        if (theIndex == 0)
        {
            deleteNode = firstNode;
            firstNode = firstNode->next;
        }
        else if (theIndex < listSize - 1)
        {
            ChainNode<T>* p = firstNode;
            for (int i = 0; i < theIndex - 1; i++)
            {
                p = p->next;
            }
            deleteNode = p->next;
            p->next = p->next->next;
        }
        else
        {
            ChainNode<T>* p = firstNode;
            for (int i = 0; i < theIndex; i++)
            {
                p = p->next;
            }
            deleteNode = p;
            p->next = NULL;
        }
        listSize--;
        delete deleteNode;
    }
}

template<class T>
void Chain<T>::insert(int theIndex, const T& theElement)
{
    if (checkIndex(theIndex))
    {
        if (theIndex == 0)
        {
            firstNode = new ChainNode<T>(theElement, firstNode);
        }
        else
        {
            ChainNode<T>* p = firstNode;
            for (int i = 0; i < theIndex - 1; i++)
            {
                p = p->next;
            }
            p->next = new ChainNode<T>(theElement, p->next);
        }
        listSize++;
    }
}


template<class T>
void Chain<T>::output()
{
    ChainNode<T>* currentNode = firstNode;
    while (currentNode != NULL)
    {
        cout << currentNode->element << " ";
        currentNode = currentNode->next;
    }
    cout << endl;
}

template<class T>
bool Chain<T>::checkIndex(int theIndex) const
{
    bool ret = !(theIndex < 0 || theIndex > listSize);
    return ret;
}

 

标签:theIndex,const,线性表,int,listSize,element,next,数据结构,描述
From: https://www.cnblogs.com/stux/p/17737631.html

相关文章

  • 数据结构总结
    数据结构数组array·数组有维度之分,是十分重要的数据结构,最简单的数组是一维数组,其逻辑结构为线性表.·数组的特点:插入删除是$O(n)$的,但是可以随机下标访问.STL中的可变长度数组vector基础操作<vector>vector<int>v;vector<int>::iteratorit;v.pus......
  • Python笔记:基本数据结构(容器)的优化
    列表的性能问题队列的弹出问题利用Python的原生语法很难写出一个真正完全能达到\(O(1)\)的队列,究其原因是由于insert方法的时间复杂度问题:classqueue: def__init__(self,q): self.q=[] defpopright(self): self.q.pop() defappendleft(self,elem): self.q.ins......
  • 浅谈数据结构栈与队列
    栈1.栈的基本概念栈(Stack):是只允许在一端进行插入或删除的线性表。首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作。不能插入和删除的一端为栈底(Bottom)栈顶(top):线性表允许进行插入删除的那一端栈底(bottom):固定的,不允许进行插入和删除的那一端空栈:不含任何元素的......
  • 数据结构---字符串
    数据结构---字符串串的定义串是由零个或多个字符顺序排列组成的有限序列空串长度为零的串空白串由一个或多个空格组成的串字符串匹配问题朴素模式匹配模式匹配的查找过程(Find):给定两个字符串变量S和P,其中目标S有n个字符,模式P有m个字符,m<=n。从S的给定位置(通常为S的第......
  • 关于数据结构树的概括
    树结构是一种非常重要且广泛应用的数据结构。它以节点和边的形式组织数据,具有层次关系和递归性质。树结构在计算机科学领域中有着广泛的应用,例如文件系统、数据库索引、网络路由等。一、什么是树树是数据结构中的一种,其属于非线性数据结构结构的一种,我们前文所提到的数据结构多数......
  • 关于数据结构树的概括
    树结构是一种非常重要且广泛应用的数据结构。它以节点和边的形式组织数据,具有层次关系和递归性质。树结构在计算机科学领域中有着广泛的应用,例如文件系统、数据库索引、网络路由等。一、什么是树树是数据结构中的一种,其属于非线性数据结构结构的一种,我们前文所提到的数据结构多数都......
  • 数据结构学习带背(一)|基本概念
    数据结构的基本概念:数据数据元素数据对象数据类型数据结构数据结构的三要素:1、2、3、分别有什么?===测试可以用()定义一个完整的数据结构(栈是什么?......
  • Redis系列 - Redis底层数据结构(简单动态字符串(SDS)、链表、字典、跳跃表、整数集合
    转自:https://blog.csdn.net/u011485472/article/details/109460490Redis系列-Redis底层数据结构(简单动态字符串(SDS)、链表、字典、跳跃表、整数集合、压缩列表)简单动态字符串(simpledynamicstring,SDS)链表字典跳跃表整数集合压缩列表RedisObject在介绍Redis底......
  • 关于数据结构单链表
    单链表作为最基础也是最常用的数据结构之一,在这门课程中占据着十分重要的地位。本文将对单链表这一章节的知识点进行总结,包括单链表的定义、基本操作、常见应用以及时间复杂度等方面。一、单链表的定义和基本操作单链表的定义:单链表由节点组成,每个节点包含数据和指向下一个节点的指......
  • UE4里的数据结构与算法
    在CoreMinimal.h的头文件里可以看到最常使用的头文件数据结构:Plane(平面)、Sphere(椭圆)、Box(四边形外接框)、Edge(边)等。算法:Core\Public\Algo文件夹下 ......