链表的游标实现

如果需要使用链表时,而又不能使用指针时,我们就的需要使用链表的游标实现法,具体的介绍如下。
首先说明一下链表的指针功能的两个特点:(a)数据存储在一个结构体中,每个结构体包含有数据及指向下一个结构体的指针(b)一个新的结构体可以通过调用malloc函数从系统全局内存得到,并可以通过调用free函数释放
要用游标法实现实现这两个功能,我们这样做:(1)定义一个全局结构体数组,每个数组元素的下标可以表示地址,就可以实现上述链表的功能(a);(2)我们用一个freelist以0为表头的表,表中的单元为不在链表中的单元构成,执行malloc函数的功能时,从freelist表中拿出一个单元,并与链表连接起来,执行free函数的功能时,从链表中将一个单元加入到freelist表。这样我们就用游标法实现了链表的两个重要的功能。
在这里,0的功能与NULL指针相当。freelist表的一种初始化如下:

Slot 0 1 2 3 4 5 6 7 8 9 10
Element
Next 1 2 3 4 5 6 7 8 9 10 0
这样我们就得到一个如下的freelist表:
freelist表
我们调用malloc函数时,则从该表中得到一个单元,调用free函数时,则将链表的一个单元放回freelist表。链表的游标实现的相关代码如下:
头文件cursor.h的代码如下:

#pragma once
#ifndef _CUTSOR_H_
#define _CUTSOR_H_
#define SpaceSize 11
typedef int ProToNode;
typedef  ProToNode List;
typedef ProToNode Position;
typedef int Elementtype;
using namespace std;
struct Node {
	Elementtype Element;
	Position Next;
}; 
extern struct Node CursorSpace[SpaceSize];

void InitilizeCursorSpace(void);//初始化Cursor空间
 Position CursorAlloc(void);//模拟malloc函数的功能,为链表分配空间
void CursorFree(Position P);//模拟free函数的功能,删除该位置的空间
List MakeEmpty(List L);//制造空链表节点
int Isempty(const List L);//判断链表是否为空
int Islast(const Position P,const List L);//判断该位置是否为链表尾
Position Find(Elementtype X, const List L);//寻找该元素在链表中的位置
void Delete(Elementtype X, List L);//删除该元素
Position FindPrevious(Elementtype X, const List L);//寻找该元素的前一个元素的位置
void Insert(Elementtype X, List L, Position P);//在链表中指定位置插入元素
void DeleteList(List L);//删除整个链表
Position First(const List L);//寻找链表第一个元素的位置
Elementtype Retrieve(const Position P);//寻找该位置的元素
void show(List L);
#endif

*头文件中的相关函数的定义文件cursor.cpp代码如下

#include"Cursor.h"
#include<iostream>


