【c++版數據結構】之用c語言實現靜態鏈表

靜態鏈表要解決的問題是:如何靜態模擬動態鏈表關於存儲空間申請和釋放,動態鏈表可以藉助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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章