如何有游标实现表?

linhf 2001-12-10 05:43:55
...全文
67 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
starfish 2001-12-10
  • 打赏
  • 举报
回复
模拟指针就是游标实现
starfish 2001-12-10
  • 打赏
  • 举报
回复
/*
文件名: List.h
功能: ADT线性表类的定义
作者: starfish (starfish.h@china.com)
最后一次修改日期: 2001/8/31
*/

#ifndef LDSA_List


/*
文件名: SimChain.h
功能: 模拟指针实现的链表
作者: starfish (starfish.h@china.com)
最后一次修改日期: 2001/8/30
*/


#ifndef LDSA_SimChain
#define LDSA_SimChain

#include "List.h"
#include "Exception.h"

namespace LDSA {

template <class TYPE> class SimChain;
template <class TYPE> class SimSpace;
template <class TYPE> class SimChainPos;


/*
定义SimNode :模拟指针的节点
*/

template <class TYPE>
class SimNode {
friend SimSpace<TYPE>;
friend SimChain<TYPE>;
friend SimChainPos<TYPE>;
private:
TYPE m_data; // 存储数据
int m_nNext; // 下一个节点的指针
};


/*
定义SimSpace :模拟指针的可用空间表
*/

template <class TYPE>
class SimSpace {
friend SimChain<TYPE>;
friend SimChainPos<TYPE>;
private:
int m_nCapacity; // 空间的容量
int m_nFirst; // 第一个可用节点的索引
SimNode<TYPE>* m_pTable; // 存储空间指针
public:
/*
enum {
DEFAULT_CAPACITY = 10000
};
*/

// 设置默认容量
static void SetDefaultCapacity(int capacity) {
DEFAULT_CAPACITY = capacity;
}
private:
static const int DEFAULT_CAPACITY;

public:
SimSpace(int Capacity = DEFAULT_CAPACITY);
~SimSpace();

// 分配一个存储空间
int Allocate();

// 释放一个索引为i的存储空间
void Dispose(int& i);

SimNode<TYPE>& operator[](const SimChainPos<TYPE>& pos)
{
if (pos.m_nIndex < 0 || pos.m_nIndex >= m_nCapacity) {
throw ENoSuchPosition();
} else {
return m_pTable[pos.m_nIndex];
}
}

SimNode<TYPE>& operator[](int nIndex)
{
if (nIndex < 0 || nIndex >= m_nCapacity) {
throw ENoSuchPosition();
} else {
return m_pTable[nIndex];
}
}
};




/*
定义SimChainPos :模拟指针链表的位置类型
*/

template <class TYPE>
class SimChainPos {
friend class SimSpace<TYPE>;
friend class SimChain<TYPE>;

private:
int m_nIndex; // 该位置在SimSpace中的索引

public:
SimChainPos() { }

private:
SimChainPos(int nIndex) {
m_nIndex = nIndex;
}

public:
const SimChainPos<TYPE>& operator++() {
m_nIndex = SimChain<TYPE>::Space[m_nIndex].m_nNext;
return (*this);
}

const SimChainPos<TYPE>& operator++(int) {
m_nIndex = SimChain<TYPE>::Space[m_nIndex].m_nNext;
return (*this);
}

bool operator==(const SimChainPos<TYPE>& pos) {
return (m_nIndex == pos.m_nIndex);
}

bool operator!=(const SimChainPos<TYPE>& pos) {
return (m_nIndex != pos.m_nIndex);
}
};


/*
定义SimChain :模拟指针实现的链表
*/

template <class TYPE>
class SimChain: public List< TYPE, SimChainPos<TYPE> > {
friend class SimChainPos<TYPE>;
protected:
SimChainPos<TYPE> m_posHeader; // 头元素的位置
SimChainPos<TYPE> m_posLast; // 最后一个元素的位置
protected:
static SimSpace<TYPE> Space; // 模拟指针的可用空间表

public:

SimChain();

SimChain(const SimChain<TYPE> &L);

virtual ~SimChain();

SimChain<TYPE>& operator=(const SimChain<TYPE>& L);


/*
下面是List中定义的纯虚方法
*/

// 返回第一个元素的位置
SimChainPos<TYPE> First() const;

// 返回表尾的位置
SimChainPos<TYPE> End() const;

// 返回pos的下一个位置
SimChainPos<TYPE> Next(SimChainPos<TYPE> pos) const;

// 返回pos的前一个位置
SimChainPos<TYPE> Prev(SimChainPos<TYPE> pos) const;

// 返回索引为nIndex的元素的位置
SimChainPos<TYPE> PositionOf(int nIndex) const;

// 返回位置为pos的元素的引用
TYPE& ElementAt(SimChainPos<TYPE> pos) const;

// 删除位置为pos的元素,并将其值返回
TYPE Delete(SimChainPos<TYPE> pos);

// 将元素x加到表的最后
List< TYPE, SimChainPos<TYPE> >& Append(const TYPE& x);

// 在位置pos上插入元素x
List< TYPE, SimChainPos<TYPE> >& Insert(SimChainPos<TYPE> pos, const TYPE& x);

// 清空线性表
void Clear();
};


// 初始化SimChain<TYPE>的静态成员变量Space
template <class TYPE>
SimSpace<TYPE> SimChain<TYPE>::Space;



/*
实现 SimSpace
*/

template <class TYPE>
const int SimSpace<TYPE>::DEFAULT_CAPACITY = 10000;

template <class TYPE>
SimSpace<TYPE>::SimSpace(int Capacity)
{
m_nCapacity = Capacity;
m_pTable = new SimNode<TYPE>[Capacity];
for (int i = 0; i < m_nCapacity - 1; i++) {
m_pTable[i].m_nNext = i + 1;
}
m_pTable[Capacity-1].m_nNext = -1;
m_nFirst = 0;
}


template <class TYPE>
inline SimSpace<TYPE>::~SimSpace()
{
delete[] m_pTable;
}


template <class TYPE>
int SimSpace<TYPE>::Allocate()
{
if (m_nFirst == -1) {
throw EOutOfCapacity();
} else {
int i = m_nFirst;
m_nFirst = m_pTable[m_nFirst].m_nNext;
return i;
}
}


template <class TYPE>
void SimSpace<TYPE>::Dispose(int& i)
{
m_pTable[i].m_nNext = m_nFirst;
m_nFirst = i;
i = -1;
}


/*
实现 SimChain
*/


// 构造函数
template <class TYPE>
SimChain<TYPE>::SimChain()
{
m_nHeader = Space.Allocate(); // 分配一个头节点
m_nLastNode = m_nHeader;
m_nLength = 0;
}


// 拷贝构造函数
template <class TYPE>
SimChain<TYPE>::SimChain(const SimChain<TYPE> &L)
{
m_nHeader = Space.Allocate();
m_nLastNode = m_nHeader;
int i = Space[L.m_nHeader].m_nNext;
while (i > 0) {
Append(Space[i].m_data);
i = Space[i].m_nNext;
}
}

// 析构函数
template <class TYPE>
SimChain<TYPE>::~SimChain()
{
Clear();
Space.Dispose(m_nHeader);
}


// 重载赋值运算符
template <class TYPE>
SimChain<TYPE>& SimChain<TYPE>::operator=(const SimChain<TYPE>& L)
{
Clear();
int i = Space[L.m_nHeader].m_nNext;
while (i > 0) {
Append(Space[i].m_data);
i = Space[i].m_nNext;
}
}



// 返回第一个元素的位置
template <class TYPE>
inline SimChainPos<TYPE> SimChain<TYPE>::First() const
{
SimChainPos<TYPE> result(m_nHeader);
return result;
}


// 返回表尾的位置
template <class TYPE>
inline SimChainPos<TYPE> SimChain<TYPE>::End() const
{
SimChainPos<TYPE> result(m_nLastNode);
return result;
}


// 返回pos的下一个位置
template <class TYPE>
SimChainPos<TYPE> SimChain<TYPE>::Next(SimChainPos<TYPE> pos) const
{
return (pos++);
}


// 返回pos的前一个位置
template <class TYPE>
SimChainPos<TYPE> SimChain<TYPE>::Prev(SimChainPos<TYPE> pos) const
{
ValidatePosition(pos.m_nIndex);
SimChainPos<TYPE> result;
int i = m_nHeader;
while (Space.m_pTable[i].m_nNext > 0) {
if (Space.m_pTable[i].m_nNext == pos.m_nIndex) {
result.m_nIndex = i;
return result;
}
i = Space.m_pTable[i].m_nNext;
}
result.m_nIndex = m_nLastNode;
return result;
}



// 返回索引为nIndex的元素的位置
template <class TYPE>
SimChainPos<TYPE> SimChain<TYPE>::PositionOf(int nIndex) const
{
if (nIndex < 0 || nIndex >= m_nLength) {
throw EOutOfBounds();
} else {
SimChainPos<TYPE> result;
int i;
for (i = m_nHeader; (i != m_nLastNode) && (nIndex > 0); nIndex--) {
i = Space.m_pTable[i].m_nNext;
}
result.m_nIndex = i;
return result;
}
}


// 返回位置为pos的元素的引用
template <class TYPE>
TYPE& SimChain<TYPE>::ElementAt(SimChainPos<TYPE> pos) const
{
ValidatePosition(pos.m_nIndex);
int i = Space.m_pTable[pos.m_nIndex].m_nNext;
ValidatePosition(i);
return Space.m_pTable[i].m_data; // 注意这里每个元素的位置是该元素的前驱的指针
}


// 删除位置为pos的元素,并将其值返回
template <class TYPE>
TYPE SimChain<TYPE>::Delete(SimChainPos<TYPE> pos)
{
ValidatePosition(pos.m_nIndex);
int p = Space.m_pTable[pos.m_nIndex].m_nNext;
ValidatePosition(p);
TYPE result;
result = Space.m_pTable[p].m_data;
Space.m_pTable[pos.m_nIndex].m_nNext = Space.m_pTable[p].m_nNext;
if (p == m_nLastNode) {
m_nLastNode = pos.m_nIndex;
}
Space.Dispose(p);
m_nLength--;
return result;
}


// 将元素x加到表的最后
template <class TYPE>
List< TYPE, SimChainPos<TYPE> >& SimChain<TYPE>::Append(const TYPE& x)
{
int p = Space.Allocate();
Space.m_pTable[p].m_data = x;
Space.m_pTable[p].m_nNext = -1;
Space.m_pTable[m_nLastNode].m_nNext = p;
m_nLastNode = p;
m_nLength++;
return (*this);
}


// 在位置pos上插入元素x
template <class TYPE>
List< TYPE, SimChainPos<TYPE> >& SimChain<TYPE>::Insert(SimChainPos<TYPE> pos, const TYPE& x)
{
ValidatePosition(pos.m_nIndex);
int p = Space.Allocate();
Space.m_pTable[p].m_data = x;
Space.m_pTable[p].m_nNext = Space.m_pTable[pos.m_nIndex].m_nNext;
Space.m_pTable[pos.m_nIndex].m_nNext = p;
if (pos.m_nIndex == m_nLastNode) {
m_nLastNode = p;
}
m_nLength++;
return (*this);
}

// 清空线性表
template <class TYPE>
void SimChain<TYPE>::Clear()
{
if (m_nLength > 0) {
Space.m_pTable[m_nLastNode].m_nNext = Space.m_nFirst;
Space.m_nFirst = Space.m_pTable[m_nHeader].m_nNext;
Space.m_pTable[m_nHeader].m_nNext = -1;
m_nLastNode = m_nHeader;
m_nLength = 0;
}
}


} // namespace LDSA

