温存温存8

一、实验目的
1、掌握散列表结构的定义和实现。
2、掌握散列表结构的应用。
二、实验内容
1、题目描述:
给定散列函数的除数D和操作数m,输出每次操作后的状态。
有以下三种操作:
插入x,若散列表已存在x,输出“Existed”,否则插入x到散列表中,输出所在的下标。
查询x,若散列表不含有x,输出“-1”,否则输出x对应下标。
删除x,若散列表不含有x,输出“Not Found”,否则输出删除x过程中移动元素的个数。
输入输出格式:
输入:
第一行两个整数D,m。分别代表散列函数的除数D和操作数m。
接下来m行,每行两个整数opt和x,分别代表操作类型和操作数。
若opt为0,代表插入x;
若opt为1,代表查询x;
若opt为2,代表删除x。
输出:
按需输出。
2、题目描述:
给定散列函数的除数D和操作数m,输出每次操作后的状态。
有以下三种操作:
插入x,若散列表已存在x,输出"Existed";
查询x,若散列表不含有x,输出"Not Found",否则输出x所在的链表长度;
删除x,若散列表不含有x,输出"Delete Failed",否则输出x所在链表删除x后的长度;
输入输出格式:
输入:
第一行两个整数D(1<=D<=3000)和m(1<=m<=3000),其中D为散列函数的除数,m为操作数。
接下来的m行,每行两个整数opt和x,分别代表操作类型和操作数。
若opt为0,则代表向散列表中插入x;
若opt为1,代表查询散列表中x是否存在;
若opt为2,(如果散列表中含有x),删除x。
输出:
按需输出。

#include<iostream>
#include<string> 
using namespace std;
template<class K>
class Hash; 
template<>
class Hash<int>{
    
    //将theKey映射,方法为其本身 
	public:
    	size_t operator()(const int theKey) const{
    
    
        	return size_t(theKey);
    }
};
template<class K,class E>
class HashTable{
    
    
	private:
		pair<const K,E>** table;//散列表
		Hash<K> hash;//把类型K映射到一个整数
		int dSize;//字典中数对个数
		int divisor;//散列函数除数 
	protected:
		int search(const K& theKey) const;
	public:
		HashTable(int theDivisor=10);
		~HashTable(){
    
    delete []table;}
		void find(const K& theKey) const;
		void insert(const pair<const K, E>&thePair);
		void erase(K& theKey);
};
template<class K,class E>
HashTable<K,E>::HashTable(int theDivisor){
    
    
	divisor=theDivisor;
	dSize=0;
	table=new pair<const K,E>*[divisor];
	for(int i=0;i<divisor;i++){
    
    
		table[i]=NULL;
	}
}
template<class K,class E>
int HashTable<K,E>::search(const K& theKey)const{
    
    
	//查找关键字为theKey的数对 
	//如果存在返回它的位置或则可以插入theKey的位置 
	int i=(int)hash(theKey)%divisor;//起始桶 
	int j=i;                        //从起始桶开始 
	do{
    
    
		if(table[j]==NULL||table[j]->first==theKey)//标识 
			return j;//返回位置或可以插入的位置 
		j=(j+1)%divisor;//找到了,但标识不同,只能放下一个桶 
	}while(j!=i);//判断是否已经回到起始桶 
	return j; //表满了 
}
template<class K,class E>
void HashTable<K, E>::find(const K& theKey) const{
    
    
	//返回匹配数对的指针。不存在则返回NULL
	int b=search(theKey);
	if(table[b]==NULL||table[b]->first!=theKey){
    
    //判断table是否匹配数对 
		cout<<-1<<endl; 
		return ;
	}//没找到 
	cout<<b<<endl;//找到匹配数对 
	return ;
} 
template<class K,class E>
void HashTable<K,E>::insert(const pair<const K, E>&thePair){
    
    
	int b=search(thePair.first);
	if(table[b]==NULL){
    
    //没匹配到数对,且表未满 
		table[b]=new pair<const K,E>(thePair);
		dSize++;
		cout<<b<<endl;//输出散列表下标 
	}else{
    
    
		if(table[b]->first==thePair.first){
    
    //有标识一样的的数对, 
			cout<<"Existed"<<endl;
		}
	}
}
template<class K,class E>
void HashTable<K,E>::erase(K& theKey){
    
    
	int b=search(theKey);
	if(table[b]==NULL||table[b]->first!=theKey)
		cout<<"Not Found"<<endl;
	else{
    
    //返回删掉这个元素之后,其他何其相同关键字元素填充进去 
		table[b] = NULL;
        int flag=0;//移动元素的个数 
        int position=b;//循环定位的位置 
		int waitinsert=b;//等待其他元素到来的空位置 
		int signal;//判断是不是被排挤的非这个下标的元素,例如0却在1位。 
        do{
    
    
            position = (position + 1) % divisor;//当前定位的位置 
            if (table[position] == NULL)
                break;
            signal = table[position]->first % divisor;//这个元素本该有的下标 
            if ((signal <= waitinsert &&waitinsert < position)
			|| (signal <=waitinsert && position < signal)
			|| (position < signal && waitinsert < position)){
    
    
                table[waitinsert] = table[position];
                table[position] = NULL;
                waitinsert = position;
                flag++;
            }
        } while(table[(position+ 1) % divisor]!= NULL&& position!= b);//不为空且未返回到原位置 
        cout << flag << endl;
	}
}
int main(){
    
    
	int D, m;
    cin>>D;cin>>m;
    HashTable<int, int> hashtable(D);
    pair<int, int> q;
    for (int i=0;i < m; i++) {
    
    
        int op,number;
        cin>>op;cin>>number;
        if (op==0){
    
    
            q.first = number; q.second = number;
            hashtable.insert(q);
        }
        else if(op==1){
    
    
            q.first = number; q.second = number;
            hashtable.find(q.first);
        }
        else{
    
    
            q.first=number;q.second=number;
            hashtable.erase(q.first);
        }
    }
    return 0;				  
}				  
#include<iostream>
using namespace std;
template<class K,class E>
struct pairNode{
    
