内嵌散列表的双链表

 

 

#include <iostream>
#include <string>
using namespace std;

//默认情况下动态数组的长度为2

template <class DataType>
class Array
{
public:
 Array(int size = 2);
 Array(const Array<DataType> &copy);
 Array<DataType>& operator=(const Array<DataType> &right);
 ~Array();
 DataType &operator[](int index);
 void ChangeSize(int size);
 int GetSize()const;
private:
 inline void DeepCopy(const Array<DataType> &origin);
 DataType *element;
 int capacity;
};

template< class DataType>
Array<DataType>::Array(int size)
{
 if(size < 1)
 {
       capacity = 2;
 }
 else
 {
  capacity = size;
 }
 element = new DataType[size];
}

template <class DataType>
Array<DataType>::Array(const Array<DataType> &copy)
{
 DeepCopy(copy);
}

template <class DataType>
Array<DataType>& Array<DataType>::operator=(const Array<DataType> &right)
{
 if(this == &right)
 {
  return *this;
 }
 delete []element;
 DeepCopy(right);
 return *this;
}

template <class DataType>

Array<DataType>::~Array()
{
 delete []element;
}

template < class DataType>
DataType& Array<DataType>::operator[](int index)
{

 return element[index];
}

template <class DataType>
void Array<DataType>::ChangeSize(int size)
{
 if((size<1) || (size==capacity))
 {
  return;
 }
 DataType *newelement = new DataType[size];
 int limit = (size>capacity) ? capacity : size;
 for(int i=0; i<limit; i++)
 {
  newelement[i] = element[i];
 }
 delete []element;
 element = newelement;
 capacity = size;
}

template<class DataType>
inline void Array<DataType>::DeepCopy(const Array<DataType> &origin)
{
 capacity = origin.capacity;
 for(int i=0; i<capacity; i++)
 {
  element[i] = origin.element[i];
 }
}

template<class DataType>
int Array<DataType>::GetSize()const
{
 return capacity;
}

//列表类。
//对先前的结点进行修改
template <class DataType>
struct Node
{
 DataType info;
 Node<DataType> *next;
 Node<DataType> *dlnext;
 Node<DataType> *dlback;
};

template <class DataType>
class LinkedList
{
public:
 LinkedList();
 ~LinkedList();
 LinkedList(const LinkedList<DataType> &copy);
 LinkedList<DataType>& operator=(const LinkedList<DataType> &right);
 void Insert(const DataType &element);
 bool Remove(DataType &element);
 bool Retrieve(DataType &element);
 bool Find(const DataType &element);
 bool Replace(const DataType &element);
 bool IsEmpty()const;
 void MakeEmpty();
 Node<DataType> *GetCurrent() const;     //配合双链表得到当前插入位置。

private:
 inline bool first(DataType &element);
 inline bool getNext(DataType &element);
 inline void DeepCopy(const LinkedList<DataType> &origin);
 Node<DataType> *header;
    Node<DataType> *current;
};


template <class DataType>
LinkedList<DataType>::LinkedList()
{
 header = NULL;
}

template <class DataType>
LinkedList<DataType>::~LinkedList()
{
 MakeEmpty();
}

template <class DataType>
LinkedList<DataType>::LinkedList(const LinkedList<DataType> &copy)
{
 DeepCopy(copy);
}

template <class DataType>
LinkedList<DataType>& LinkedList<DataType>::operator=(const LinkedList<DataType> &right)
{
 if(&right == this)
 {
  return *this;
 }
 MakeEmpty();
 DeepCopy(right);
 return *this;
}


//对先前的列表类进行修改
//增加一个GetCurrent()函数,得到当前插入结点的位置
template <class DataType>
Node<DataType> *LinkedList<DataType>::GetCurrent() const
{
 return current;
}

template <class DataType>
void LinkedList<DataType>::Insert(const DataType &element)
{
 if(NULL == header)
 {
  header = new Node<DataType>;
  header->info = element;
  header->next = NULL;   //NULL结束标记就像字符串里的/0一样很重要。
  current = header;          //在插入操作后current值不为NULL,而是指向新结点
  return;
 }
 Node<DataType> *temp = new Node<DataType>;
 temp->info = element;
 temp->next = header;
 header = temp;
 current = header;     //需要将current 指向当前插入位置。。。
}

