C++数据结构之静态链表

1.静态链表的作用

在有些早期的高级语言中,并没有指针概念,所以带有指针域的链表都无法在这些高级语言中使用。于是,出现了用一维数组代替指针来描述单链表,这种一维数组描述的链表就被称为静态链表,用以为数组的方式来表示链表,因此拥有了数组的特性:1、内存连续 2、存储的数据类型相同,作用是为了不使用指针来表示连续存储的链式数据结构。

        图1 用静态链表存储数据(需要分配一整块连续的内存空间)

2.代码实现

代码如下:

#define MaxSize 201
//节点使用情况的枚举标记值
enum NODEUSE
{
    e_NOUSE = -1,//未使用
    e_LAST = -2//最后一个节点(末尾)
};

template<typename T>
struct Node 
{
    T data;
    int cur;//游标,记录下个静态链表节点的数组下标
};

template<typename T>
class StaticLinkList 
{
public:
    StaticLinkList();
    ~StaticLinkList();

public:
    int findAndIdlePos();//找一个空闲的位置用于保存数据
    bool ListInsert(int i,const T& e);//在第i个位置插入指定元素e
    bool ListDelete(int i);//删除第i个位置的元素
    bool GetElem(int i,T& e);//获取第i个位置的元素值
    int LocateElem(const T& e);//按元素值查找到其在静态链表中第一次出现的位置
    void DispList();//输出静态数组中的所有元素
    int ListLength();//获取静态链表的长度
    bool Empty();//判断静态链表是否为空

private:
    Node<T> m_data[MaxSize];//保存节点数据的数组
    int m_length;//当前长度,也就是当前保存的数据节点数目
};

template<typename T>
StaticLinkList<T>::StaticLinkList() 
{
    for (int i = 1; i < MaxSize; i++) //下标0是头节点,不能用来保存数据
    {
        m_data[i].cur = e_NOUSE;//初始化各个节点的状态为未使用
    }
    m_length = 0;
}

template<typename T>
StaticLinkList<T>::~StaticLinkList() 
{
    
}

template<typename T>
int StaticLinkList<T>::findAndIdlePos() 
{
    for (int i = 1; i < MaxSize; i++) 
    {
        if (m_data[i].cur == e_NOUSE)
        {
            return i;
        }
    }
    return -1;
}

template<typename T>
bool StaticLinkList<T>::ListInsert(int i, const T& e)
{
    if ((i < 1) || (i > (m_length +1)))
    {
        cout << "元素" << e << "插入的位置" << i << "不合理,合理的位置为1到" << m_length << "之间" << endl;
        return false;
    }
    int iIdx;
    if ((iIdx = findAndIdlePos()) == -1) 
    {
        cout << "静态链表已满,无法插入数据" << endl;
        return false;
    }
    int iDataCount = 1;//统计静态链表中的元素个数
    int iIdxPrev;//保存第i-1个位子对应的m_data数组的下标
    if (i == 1) //向第一个元素插入数据,需要单独处理
    {
        m_data[iIdx].data = e;
        if (m_length == 0) 
        {
            m_data[iIdx].cur = e_LAST;
        }
        else 
        {
            m_data[iIdx].cur = m_data[0].cur;
        }
        m_data[0].cur = iIdx;
    }
    else 
    {
        int iPosCount = 0;//位置的计数
        int tmpcur = m_data[0].cur;
        while (1) 
        {
            iPosCount++;
            if (iPosCount >= (i - 1)) 
            {
                iIdxPrev = tmpcur;
                break;
            }
            tmpcur = m_data[tmpcur].cur;
        }
        int ITmpCurr = m_data[iIdxPrev].cur;
        m_data[iIdxPrev].cur = iIdx;
        m_data[iIdx].data = e;
        m_data[iIdx].cur = ITmpCurr;
    }
    cout << "成功在位置为" << i << "处插入元素" << e << endl;
    m_length++;
    return true;
}

template<typename T>
void StaticLinkList<T>::DispList() 
{
    if (m_length <1) 
    {
        cout << "当前静态链表为空,无法输出元素" << endl;
        return;
    }
    int tmpcur = m_data[0].cur;
    while (1) 
    {
        cout << m_data[tmpcur].data << " ";
        if ((tmpcur = m_data[tmpcur].cur) == e_LAST)
        {
            break;
        }
    }
    cout << endl;
}

template<typename T>
bool StaticLinkList<T>::GetElem(int i,T &e) 
{
    if (m_length < 1) 
    {
        cout << "当前静态链表为空,无法输出元素" << endl;
        return false;
    }
    if (i < 1 || i > m_length) 
    {
        cout << "获取元素的位置" << i << "不合理,合理的位置应该位于1到" << m_length << "之间" << endl;
        return false;
    }
    int tmpcur = m_data[0].cur;
    int iPos = 0;
    while (true)
    {
        ++iPos;
        if (iPos == i) 
        {
            e = m_data[tmpcur].data;
            cout << "成功获取位置为" << i << "的元素,该元素的值为" << e << endl;
            return true;
        }
        tmpcur = m_data[tmpcur].cur;
    }
    return false;
}

template<typename T>
int StaticLinkList<T>::LocateElem(const T& e) 
{
    if (m_length < 1) 
    {
        cout << "当前静态链表为空,不能获取任何数据" << endl;
        return -1;
    }
    int tmpcur = m_data[0].cur;
    int iPos = 0;
    while (true) 
    {
        iPos++;
        if (m_data[tmpcur].data == e && m_data[tmpcur].cur != e_NOUSE)
        {
            cout << "元素值为" << e << "第一次出现在静态链表中的位置为" << iPos << endl;
            return tmpcur;
        }
        if (m_data[tmpcur].cur == e_LAST)
        {
            break;
        }
        tmpcur = m_data[tmpcur].cur;
    }
    cout << "值为" << e << "的元素在静态链表中没有找到" << endl;
    return -1;
}

template<typename T>
bool StaticLinkList<T>::Empty() 
{
    if (m_length < 1) 
    {
        return true;
    }
    return false;
}

template<typename T>
bool StaticLinkList<T>::ListDelete(int iPos) 
{
    if (m_length < 1) 
    {
        cout << "当前静态链表为空,不能删除任何数据" << endl;
        return false;
    }
    if (iPos < 1 || iPos > m_length) 
    {
        cout << "删除的位置" << iPos << "不合理,合理的位置是1到" << m_length << "之间" << endl;
        return false;
    }
    int tmpcur = m_data[0].cur;
    if (iPos == 1) //单独处理位置为1的情况
    {
        if (m_length != 1) 
        {
            //静态数组不止一个元素的情况
            m_data[0].cur = m_data[tmpcur].cur;
        }
        m_data[tmpcur].cur = e_NOUSE;
        cout << "成功删除位置为" << iPos << "的元素,该元素的值为" << m_data[tmpcur].data << endl;
    }
    else 
    {
        int iIdxPrev;//第iPos-1个位置对应的m_data数组的下标
        int iPosCount = 0;//设置计数
        while (true) 
        {
            iPosCount++;
            if (iPosCount >= (iPos - 1)) 
            {
                iIdxPrev = tmpcur;
                break;
            }
            tmpcur = m_data[tmpcur].cur;
        }
        int iTmpCurr = m_data[iIdxPrev].cur;
        m_data[iTmpCurr].cur = e_NOUSE;
        cout << "成功删除位置为" << iPos << "的元素,该元素的值为" << m_data[iTmpCurr].data << endl;
    }
    m_length--;
    return true;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值