    //节点结构 
	typedef pair<const K,E> pairType;//为pair<const K,E>起个别名
	pairType element;
	pairNode<K,E> *next;
	//构造节点 
	pairNode(const pairType& thePair):element(thePair){
    
    }//记得要用这种形式的,否则报错 
	pairNode(const pairType& thePair,pairNode<K,E>*theNext):element(thePair){
    
    //更新 
		this->next=theNext; 
	}
};
template<class K,class E>
class SortChain{
    
    
	private:
		pairNode<K,E>*firstNode;//指向第一个节点的指针 
		int dSize;//链表的数对个数
	public: 
	SortChain():firstNode(NULL),dSize(0){
    
    }
	~SortChain();
	void insert(const pair< K,E>& thePair);
	void find(const K&theKey)const;//pair<const K,E>*是一种类型 
	void erase(const K&theKey);
	int size() const {
    
    return dSize;}
};
template<class K,class E>
SortChain<K,E>::~SortChain(){
    
    
	pairNode<K,E>*nextNode;
	while(firstNode!=NULL){
    
    
		nextNode=firstNode->next;
		delete firstNode;
		firstNode=nextNode;
	}
}
template<class K,class E>
void SortChain<K,E>::insert(const pair< K,E>& thePair){
    
    
	pairNode<K,E> *p=firstNode;//pairnode类型的指针,指向firstnode
	pairNode<K,E> *tp=NULL;
	while(p!=NULL&&p->element.first<thePair.first){
    
    
		tp=p;                                 //为了待能在tp之后插入新节点会 
		p=p->next;
	} 
	if(p!=NULL&&p->element.first==thePair.first){
    
    //匹配到点 
		cout<<"Existed"<<endl;
		return ;
	}
	//未找到匹配的 
	pairNode<K,E>*newNode=new pairNode<K,E>(thePair,p);//在p前立一个新节点
	if(tp==NULL){
    
    
		firstNode=newNode;
	}else{
    
    
		tp->next=newNode;
	} 
	dSize++;
	return ;
}
template<class K,class E>
void SortChain<K,E>::find(const K&theKey)const{
    
    
	pairNode<K,E>*currentNode=firstNode;//指向现有头节点的指针 
	while(currentNode!=NULL&&currentNode->element.first!=theKey){
    
    
		currentNode=currentNode->next;
	}
	if(currentNode!=NULL&&currentNode->element.first==theKey){
    
    //匹配到了 
		cout<<dSize<<endl;
		return ;
	}
//未匹配到 
	cout<<"Not Found"<<endl;
	return ;
}
template<class K,class E>
void SortChain<K,E>::erase(const K&theKey){
    
    
	pairNode<K,E> *p=firstNode;
	pairNode<K,E> *tp=NULL;
	while(p!=NULL&&p->element.first<theKey){
    
    
		tp=p;
		p=p->next;
	}
	if(p!=NULL&&p->element.first==theKey){
    
    
		if(tp==NULL){
    
    
			firstNode=p->next; 
		}else{
    
    
			tp->next=p->next;
		}
		delete p;
		dSize--;
		cout<<dSize<<endl; 
	}else{
    
    
		cout<<"Delete Failed"<<endl;
	}
}
template<class K>
class Hash; 
template<>
class Hash<int>{
    
    //将theKey映射,方法为其本身 
	public:
    	size_t operator()(const int theKey) const{
    
    
        	return size_t(theKey);
    }
};
template<class K,class E>
class HashChain{
    
    
	protected:
		SortChain<K,E>*table;//链表型数组
		int divisor;//位置数
		Hash<K>hash;//把类型K映射到一个非负整数
		int dSize;//整个系统的数对个数
	public:
		HashChain(int theDivisor=10);
		~HashChain(){
    
    delete []table;};
		void find(const K&theKey)const; 
		void insert(const pair<const K,E>& thePair);
		void erase(const K&theKey); 
};
template<class K,class E>
HashChain<K,E>::HashChain(int theDivisor){
    
    
	divisor=theDivisor;
	dSize=0;
	table=new SortChain<K,E>[divisor];//SortChain<K,E>型的数组 
}
template<class K,class E>
void HashChain<K,E>::find(const K&theKey)const{
    
    
	table[hash(theKey)%divisor].find(theKey);
}
template<class K,class E>
void HashChain<K,E>::insert(const pair<const K,E>& thePair){
    
    
	int Arrayindex=(int)hash(thePair.first)%divisor;//先找数组对应的格子 
	int Listsize=table[Arrayindex].size();//这个格子的链表的长度
	table[Arrayindex].insert(thePair);
	if(table[Arrayindex].size()>Listsize)//代表插进去的不是重复的,因此总数加一 
		dSize++; 
}
template<class K,class E>
void HashChain<K,E>::erase(const K&theKey){
    
    
	table[hash(theKey)%divisor].erase(theKey);
}
int main(){
    
    
	int D,m;
	cin>>D;cin>>m;
	HashChain<int,int> H(D);
	pair<int,int> q;
	for(int i=0;i<m;i++){
    
    
		int op,x;
		cin>>op;cin>>x;
		if(op==0){
    
    
			q.first=x;q.second=x;
			H.insert(q);
		}else if(op==1){
    
    
			q.first=x;q.second=x;
			H.find(q.first);
		}else if(op==2){
    
    
			q.first=x;q.second=x;
			H.erase(q.first);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/m0_51406030/article/details/121166271
8