「数据结构」: 间接寻址

  间接寻址(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*类型空间。容易遗忘。

你可能感兴趣的:(数据结构)