#include <iostream>
#include <string>
using namespace std;
//默认情况下动态数组的长度为2
template <class DataType>
class Array
{
public:
Array(int size = 2);
Array(const Array<DataType> ©);
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> ©)
{
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> ©);
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> ©)
{
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 ©); //复制构造函数
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 ©) //复制构造函数
{
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;
}