template <class DataType>
bool LinkedList<DataType>::Remove(DataType &element)
{
 current = NULL;
 Node<DataType> *temp = header;
 if(header->info == element)
 {
  header = header->next;
  element = temp->info;
  delete temp;
  return true;
 }
 while(temp->next != NULL)
 {
  if(temp->next->info == element)
  {
   Node<DataType> *del = temp->next;
   element = del->info;
   temp->next = del->next;
   delete del;
   return true;
  }
  temp = temp->next;
 }
 return false;
}

template <class DataType>
bool LinkedList<DataType>::Retrieve(DataType &element)
{
 if(!Find(element))
 {
  return false;
 }
 element = current->info;
 return true;
}

template <class DataType>
bool LinkedList<DataType>::Find(const DataType &element)
{
 DataType temp;
 if(!first(temp))
 {
          return false;
 }
 do
 {
  if(temp == element)
  {
          return true;
  }
 } while (getNext(temp));
          return false;
}
template <class DataType>

bool LinkedList<DataType>::Replace(const DataType &element)
{
 if(NULL == current)
 {
       return false;
 }
 current->info = element;
       return true;
}

template <class DataType>
bool LinkedList<DataType>::IsEmpty()const
{
       return NULL == header;
}

template <class DataType>

void LinkedList<DataType>::MakeEmpty()
{
 while(NULL != header)
 {
  current = header;
  header = header->next;
  delete current;
 }
 current = NULL;
}

template <class DataType>
inline bool LinkedList<DataType>::first(DataType &element)
{
 if(NULL == header)
 {
      current = NULL;
      return false;
 }
 current = header;
 element = current->info;
 return true;
}

template <class DataType>
inline bool LinkedList<DataType>::getNext(DataType &element)
{
 if(NULL == current)
 {
     return false;
 }
 if(NULL == current->next)
 {
     current = NULL;
     return false;
 }
 current = current->next;
 element = current->info;
 return true;
}

template <class DataType>
inline void LinkedList<DataType>::DeepCopy(const LinkedList<DataType> &origin)
{
 header = current = NULL;
 if(NULL == origin.header)
 {
  return;
 }
 header = origin.header;
 header->info = origin.header->info;
 if(origin.header->info == origin.current)
 {
  current = header;
 }
 Node<DataType> *copy = header;
 Node<DataType> *originptr = origin.header;
 while(originptr->next != NULL)
 {
  originptr = originptr->next;
  copy->next = new Node<DataType>;
  copy = copy->next;
  copy->info = originptr->info;
  if(originptr == origin.current)
  {
   current = copy;
  }
 }
 header->next = NULL;
}

 

//散列表(hashtable)

template <class DataType>
class HashTable
{
public:
 HashTable(int (*pFunc)(const DataType &), int size);
 bool Insert(const DataType &element);
 bool Retrieve(DataType &element);
 bool Remove(DataType &element);
 void MakeEmpty();
 int GetSize() const;
 int (*GetHashFuc() const)(const DataType &element);                                      //返回函数指针
 void SetHashFuc(int (*pfunc)(const DataType &element));
 void ChangeSize(int size);
 Node<DataType> *GetCurrent();
private:
 int position;        
 Array< LinkedList<DataType> > array;    //动态数组内嵌单链表
 int (*hashfunc)(const DataType &element);   //散列函数应由主程序员自己生成,所以用一个函数指针。
};

template <class DataType>
void HashTable<DataType>::MakeEmpty()
{
 int nLimit = array.GetSize();
 for(int i=0; i<nLimit; i++)
 {
  array[i].MakeEmpty();
 }

}


template <class DataType>
void HashTable<DataType>::ChangeSize(int size)
{
 array.ChangeSize(size);
}

 

template <class DataType>
int (*HashTable<DataType>::GetHashFuc() const)(const DataType &element)    
{
 return hashfunc;
}

 

template <class DataType>
void HashTable<DataType>::SetHashFuc(int (*pfunc)(const DataType &element))
{
 hashfunc = pfunc;
}

 

