您的位置:首页 > 理论基础 > 数据结构算法

【c++版数据结构】之用c语言实现静态链表

2015-08-27 14:58 766 查看
静态链表要解决的问题是:如何静态模拟动态链表关于存储空间申请和释放,动态链表可以借助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 || i == MAXSIZE - 1)
		return 0;
	else//存在备用链表
		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;
}

//void Clear_SL(StaticList &SL)
//#include<iostream>
//using namespace std;
//#define MAXSIZE 8
//typedef int ElemType;
//
//typedef struct StaticListNode
//{
//	ElemType data;
//	size_t   cur;
//}StaticListNode;
//typedef StaticListNode StaticList[MAXSIZE];
//
//void Initialize(StaticList &SL)
//{
//
//}
//int Malloc_SL(StaticList &SL)
//{
//	if (SL[1].cur == -1)     //SL[1].cur存放备用链表的第一个节点的下标
//		return -1;
//	int i = SL[1].cur;
//	SL[1].cur = SL[i].cur;   //作业——--->头删除,尾删除(回收空间)
//	return i;
//}


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


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: