间接寻址(indirect addressing)是公式化描述和链表描述的组合。采用这种方法,可以保留公式化描述方法的许多优点,在单位时间内访问每个元素,可采用二叉搜索方法在对数时间内对一个有序表进行搜索等等。与此同时,也可以获得链表描述方法的重要特色---在诸如插入和删除操作期间不必对元素进行实际的移动。因些,大多数间接寻址链表操作的时间复杂度都有元素的总数无关。
说到底,间接寻址只是一个每链只有一个节点的邻接矩阵。实现起来简单方便,兼具顺序表与链表的优点。
本次程序采用仍使用C++语言实现,为保证通用性使用模板机制。
程序结构:
1、IndirectAddr.h
2、excp.h
3、IndirectAddr.cpp
/*IndirectAddr.h*/
#ifndef __INDIRECTADDR__
#define __INDIRECTADDR__
#include "excp.h"
#include <iostream>
using namespace std;
template<class T>
class IndirectAddr {
public:
IndirectAddr(int maxaSize = 10);
~IndirectAddr();
bool isEmpty() const {return length == 0;}
int getLength() const {return length;}
bool findElement(int k, T& x) const;
int searchElement(const T& x) const;
IndirectAddr<T>& deleteElement(int k, T& x);
IndirectAddr<T>& insertElement(int k, const T& x);
void output(ostream& out) const;
private:
T **table;
int length;
int maxSize;
};
template<class T>
IndirectAddr<T>::IndirectAddr(int maxaSize)
{
maxSize = maxaSize;
length = 0;
table = new T *[maxSize];
}
template<class T>
IndirectAddr<T>::~IndirectAddr()
{
for (int i = 0; i < length; i++)
delete table[i];
delete [] table;
}
template<class T>
bool IndirectAddr<T>::findElement(int k, T& x) const
{
if (k<1 || k>length)
return false;
x = *table[k-1];
return true;
}
template<class T>
int IndirectAddr<T>::searchElement(const T& x) const
{
for (int i=0; i<length; i++)
if (*table[i] == x)
return i+1;
return 0;
}
template<class T>
IndirectAddr<T>& IndirectAddr<T>::deleteElement(int k, T& x)
{
if (findElement(k, x))
{
for (int i=k; i<length; i++)
table[i-1] = table[i];
length--;
return *this;
}
else
throw OutOfBounds();
}
template<class T>
IndirectAddr<T>& IndirectAddr<T>::insertElement(int k, const T& x)
{
if (k<1 || k>length+1)
throw OutOfBounds();
if (length == maxSize)
throw FullMemory();
for (int i=length-1; i>=k-1; i--)
table[i+1] = table[i];
table[k-1] = new T;
*table[k-1] = x;
length++;
return *this;
}
template<class T>
void IndirectAddr<T>::output(ostream& out) const
{
for(int i=0; i<length; i++)
out<<*table[i]<<" ";
out<<endl;
}
template<class T>
ostream& operator<<(ostream& out, IndirectAddr<T>& x)
{
x.output(out);
return out;
}
#endif
/*excp.h*/
#ifndef _EXCP_
#define _EXCP_
#include <new>
using namespace std;
class OutOfBounds {
public:
OutOfBounds(){}
};
class FullMemory {
public:
FullMemory(){}
};
void my_new_handler()
{
throw FullMemory();
}
new_handler old_handler = set_new_handler(my_new_handler);
#endif
/*IndirectAddr.cpp*/
#include <iostream>
#include "IndirectAddr.h"
#include "excp.h"
using namespace std;
int main()
{
try{
IndirectAddr<int> L;
cout<<"Length = "<<L.getLength()<<endl;
cout<<"IsEmpty = "<<L.isEmpty()<<endl;
L.insertElement(1 ,2).insertElement(2, 6).insertElement(2, 3).
insertElement(3, 6);
cout<<"List is "<<L<<endl;
cout<<"IsEmpty ="<<L.isEmpty()<<endl;
int c;
L.findElement(1, c);
cout<<"First element is "<<c<<endl;
cout<<"Length = "<<L.getLength()<<endl;
L.deleteElement(3, c);
cout<<"Delete element is "<<c<<endl;
cout<<"List is "<<L<<endl;
}
catch(...)
{
cerr<<"This is a error"<<endl;
}
return 0;
}
总结:
注意在使用table表内指针之前要先初始化,即分配一个T*类型空间。容易遗忘。