void InitilizeCursorSpace(void) {//初始化Cursor空间
	for (int i = 0; i < SpaceSize-1; i++) {
		CursorSpace[i].Element = 0;
		CursorSpace[i].Next = i + 1;
	}
	CursorSpace[SpaceSize-1].Element = 0;
	CursorSpace[SpaceSize-1].Next = 0;
	
}
  Position CursorAlloc(void) {//模拟malloc函数的功能,为链表分配空间
	Position P;
	P = CursorSpace[0].Next;
	CursorSpace[0].Next = CursorSpace[P].Next;
	return P;
}
 void CursorFree(Position P) {//模拟free函数的功能,删除该位置的空间
	CursorSpace[P].Next = CursorSpace[0].Next;
	CursorSpace[0].Next = P;
}
List MakeEmpty(List L) {//制造空链表节点
	Position p = CursorAlloc();
	return (List)p;
}
int Isempty(const List L) {//判断链表是否为空
	return CursorSpace[L].Next == 0;
}
int Islast(const Position P, const List L) {//判断该位置是否为链表尾
	return CursorSpace[P].Next == 0;
}
Position Find(Elementtype X, const List L) {//寻找该元素在链表中的位置
	Position P;
	P = CursorSpace[L].Next;
	while (P&&CursorSpace[P].Element!=X) {
		P = CursorSpace[P].Next;
	}
	if (CursorSpace[P].Element == X)
		cout << "链表中有该元素,返回的位置确实为该元素的位置!" << endl;
	else
		cout << "链表中无该元素,返回的是链表表尾的位置!" << endl;
	return P;
}
Position FindPrevious(Elementtype X, const List L) {//寻找该元素的前一个的位置
	Position P;
	P =L ;
	while (CursorSpace[P].Next && CursorSpace[CursorSpace[P].Next].Element != X) {
		P = CursorSpace[P].Next;
	}
	if (CursorSpace[CursorSpace[P].Next].Element == X)
		cout << "链表中有该元素,返回的位置确实为该元素前面一个的位置!" << endl;
	else
		cout << "链表中无该元素,返回的是链表表尾前一个的位置!" << endl;
	
	return P;
}
void Delete(Elementtype X, List L) {//删除该元素
	Position P = FindPrevious(X, L);
	Position temp = CursorSpace[P].Next;
	CursorFree(CursorSpace[P].Next);
	CursorSpace[P].Next = P + 2;
}

void Insert(Elementtype X, List L, Position P) {//在链表中指定位置插入元素
	
		Position Temp = CursorAlloc();
		CursorSpace[Temp].Element = X;
		CursorSpace[Temp].Next = CursorSpace[P].Next;
		CursorSpace[P].Next = Temp;//将链表连接起来
		
	
}
void DeleteList(List L) {//删除整个链表
	Position P1 = L;
	Position P2 = CursorSpace[L].Next;
	for (; P2 != 0; P2 = CursorSpace[P1].Next) {
		CursorFree(P1);
		P1 = P2;
	}
	CursorFree(P1);
}

Position First(const List L) {//寻找链表第一个的位置
	return CursorSpace[L].Next;
}

Elementtype Retrieve(const Position P) {//寻找该位置的元素
	return CursorSpace[P].Element;
}
void show(List L) {
	Position P;
	for (P = CursorSpace[L].Next; P != 0; P = CursorSpace[P].Next)
		printf("%d  ", CursorSpace[P].Element );
	
}



主程序的代码如下

/**************************************************************************************************************************
//该程序用于实现链表的游标实现(1)将数据存储在一个全局数组,每个数据有一个下标表示地址,来实现链表的每个结构体有指向下一个
//结构体的指针(2)用一个以单元0作为表头的表,让全局数组的数据单元来代行链表的malloc,free功能
//
****************************************************************************************************************************/

#include"Cursor.h"
#include<iostream>
 struct Node CursorSpace[SpaceSize];
int main() {
	InitilizeCursorSpace();
	List pList=CursorAlloc();
	Position P1 = CursorAlloc();
	CursorSpace[pList].Next = P1;
	for (int i = 1; i < 10; ++i) {
		CursorSpace[P1].Element = i;
		Position P2 = CursorAlloc();
		CursorSpace[P1].Next = P2;
		P1 = P2;
	}
	
	show(pList);
	printf("\n");
	
	//下面只测试部分函数的功能
	cout << "测试Find函数" << endl;
	cout <<"元素5的位置为"<< Find(5, pList) << endl;
	
	cout << "测试Delete函数" << endl;
	cout << "删除元素5" << endl;
	Delete(5, pList);
	show(pList);
	printf("\n");
	
	cout << "测试Insert函数:" << endl;
	Insert(5, pList, 5);
	show(pList);
	printf("\n");

	cout << "测试Retrive函数:" << endl;
	Elementtype t = Retrieve(4);
	cout << "位置4的元素为:" << t<<endl;

	cout << "测试DeleteList函数:" << endl;
	DeleteList(pList);
	show(pList);
	return 0;
}

程序的运行结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值