「数据结构」: 间接寻址

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

posted @ 2014-02-26 13:35  sangoly  阅读(1100)  评论(0编辑  收藏  举报