社区
数据结构与算法
帖子详情
如何有游标实现表?
linhf
2001-12-10 05:43:55
...全文
69
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
打赏
举报
回复
如何用游标实现表?
约瑟夫问题的
游标
实现
约瑟夫问题的
游标
实现
,可以自己设置杀人的个数
通过使用
游标
实现
批量更新
表
中某个字段的值.sql
oracle 用SQL通过使用
游标
实现
批量更新
表
中某个字段的值
表
名和字段名需要修改,字符串的截取的方法需要根据实际情况修改
sql不用
游标
实现
逐行处理
sql不用
游标
实现
逐行处理 一个Insert语句一次插入3行到某个
表
中。触发器需要从Inserted
表
中读取每一行的主键送到另一个存储过程去处理。第一反应可能是使用
游标
循环遍历Inserted
表
读取主键然后调用存储过程。但在...
游标
.sql
游标
.sql
LabVIEW 的
游标
图例
游标
图例用来显示图形中的
游标
,如图1所示。在图形上用
游标
可读取绘图区域上某个点的确切值,游...右键单击单曲线
游标
图例,从弹出的快捷菜单中选择“关联至”,可将
游标
与一个或所有曲线
实现
关联。多曲线模式将
游标
数据结构与算法
33,028
社区成员
35,337
社区内容
发帖
与我相关
我的任务
数据结构与算法
数据结构与算法相关内容讨论专区
复制链接
扫一扫
分享
社区描述
数据结构与算法相关内容讨论专区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章