「数据结构」: 间接寻址
间接寻址(indirect addressing)是公式化描述和链表描述的组合。采用这种方法,可以保留公式化描述方法的许多优点,在单位时间内访问每个元素,可采用二叉搜索方法在对数时间内对一个有序表进行搜索等等。与此同时,也可以获得链表描述方法的重要特色---在诸如插入和删除操作期间不必对元素进行实际的移动。因些,大多数间接寻址链表操作的时间复杂度都有元素的总数无关。
说到底,间接寻址只是一个每链只有一个节点的邻接矩阵。实现起来简单方便,兼具顺序表与链表的优点。
本次程序采用仍使用C++语言实现,为保证通用性使用模板机制。
程序结构:
1、IndirectAddr.h
2、excp.h
3、IndirectAddr.cpp
1 /*IndirectAddr.h*/ 2 #ifndef __INDIRECTADDR__ 3 #define __INDIRECTADDR__ 4 #include "excp.h" 5 #include <iostream> 6 using namespace std; 7 template<class T> 8 class IndirectAddr { 9 public: 10 IndirectAddr(int maxaSize = 10); 11 ~IndirectAddr(); 12 bool isEmpty() const {return length == 0;} 13 int getLength() const {return length;} 14 bool findElement(int k, T& x) const; 15 int searchElement(const T& x) const; 16 IndirectAddr<T>& deleteElement(int k, T& x); 17 IndirectAddr<T>& insertElement(int k, const T& x); 18 void output(ostream& out) const; 19 private: 20 T **table; 21 int length; 22 int maxSize; 23 }; 24 25 template<class T> 26 IndirectAddr<T>::IndirectAddr(int maxaSize) 27 { 28 maxSize = maxaSize; 29 length = 0; 30 table = new T *[maxSize]; 31 } 32 33 template<class T> 34 IndirectAddr<T>::~IndirectAddr() 35 { 36 for (int i = 0; i < length; i++) 37 delete table[i]; 38 delete [] table; 39 } 40 41 template<class T> 42 bool IndirectAddr<T>::findElement(int k, T& x) const 43 { 44 if (k<1 || k>length) 45 return false; 46 x = *table[k-1]; 47 return true; 48 } 49 50 template<class T> 51 int IndirectAddr<T>::searchElement(const T& x) const 52 { 53 for (int i=0; i<length; i++) 54 if (*table[i] == x) 55 return i+1; 56 return 0; 57 } 58 59 template<class T> 60 IndirectAddr<T>& IndirectAddr<T>::deleteElement(int k, T& x) 61 { 62 if (findElement(k, x)) 63 { 64 for (int i=k; i<length; i++) 65 table[i-1] = table[i]; 66 length--; 67 return *this; 68 } 69 else 70 throw OutOfBounds(); 71 } 72 73 template<class T> 74 IndirectAddr<T>& IndirectAddr<T>::insertElement(int k, const T& x) 75 { 76 if (k<1 || k>length+1) 77 throw OutOfBounds(); 78 if (length == maxSize) 79 throw FullMemory(); 80 for (int i=length-1; i>=k-1; i--) 81 table[i+1] = table[i]; 82 table[k-1] = new T; 83 *table[k-1] = x; 84 length++; 85 return *this; 86 } 87 88 template<class T> 89 void IndirectAddr<T>::output(ostream& out) const 90 { 91 for(int i=0; i<length; i++) 92 out<<*table[i]<<" "; 93 out<<endl; 94 } 95 96 template<class T> 97 ostream& operator<<(ostream& out, IndirectAddr<T>& x) 98 { 99 x.output(out); 100 return out; 101 } 102 #endif
1 /*excp.h*/ 2 #ifndef _EXCP_ 3 #define _EXCP_ 4 #include <new> 5 using namespace std; 6 7 class OutOfBounds { 8 public: 9 OutOfBounds(){} 10 }; 11 12 class FullMemory { 13 public: 14 FullMemory(){} 15 }; 16 17 void my_new_handler() 18 { 19 throw FullMemory(); 20 } 21 22 new_handler old_handler = set_new_handler(my_new_handler); 23 #endif
1 /*IndirectAddr.cpp*/ 2 #include <iostream> 3 #include "IndirectAddr.h" 4 #include "excp.h" 5 using namespace std; 6 int main() 7 { 8 try{ 9 IndirectAddr<int> L; 10 cout<<"Length = "<<L.getLength()<<endl; 11 cout<<"IsEmpty = "<<L.isEmpty()<<endl; 12 L.insertElement(1 ,2).insertElement(2, 6).insertElement(2, 3). 13 insertElement(3, 6); 14 cout<<"List is "<<L<<endl; 15 cout<<"IsEmpty ="<<L.isEmpty()<<endl; 16 int c; 17 L.findElement(1, c); 18 cout<<"First element is "<<c<<endl; 19 cout<<"Length = "<<L.getLength()<<endl; 20 L.deleteElement(3, c); 21 cout<<"Delete element is "<<c<<endl; 22 cout<<"List is "<<L<<endl; 23 } 24 catch(...) 25 { 26 cerr<<"This is a error"<<endl; 27 } 28 return 0; 29 }
总结:
注意在使用table表内指针之前要先初始化,即分配一个T*类型空间。容易遗忘。