静态链表要解决的问题是:如何静态模拟动态链表关于存储空间申请和释放,动态链表可以借助malloc和free两个函数实现。在静态链表中,由于操作的是数组,不存在像动态链表的节点申请和释放问题,因此我们得自己完成两个函数来模拟这两个动作。
解决办法:
将静态链表划分为“有效链表,备用链表”,通过两者模拟节点的申请和释放
静态链表:
1)有效链表(已经使用的数组元素按游标cur链接而成)
2)备用链表(未使用的数组元素按游标cur链接而成)
Malloc_SL(申请节点):从备用链表中取得一个节点
Free_SL (释放节点) :将释放的节点连接到备用链表中
所实现的静态链表的结构如下图所示:
具体实现参考如下代码:
StaticList.h
//静态链表 //数组第一个元素和最后一个元素特殊化处理 //1:s[0].cur存放备用链表的第一个节点的下标(备用链表的头结点),非0表示存在备用链表,为0表示不存在备用链表 //2:s[MAXSIZE-1].cur存放第一个有数值的节点的下标(相当于头结点)非0表示存在有效链表,为0表示不存在有效链表 #include<iostream> #include<cstdlib> #include<cassert> using namespace std; typedef enum{FALSE,TRUE}Status; typedef int ElemType; #define MAXSIZE 10 typedef struct StaticNode { ElemType data; int cur; }StaticNode; typedef StaticNode StaticList[MAXSIZE]; void Init_SL(StaticList &SL) { for (int i = 0; i < MAXSIZE - 1; ++i) { SL[i].cur = i + 1; } SL[MAXSIZE - 1].cur = 0;//开始静态链表为空,没有有效节点,所以有效链表的头结点的指向为NULL(0) } //开辟成功:返回开辟节点的下标 //开辟失败:返回0 int Malloc_SL(StaticList &SL) { int i = SL[0].cur; if (i != 0)//存在备用链表 { SL[0].cur = SL[i].cur;//备用链表用了一个节点,把它的下一个节点用来备用 } return i; } //将释放的节点,头插到备用链表中 void Free_SL(StaticList &SL,int k) { SL[k].cur = SL[0].cur; SL[0].cur = k; } void Show_SL(StaticList SL) { int i = SL[MAXSIZE - 1].cur;//找到第一个有效节点的下标 while (i != 0) { cout << SL[i].data << "-->"; i = SL[i].cur; } cout <<"Nul."<< endl; } Status Push_Back(StaticList &SL, ElemType x) { int i = Malloc_SL(SL); if (i == 0) { cout << "静态链表已满"<<x<<"无法尾插" << endl; return FALSE; } SL[i].data = x; SL[i].cur = 0; int j = SL[MAXSIZE - 1].cur;//寻找最后一个节点(最后一个节点的cur为0),进行尾插 while (SL[j].cur != 0) { j = SL[j].cur; } SL[j].cur = i; return TRUE; } Status Push_Front(StaticList &SL, ElemType x) { int i = Malloc_SL(SL); if (i == 0) { cout << "静态链表已满" << x << "无法头插" << endl; return FALSE; } SL[i].data = x; SL[i].cur = SL[MAXSIZE - 1].cur; SL[MAXSIZE - 1].cur = i; return TRUE; } Status Pop_Front(StaticList &SL) { if (SL[MAXSIZE - 1].cur == 0) { cout << "静态链表已空,无法头删" << endl; return FALSE; } int i = SL[MAXSIZE - 1].cur; SL[MAXSIZE - 1].cur = SL[i].cur; Free_SL(SL, i); //SL[MAXSIZE - 1].cur = SL[i].cur;//从有效节点中删除 //SL[i].cur = SL[0].cur;//将删除的节点头插入到备用链表中 //SL[0].cur = i; return TRUE; } Status Pop_Back(StaticList &SL) { if (SL[MAXSIZE - 1].cur == 0) { cout << "静态链表已空,无法头删" << endl; return FALSE; } int i = MAXSIZE - 1; while (SL[SL[i].cur].cur != 0)//寻找最后一个节点的前驱 { i = SL[i].cur; } int tmp = SL[i].cur;//有效链表的最后一个节点的坐标(先保存下来) SL[i].cur = 0;//在有效链表中删除尾节点 Free_SL(SL,tmp); //SL[tmp].cur = SL[0].cur; //SL[0].cur = tmp; return TRUE; }
main.cpp
#include"StaticList.h" int main() { StaticList SL; Init_SL(SL); for (int i = 0; i < 5; ++i) { //Push_Back(SL, i); Push_Front(SL, i); } Show_SL(SL); for (int i = 0; i < 5; ++i) { //Pop_Front(SL); Pop_Back(SL); Show_SL(SL); } system("pause"); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-27 07:02:58