template <class DataType>        
Node<DataType> *HashTable<DataType>::GetCurrent()
{
 return array[position].GetCurrent();  //array不能是一个左值。
}

 

template <class DataType>
HashTable<DataType>::HashTable(int (*pFunc)(const DataType &), int size)
:array(size)
{
 hashfunc = pFunc;
}

 

template <class DataType>
int HashTable<DataType>::GetSize() const
{
 return array.GetSize();
}

 

template <class DataType>
bool HashTable<DataType>::Insert(const DataType &element)
{
 position = hashfunc(element);
 if((position<0) || (position>=array.GetSize()))
 {
  return false;
 }
 array[position].Insert(element);
 return true;
}

 

template <class DataType>
bool HashTable<DataType>::Retrieve(DataType &element)
{
 position = hashfunc(element);
 if((position<0) || (position>=array.GetSize()))
 {
  return false;
 }
 if(!array[position].Retrieve(element))
 {
  return false;
 }
 return true;
}

 

template <class DataType>
bool HashTable<DataType>::Remove(DataType &element)
{
 position = hashfunc(element);
 if((position<0) || (position>=array.GetSize()))
 {
  return false;
 }
 if(!array[i].Remove(element))
 {
  return false;
 }
 return true;
}

 

//内嵌散列表的双链表,一个很重要的数据结构。

template <class DataType>
class DoublyLinkedList
{
public:
 DoublyLinkedList(int(*pFunc)(const DataType &element), int size);
 ~DoublyLinkedList();
 DoublyLinkedList(const DoublyLinkedList &copy);    //复制构造函数
 DoublyLinkedList<DataType> &operator=(const DoublyLinkedList<DataType> &right);
 bool Insert(const DataType &element);
 bool Find(const DataType &element);
 bool Retrieve(DataType &element);
 bool Remove(DataType &element);
 bool Replace(const DataType &element);
 void MakeEmpty();
 bool IsEmpty() const;
private:
 inline void DeepCopy(const DoublyLinkedList<DataType> &origin);
 Node<DataType> *header;
 Node<DataType> *trailer;
 Node<DataType> *current;
 HashTable<DataType> hashtable;
 Node<DataType> headerNode;
 Node<DataType> trailerNode;
};

 

template <class DataType>
DoublyLinkedList<DataType>::DoublyLinkedList(int(*pFunc)(const DataType &element), int size)
:hashtable(pFunc, size)
{
 header = &headerNode;
 trailer = &trailerNode;
 header->dlnext = trailer;
 trailer->dlback = header;
 current = trailer;                                                         //没有当前位置current批向尾结点,符全思路。
}

 

template <class DataType>
DoublyLinkedList<DataType>::~DoublyLinkedList()
{
      MakeEmpty();
}

 

template <class DataType>
DoublyLinkedList<DataType>::DoublyLinkedList(const DoublyLinkedList &copy)    //复制构造函数
{
     DeepCopy(copy);
}

 

template <class DataType>
DoublyLinkedList<DataType> &DoublyLinkedList<DataType>::operator=(const DoublyLinkedList<DataType> &right)
{
 if(&right == this)
 {
  return *this;
 }
 MakeEmpty();
 DeepCopy(right);
 return *this;
}

 

template<class DataType>
bool DoublyLinkedList<DataType>::Insert(const DataType &element)
{
 if(!hashtable.Insert(element))
 {
  return false;
 }
 current = hashtable.GetCurrent();
 current->dlnext = header->dlnext;
 current->dlback = header;
 header->dlnext->dlback = current;
 header->dlnext = current;
 current = trailer;                                                              //每个新插入的结点做为新结点,插入后没有当前位置
 return true;
}

 

template <class DataType>
bool DoublyLinkedList<DataType>::Find(const DataType &element)
{
 DataType temp = element;
 if(!hashtable.Retrieve(temp))
 {
  current = trailer;
  return false;
 }
 current = hashtable.GetCurrent();
 return true;
}

 

