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;
}