#endif // define SimChain
#define LDSA_List

#include <iostream.h>

namespace LDSA {

//////////////////////////////////////////////
//
// 定义线性表抽象类 List
// TYPE —— 元素类型
// POS_TYPE —— 位置类型
//
// 注意:线性表的索引从0开始计数
//
//////////////////////////////////////////////

template <class TYPE, class POS_TYPE>
class List {
protected:
int m_nLength; // 表的长度

public:
typedef POS_TYPE pos_type; // 位置类型

virtual ~List() {} // virtual destructor

//////////////////////////////////////
// 以下为线性表的基本运算
//////////////////////////////////////

int Length() const; // 返回表的长度

bool IsEmpty() const; // 判断表是否为空

virtual POS_TYPE First() const = 0; // 返回第一个元素的位置

virtual POS_TYPE End() const = 0; // 返回表尾的位置

virtual POS_TYPE Next(POS_TYPE pos) const = 0; // 返回pos的下一个位置

virtual POS_TYPE Prev(POS_TYPE pos) const = 0; // 返回pos的前一个位置

virtual POS_TYPE PositionOf(int nIndex) const = 0; // 返回索引为nIndex的元素的位置

virtual TYPE& ElementAt(POS_TYPE pos) const = 0; // 返回位置为pos的元素的引用

virtual TYPE Delete(POS_TYPE pos) = 0; // 删除位置为pos的元素,并将其值返回

// 将元素x加到表的最后
virtual List<TYPE, POS_TYPE>& Append(const TYPE& x) = 0;

// 在位置pos上插入元素x
virtual List<TYPE, POS_TYPE>& Insert(POS_TYPE pos, const TYPE& x) = 0;

// 清空线性表
virtual void Clear() = 0;

//////////////////////////////////////
// 以下为线性表的扩展运算
//////////////////////////////////////

TYPE& Item(int nIndex) const; // 返回索引为nIndex的元素的引用

POS_TYPE Find(const TYPE& x) const; // 找到元素x在表中的位置,如果不存在返回List::End()

int IndexOf(const TYPE& x) const; // 返回元素x的在表中的索引,如果x不存在返回-1

TYPE& operator[](POS_TYPE pos) const; // 重载[]操作符以便直接根据下标访问线性表的元素

};

//////////////////////////////////////////////
//
// 实现类 CList
//
//////////////////////////////////////////////

template <class TYPE, class POS_TYPE>
inline int List<TYPE, POS_TYPE>::Length() const // 返回线性表的长度
{
return m_nLength;
}

template <class TYPE, class POS_TYPE>
inline bool List<TYPE, POS_TYPE>::IsEmpty() const // 判断线性表是否为空
{
return (m_nLength == 0);
}

template <class TYPE, class POS_TYPE>
TYPE& List<TYPE, POS_TYPE>::Item(int nIndex) const // 返回索引为nIndex的元素的引用
{
List<TElement, TPosition>::pos_type pos;
pos = PositionAt(nIndex);
return ElementAt(pos);
}

// 找到元素x在表中的位置,如果不存在返回List::End()
template <class TYPE, class POS_TYPE>
POS_TYPE List<TYPE, POS_TYPE>::Find(const TYPE& x) const
{
List<TYPE, POS_TYPE>::pos_type pos;
for (pos = First(); pos != End(); pos++) {
if (ElementAt(pos) == x) break;
}
return pos;
}

// 返回元素x的在表中的索引,如果x不存在返回-1
template <class TYPE, class POS_TYPE>
int List<TYPE, POS_TYPE>::IndexOf(const TYPE& x) const
{
int nIndex = 0;
List<TYPE, POS_TYPE>::pos_type pos;
for (pos = First(); pos != End(); pos++) {
if (ElementAt(pos) == x) return nIndex;
nIndex++;
}
return -1;
}

// 重载[]操作符以便直接根据下标访问线性表的元素
template <class TYPE, class POS_TYPE>
inline TYPE& List<TYPE, POS_TYPE>::operator[](POS_TYPE pos) const
{
return ElementAt(pos);
}

// 复制线性表
template <class T, class P1, class P2>
List<T, P2>& Clone(const List<T, P1>& src, List<T, P2>& des)
{
des.Clear();
P1 pos;
for (pos = src.First(); pos != src.End(); pos++) {
des.Append(src[pos]);
}
return des;
}

}; // namespace LDSA


// 重载 << 运算符,以便可以直接使用 out << L 来输出线性表的元素
template <class TYPE, class POS_TYPE>
ostream& operator<<(ostream& out, LDSA::List<TYPE, POS_TYPE>& L)
{
POS_TYPE pos;
for (pos = L.First(); pos != L.End(); pos++) {
out << L[pos] << ' ';
}
return out;
}


#endif // #ifndef LDSA_List
linhf 2001-12-10
  • 打赏
  • 举报
回复
如何用游标实现表?

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