template <class DataType>
bool DoublyLinkedList<DataType>::Retrieve(DataType &element)
{
 if(!hashtable.Retrieve(element))
 {
  current = trailer;
  return false;
 }
 current = hashtable.GetCurrent();
 return true;
}

 

template <class DataType>
bool DoublyLinkedList<DataType>::Remove(DataType &element)
{
 if(!hashtable.Retrieve(element))
 {
  return false;
 }
 current = hashtable.GetCurrent();
 current->dlback->dlnext = current->dlnext;
 current->dlnext->dlback = current->dlback;
 hashtable.Remove(element);                                                               //保证安全,删除操作应该在最后完成。
 current = trailer;
 return true;
}

 

template <class DataType>
bool DoublyLinkedList<DataType>::Replace(const DataType &element)
{
 if(trailer == current)                                             //敲过几次后,发现还是有规律可寻的。和上面的列表类对比一下就能发现共同点
 {
       return false;
 }
 current->info = element;
 return true;
}

template <class DataType>
void DoublyLinkedList<DataType>::MakeEmpty()
{
 hashtable.MakeEmpty();
 current = trailer;
 header->dlnext = trailer;
 trailer->dlback = current;
}

 

template <class DataType>
bool DoublyLinkedList<DataType>::IsEmpty() const
{
 return header->dlnext == trailer;                           //外形上是一个双链表
}

 

//深复制函数
//在构造函数和重载赋值运算符中使用

//所以要对可能两方面的使用都做一些物殊处理

//

template <class DataType>
void DoublyLinkedList<DataType>::DeepCopy(const DoublyLinkedList<DataType>& origin)
{

//在复制构造函数中使用时,保证左右对象的数组容量相同。
 if(hashtable.GetSize() != origin.hashtable.GetSize())                           //保证动态数组大小和右操作数大小相同。
 {                                                                                                           //
   hashtable.ChangeSize(origin.hashtable.GetSize());
 }
 hashtable.SetHashFuc(origin.hashtable.GetHashFuc());   //设置散列函数

//实现构造函数功能
 header = &headerNode;
 trailer = &trailerNode;
 header->dlnext = trailer;
 trailer->dlback = header;
 current = trailer;
 Node<DataType> *SaveCurrent = NULL;
 Node<DataType> *originptr = origin.trailer->dlback;
 while(originptr->dlback != origin.header)
 {
  originptr = originptr->dlback;
  Insert(originptr);
  if(originptr == origin.current)
  {
   SaveCurrent = header->dlnext;                                                    

  }
 }
 current = SaveCurrent;           
}


// template<class DataType>
// void  HashTable<DataType>::MakeEmpty()
// {
//  int nLen = array.GetSize();
//  for(int i=0; i<nLen; i++)
//  {
//   array[i].MakeEmpty();
//  }
// }
//
struct MyStruct    
{  
    string str;  
    int num;  
    bool operator==(const MyStruct & r);
 friend ostream& operator<<(ostream &out, const MyStruct &right);
};  

ostream& operator<<(ostream &out, const MyStruct &right)
{
 out<<"Name is: "<<right.str<<endl;
 out<<" age is: "<<right.num<<endl;
 out<<endl;
 return  out;
}
bool MyStruct::operator==(const MyStruct & r)
{
 return str == r.str;
}
const int SIZE1=97,SIZE2=199;
int hash1(const MyStruct & obj);  

int hash2(const MyStruct & obj);  
int  main()  
{  
 DoublyLinkedList<MyStruct> list(hash1, SIZE1);
 MyStruct stu;
 stu.str = "zhaozigeng";
 stu.num = 26;

 MyStruct stu2;
 stu2.str ="yujingkun";
 stu2.num = 24; 
 list.Insert(stu);
 list.Insert(stu2);

 MyStruct stu3;
 stu3.str = "yujingkun";
 list.Retrieve(stu3);
 cout<<stu3;
   
 stu3.num = 2000;
 list.Replace(stu3);
 cout<<stu3;

    return 0; 
}  


int hash1(const MyStruct & obj)  
{  
    int sum=0;  
    for (int i=0;i<3 && i<int(obj.str.length());i++)  
    {  
        sum+=obj.str[i];  
    }  
    return sum % SIZE1;  
}  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值