数据结构实验结果
实验一-递归
#include<iostream> using namespace std; int ans; void dfs(int pos,int n,int *a,int *b){ if(pos>n){ int ans_now=0,num=0; for(int i=1;i<=n;i++) if(b[i]==1){ num++; ans_now+=num*a[i]; } ans^=ans_now; return; } dfs(pos+1,n,a,b); b[pos]=1; dfs(pos+1,n,a,b); b[pos]=0; } int main(){ int n,*a,*b,*v; cin>>n; a=new int[n+1]; b=new int[n+1]; for(int i=1;i<=n;i++){ cin>>a[i]; b[i]=0; } dfs(1,n,a,b); cout<<ans<<endl; delete []a; delete []b; return 0; }
#include<iostream> #include<cstring> using namespace std; int ans=0; void dfs(int pos,int n,int *a,int *b,int *vis){ if(pos>n){ int ans_now=0; for(int i=1;i<=n;i++){ ans_now+=a[b[i]]^i; } ans|=ans_now; return; } for(int i=1;i<=n;i++){ if(!vis[i]){ vis[i]=1; b[pos]=i; dfs(pos+1,n,a,b,vis); vis[i]=0; } } } int main(){ int n,*a,*b,*vis; cin>>n; a=new int[n+1]; b=new int[n+1]; vis=new int[n+1]; for(int i=1;i<=n;i++){ cin>>a[i]; vis[i]=0; } dfs(1,n,a,b,vis); cout<<ans<<endl; delete []a; delete []b; delete []vis; return 0; }
实验二-排序
#include<iostream> using namespace std; template<typename T> class SORT{ public: SORT(){} SORT(int _n); ~SORT(); template<typename U> friend istream & operator >> (istream & input,SORT<U> &); template<typename U> friend ostream & operator << (ostream & output,SORT<U> &); void rank(); void rearrange();//名次排序 void selection_sort();//及时终止的选择排序 bool bubble(); void bubble_sort();//及时终止的冒泡排序 void insert(int ,const T&); void insertion_sort();//插入排序 private: T *a; int *r,n; }; template<typename T> SORT<T>::SORT(int _n){ n=_n; a=new T[n]; r=new int[n]; } template<typename T> SORT<T>::~SORT(){ delete []a; delete []r; } template<typename T> istream & operator >> (istream & input,SORT<T> & w){ for(int i=0;i<w.n;i++)input>>w.a[i]; return input; } template<typename T> ostream & operator << (ostream & output,SORT<T> & w){ for(int i=0;i<w.n;i++)output<<w.a[i]<<" "; output<<endl; return output; } /*------------------------名次排序----------------------------*/ template<typename T> void SORT<T>::rank(){ for(int i=0;i<n;i++)r[i]=0; for(int i=1;i<n;i++) for(int j=0;j<i;j++) if(a[j]<=a[i])r[i]++; else r[j]++; } template<typename T> void SORT<T>::rearrange(){ rank(); for(int i=0;i<n;i++) while(r[i]!=i){ int t=r[i]; swap(a[i],a[t]); swap(r[i],r[t]); } } /*-------------------及时终止的选择排序----------------------*/ template<typename T> void SORT<T>::selection_sort(){ bool sorted=0; for(int size=n;!sorted&&(size>1);size--){ int index_of_max=0; sorted=1; for(int i=1;i<size;i++) if(a[index_of_max]<a[i])index_of_max=i; else sorted=0; swap(a[index_of_max],a[size-1]); } } /*-------------------及时终止的冒泡排序----------------------*/ template<typename T> bool SORT<T>::bubble(){ bool swapped=0; for(int i=0;i<n-1;i++) if(a[i]>a[i+1]){ swap(a[i],a[i+1]); swapped=1; } return swapped; } template<typename T> void SORT<T>::bubble_sort(){ for(int i=n;i>1&&bubble();i--); } /*------------------------插入排序----------------------------*/ template<typename T> void SORT<T>::insert(int _n,const T& x){ int i; for(i=_n-1;i>=0&&x<a[i];i--)a[i+1]=a[i]; a[i+1]=x; } template<typename T> void SORT<T>::insertion_sort(){ for(int i=1;i<n;i++){ T t=a[i]; insert(i,t); } } int main(){ int n; cin>>n; SORT<int>q(n); cin>>q; q.insertion_sort(); cout<<q; return 0; }
实验三-数组
#include<iostream> #include<cstring> using namespace std; class list_node{ private: string name,phone_number; int Class,dormitory; public: list_node(){} list_node(string s1,string s2,int x,int y):name(s1),phone_number(s2),Class(x),dormitory(y){}; string get_name(){return name;} string get_phone_number(){return phone_number;} int get_Class(){return Class;} int get_dormitory(){return dormitory;} void set_name(string s){name=s;} void set_phone_number(string s){phone_number=s;} void set_Class(int x){Class=x;} void set_dormitory(int x){dormitory=x;} }; class list{ private: list_node* a; int n; public: list(){} list(int _n){n=0;a=new list_node[_n];} ~list(){delete []a;} void insert(const list_node& theElement); void erase(const string& s); void change(const string& name,const int& op); bool find_name(const string& name); int find_dormitory(const int& Class); }; void list::insert(const list_node& theElement){ a[n]=theElement; n++; } void list::erase(const string& s){ bool flag=0; for(int i=0;i<n;i++){ if(a[i].get_name()==s){ flag=1; } else if(flag){ a[i-1]=a[i]; } } n--; } void list::change(const string& name,const int& op){ int pos=0; for(int i=0;i<n;i++) if(a[i].get_name()==name){ pos=i; break; } if(op==1){ string phone_number; cin>>phone_number; a[pos].set_phone_number(phone_number); } else if(op==2){ int Class; cin>>Class; a[pos].set_Class(Class); } else { int dormitory; cin>>dormitory; a[pos].set_dormitory(dormitory); } } bool list::find_name(const string& name){ for(int i=0;i<n;i++){ if(a[i].get_name()==name)return 1; } return 0; } int list::find_dormitory(const int& Class){ int res=0; for(int i=0;i<n;i++){ if(a[i].get_Class()==Class)res^=a[i].get_dormitory(); } return res; } void solve0(list& q){ string name,phone_number;int Class,dormitory; cin>>name>>phone_number>>Class>>dormitory; list_node p(name,phone_number,Class,dormitory); q.insert(p); } void solve1(list& q){ string name; cin>>name; q.erase(name); } void solve2(list& q){ string name;int op; cin>>name>>op; q.change(name,op); } bool solve3(list& q){ string name; cin>>name; return q.find_name(name); } int solve4(list& q){ int Class; cin>>Class; return q.find_dormitory(Class); } int main(){ int n,op; cin>>n; list q(n); while(n--){ cin>>op; switch(op){ case 0:solve0(q);break; case 1:solve1(q);break; case 2:solve2(q);break; case 3:cout<<solve3(q)<<endl;break; default:cout<<solve4(q)<<endl;break; } } return 0; }
#include<iostream> #include<cstdio> #include<string> #include<algorithm> #include<sstream> using namespace std; class illegalParameterValue{ public: illegalParameterValue():message("Illegal parameter value"){} illegalParameterValue(string theMessage){message=theMessage;} void outputMessage(){cout<<message<<endl;} private: string message; }; template<class T> class linearList{ public: virtual ~linearList(){}; virtual bool empty() const=0; virtual int size()const =0; virtual T& get(int theIndex)const=0; virtual int indexOf(const T& theElement)const=0; virtual void erase(int theIndex)=0; virtual void insert(int theIndex,const T& theElement)=0; virtual void output(ostream & out)const=0; }; template<class T> class circularArrayList:public linearList<T>{ public: circularArrayList(int initialCapacity=10); circularArrayList(const circularArrayList<T>&); ~circularArrayList(){delete []element;} bool empty()const{return listSize==0;} int size()const{return listSize;} T& get(int theIndex)const; int indexOf(const T& theElement)const; void erase(int theIndex); void insert(int theIndex,const T& theElement); void output(ostream& out)const; int capacity()const{return arrayLength;} int first,last; protected: void checkIndex(int theIndex)const; T* element; int arrayLength; int listSize; }; template<class T> circularArrayList<T>::circularArrayList(int initialCapacity){ if(initialCapacity<1){ ostringstream s; s<<"Initial capacity = "<<initialCapacity<<" Must be > 0"; throw illegalParameterValue(s.str()); } arrayLength=initialCapacity; element=new T[arrayLength]; listSize=0; first=last=-1; } template<class T> circularArrayList<T>::circularArrayList(const circularArrayList<T>& theList){ arrayLength=theList.arrayLength; listSize=theList.listSize; element=new T[arrayLength]; int start=first,end; if(first<=last)end=last; else end=last+arrayLength; for(int i=start;i<=end;i++){ element[i%arrayLength]=theList.element[i%arrayLength]; } } template<class T> void circularArrayList<T>::checkIndex(int theIndex)const{ int start=first,end,pos; if(first<=last)end=last; else end=last+arrayLength; if(first<=theIndex)pos=theIndex; else pos=theIndex+arrayLength; if(pos<start || pos>end){ ostringstream s; s<<"Index = "<<theIndex<<" size = "<<listSize; throw illegalParameterValue(s.str()); } } template<class T> T& circularArrayList<T>::get(int theIndex)const{ theIndex=(theIndex+first)%arrayLength; checkIndex(theIndex); return element[theIndex]; } template<class T> int circularArrayList<T>::indexOf(const T& theElement)const{ int pos=first,end; if(first<=last)end=last; else end=last+arrayLength; while(pos<=end){ if(element[pos%arrayLength]==theElement)break; pos++; } if(pos==end+1)return -1; else return (pos-first+arrayLength)%arrayLength; } template<class T> void circularArrayList<T>::erase(int theIndex){ theIndex=(theIndex+first)%arrayLength; checkIndex(theIndex); int start=first,end,pos; if(first<=last)end=last; else end=last+arrayLength; if(first<=theIndex)pos=theIndex; else pos=theIndex+arrayLength; if(theIndex-start>=end-theIndex){//鍚庨潰鐨勫悜鍓嶇Щ鍔? for(int i=pos+1;i<=end;i++){ element[(i-1+arrayLength)%arrayLength]=element[i%arrayLength]; } last=(end-1+arrayLength)%arrayLength; } else {//鍓嶉潰鐨勫悜鍚庣Щ鍔? for(int i=pos-1;i>=first;i--){ element[(i+1)%arrayLength]=element[i%arrayLength]; } first=(first+1)%arrayLength; } listSize--; } template<class T> void changeLength1D(T*& a,int oldLength,int newLength,int &first,int &last){ if(newLength<0) throw illegalParameterValue("new length nust be >= 0"); T* tmp=new T[newLength]; int start=first,end; if(first<=last)end=last; else end=last+oldLength; for(int i=start;i<=end;i++){ tmp[i%newLength]=a[i%oldLength]; } delete []a; a=tmp; first=start%newLength; last=start%newLength; } template<class T> void circularArrayList<T>::insert(int theIndex,const T& theElement){ if(listSize+1>=arrayLength){ changeLength1D(element,arrayLength,2*arrayLength,first,last); arrayLength*=2; } theIndex=(theIndex+max(0,first))%arrayLength; int start=first,end,pos; if(first<=last)end=last; else end=last+arrayLength; if(first<=theIndex)pos=theIndex; else pos=theIndex+arrayLength; if(pos<first||pos>end+1){ } if(pos-start<=end-pos+1){//前面的向前移 for(int i=start;i<pos;i++){ element[(i-1+arrayLength)%arrayLength]=element[i%arrayLength]; } element[(pos-1+arrayLength)%arrayLength]=theElement; first=(first-1+arrayLength)%arrayLength; } else{//后面的向后移 for(int i=end;i>=pos;i--){ element[(i+1)%arrayLength]=element[i%arrayLength]; } element[pos%arrayLength]=theElement; last=(end+1)%arrayLength; } listSize++; if(listSize==1){ first=last; } } template<class T> void circularArrayList<T>::output(ostream &out)const{ int start=first,end; if(first<=last)end=last; else end=last+arrayLength; for(int i=start;i<=end;i++){ out<<element[i%arrayLength]<<" "; } out<<endl; } template<class T> ostream& operator<<(ostream& out,const circularArrayList<T>& x){ x.output(out); return out; } int main(){ circularArrayList<int> a; cout<<a; return 0; }
实验四-链表
#include<iostream> #include<cstring> #include<sstream> using namespace std; template<class T> struct chainNode{ T element; chainNode<T> *next; chainNode(){} chainNode(const T& element){this->element=element;} chainNode(const T& element,chainNode<T>* next){ this->element=element; this->next=next; } }; template<class T> class chain{ public: chain(int initialCapacity=10); chain(const chain<T>&);//复制构造函数 ~chain(); void insert(int theIndex,const T& theElement);//将元素theElement插入到位置theIndex上 void erase(const T& val);//删除val第一次出现的位置 void reverse();//原地逆置 int indexOf(const T& theElement)const;//找到theElement第一次出现的位置 T& get(int theIndex)const;//找到序号为theIndex的元素 class iterator;//定义迭代器类 iterator begin(){return iterator(firstNode);} iterator end(){return iterator(NULL);} int find();//计算索引与元素的异或和 void output( ostream &out)const;//将链表中的元素输出到out中 protected: chainNode<T>* firstNode; int listSize; }; template<class T> chain<T>::chain(int initialCapacity){ firstNode=NULL; listSize=0; } template<class T> chain<T>::chain(const chain<T>& theList){ listSize=theList.listSize; if(listSize==0){//链表theList为空 firstNode=NULL; return; } //链表theList为非空 chainNode<T>* sourceNode=theList.firstNode; firstNode=new chainNode<T>(sourceNode->element);//复制链表theList的首元素 sourceNode=sourceNode->next; chainNode<T>* targetNode=firstNode; while(sourceNode!=NULL){//最后一个节点(结束的标志) targetNode->next=new chainNode<T>(sourceNode->element); targetNode=targetNode->next; sourceNode=sourceNode->next; } targetNode->next=NULL;//链表结束 } template<class T> class chain<T>::iterator{ public: iterator(chainNode<T>* theNode=NULL){node=theNode;}//构造函数 //解引用操作符 T& operator*()const{return node->element;} T* operator->()const{return &node->element;} //迭代器加法操作 iterator & operator++(){ node=node->next; return node; } iterator operator++(T){ iterator old=*this; node=node->next; return old; } //相等检验 bool operator!=(const iterator right)const{ return node!=right.node; } bool operator==(const iterator right)const{ return node==right.node; } protected: chainNode<T>* node; }; template<class T> chain<T>::~chain(){ while(firstNode!=NULL){ chainNode<T>* nextNode=firstNode->next; delete firstNode; firstNode=nextNode; } } template<class T> void chain<T>::insert(int theIndex,const T& theElement){ if(theIndex==0){//在链表头插入 firstNode=new chainNode<T>(theElement,firstNode); listSize++; return; } chainNode<T>* p=firstNode; int id=0; while(id<theIndex-1){//寻找元素前驱 p=p->next; id++; } p->next=new chainNode<T>(theElement,p->next);//在p之后插入 listSize++; } template<class T> void chain<T>::erase(const T& theElement){ if(firstNode->element==theElement){ chainNode<T>* prefirstNode=firstNode; firstNode=firstNode->next; delete prefirstNode; } chainNode<T>* currentNode=firstNode; while(currentNode->next!=NULL && currentNode->next->element!=theElement) currentNode=currentNode->next; if(currentNode->next==NULL){ puts("-1"); return; } chainNode<T>* p=currentNode->next; currentNode->next=currentNode->next->next; delete p; listSize--; } template<class T> int chain<T>::indexOf(const T& theElement)const{ chainNode<T>* currentNode=firstNode; int index=0; //搜索链表寻找元素theElement while(currentNode!=NULL && currentNode->element!=theElement){ currentNode=currentNode->next; index++; } //确定是否找到所需的元素 if(currentNode==NULL)return -1; else return index; } template<class T> T& chain<T>::get(int theIndex)const { if(theIndex>=listSize)return firstNode->element; //移向所需要的节点 chainNode<T>* currentNode=firstNode; for(int i=0;i<theIndex;i++)currentNode=currentNode->next; return currentNode->element; } template<class T> void chain<T>::reverse(){ if(listSize==0)return; //定义三个节点,表示当前节点以及当前节点的上一个节点和下一个节点 chainNode<T>* preNode=firstNode; chainNode<T>* currentNode=firstNode->next; chainNode<T>* nextNode; firstNode->next=NULL; while(currentNode!=NULL){ nextNode=currentNode->next;//更新下一个节点 currentNode->next=preNode;//将当前节点的next值赋值为上一个节点,实现指针反向 preNode=currentNode;//将上一个节点后移 currentNode=nextNode;//将当前节点后移 } firstNode=preNode; } template<class T> int chain<T>::find(){ int res=0; int pos=0; for(iterator p=begin();p!=end();p++){ res+=(pos^(*p));//用迭代器依次向后遍历 pos++; } return res; } template<class T> void chain<T>::output( ostream &out)const{ iterator p=begin(); // out<<listSize<<endl; for(int i=0;i<listSize;i++,p++){ out<<(*p)<<" "; } out<<endl; } template<class T> ostream & operator << (ostream & out,const chain<T> & a){ a.output(out);return out; } int main(){ chain<int> a; int n,q,x; cin>>n>>q; for(int i=0;i<n;i++){ cin>>x; a.insert(i,x); } int op,idx,val; while(q--){ cin>>op; // cout<<a; switch (op){ case 1:cin>>idx>>val;a.insert(idx,val);break; case 2:cin>>val;a.erase(val);break; case 3:a.reverse();break; case 4:cin>>val;cout<<a.indexOf(val)<<endl;break; default:cout<<a.find()<<endl;break; } } return 0; }
#include<iostream> #include<cstring> #include<sstream> using namespace std; template<typename T> class SORT{ public: SORT(){} SORT(int _n); ~SORT(); T operator [] (int i)const{return a[i];}; template<typename U> friend istream & operator >> (istream & input,SORT<U> &); template<typename U> friend ostream & operator << (ostream & output,SORT<U> &); void insert(int ,const T&); void insertion_sort();//²åÈëÅÅÐò private: T *a; int n; }; template<typename T> SORT<T>::SORT(int _n){ n=_n; a=new T[n]; } template<typename T> SORT<T>::~SORT(){ delete []a; } template<typename T> istream & operator >> (istream & input,SORT<T> & w){ for(int i=0;i<w.n;i++)input>>w.a[i]; return input; } template<typename T> ostream & operator << (ostream & output,SORT<T> & w){ for(int i=0;i<w.n;i++)output<<w.a[i]<<" "; output<<endl; return output; } template<typename T> void SORT<T>::insert(int _n,const T& x){ int i; for(i=_n-1;i>=0&&x<a[i];i--)a[i+1]=a[i]; a[i+1]=x; } template<typename T> void SORT<T>::insertion_sort(){ for(int i=1;i<n;i++){ T t=a[i]; insert(i,t); } } template<class T> struct chainNode{ T element; chainNode<T> *next; chainNode(){} chainNode(const T& element){this->element=element;} chainNode(const T& element,chainNode<T>* next){ this->element=element; this->next=next; } }; template<class T> class chain{ public: chain(int initialCapacity=10); chain(const chain<T>&);//复制构造函数 ~chain(); void insert(int theIndex,const T& theElement);//将元素theElement插入到位置theIndex上 void erase(const T& val);//删除val第一次出现的位置 void reverse();//原地逆置 int indexOf(const T& theElement)const;//找到theElement第一次出现的位置 T& get(int theIndex)const;//找到序号为theIndex的元素 class iterator;//定义迭代器类 iterator begin(){return iterator(firstNode);} iterator end(){return iterator(NULL);} int find();//计算索引与元素的异或和 void output( ostream &out)const;//将链表中的元素输出到out中 template<class U> friend void merge(const chain<U>&,const chain<U>&,chain<U>&);//将两个链表合并,保持有序 protected: chainNode<T>* firstNode; int listSize; }; template<class T> chain<T>::chain(int initialCapacity){ firstNode=NULL; listSize=0; } template<class T> chain<T>::chain(const chain<T>& theList){ listSize=theList.listSize; if(listSize==0){//链表theList为空 firstNode=NULL; return; } //链表theList为非空 chainNode<T>* sourceNode=theList.firstNode; firstNode=new chainNode<T>(sourceNode->element);//复制链表theList的首元素 sourceNode=sourceNode->next; chainNode<T>* targetNode=firstNode; while(sourceNode!=NULL){//最后一个节点(结束的标志) targetNode->next=new chainNode<T>(sourceNode->element); targetNode=targetNode->next; sourceNode=sourceNode->next; } targetNode->next=NULL;//链表结束 } template<class T> class chain<T>::iterator{ public: iterator(chainNode<T>* theNode=NULL){node=theNode;}//构造函数 //解引用操作符 T& operator*()const{return node->element;} T* operator->()const{return &node->element;} //迭代器加法操作 iterator & operator++(){ node=node->next; return node; } iterator operator++(int){ iterator old=*this; node=node->next; return old; } //相等检验 bool operator!=(const iterator right)const{ return node!=right.node; } bool operator==(const iterator right)const{ return node==right.node; } iterator & operator = (const iterator right){ node=right.node; return *this; } protected: chainNode<T>* node; }; template<class T> chain<T>::~chain(){ while(firstNode!=NULL){ chainNode<T>* nextNode=firstNode->next; delete firstNode; firstNode=nextNode; } } template<class T> void chain<T>::insert(int theIndex,const T& theElement){ if(theIndex==0){//在链表头插入 firstNode=new chainNode<T>(theElement,firstNode); listSize++; return; } chainNode<T>* p=firstNode; int id=0; while(id<theIndex-1){//寻找元素前驱 p=p->next; id++; } p->next=new chainNode<T>(theElement,p->next);//在p之后插入 listSize++; } template<class T> void chain<T>::erase(const T& theElement){ if(firstNode->element==theElement){ chainNode<T>* prefirstNode=firstNode; firstNode=firstNode->next; delete prefirstNode; } chainNode<T>* currentNode=firstNode; while(currentNode->next!=NULL && currentNode->next->element!=theElement) currentNode=currentNode->next; if(currentNode->next==NULL){ puts("-1"); return; } chainNode<T>* p=currentNode->next; currentNode->next=currentNode->next->next; delete p; listSize--; } template<class T> int chain<T>::indexOf(const T& theElement)const{ chainNode<T>* currentNode=firstNode; int index=0; //搜索链表寻找元素theElement while(currentNode!=NULL && currentNode->element!=theElement){ currentNode=currentNode->next; index++; } //确定是否找到所需的元素 if(currentNode==NULL)return -1; else return index; } template<class T> T& chain<T>::get(int theIndex)const { if(theIndex>=listSize)return firstNode->element; //移向所需要的节点 chainNode<T>* currentNode=firstNode; for(int i=0;i<theIndex;i++)currentNode=currentNode->next; return currentNode->element; } template<class T> void chain<T>::reverse(){ if(listSize==0)return; //定义三个节点,表示当前节点以及当前节点的上一个节点和下一个节点 chainNode<T>* preNode=firstNode; chainNode<T>* currentNode=firstNode->next; chainNode<T>* nextNode; firstNode->next=NULL; while(currentNode!=NULL){ nextNode=currentNode->next;//更新下一个节点 currentNode->next=preNode;//将当前节点的next值赋值为上一个节点,实现指针反向 preNode=currentNode;//将上一个节点后移 currentNode=nextNode;//将当前节点后移 } firstNode=preNode; } template<class T> int chain<T>::find(){ int res=0; int pos=0; for(iterator p=begin();p!=end();p++){ res+=(pos^(*p));//用迭代器依次向后遍历 pos++; } return res; } template<class T> void chain<T>::output( ostream &out)const{ iterator p=firstNode; // out<<listSize<<endl; for(int i=0;i<listSize;i++,p++){ out<<(*p)<<" "; } out<<endl; } template<class T> ostream & operator << (ostream & out,const chain<T> & a){ a.output(out);return out; } template<class T> void merge(chain<T>& a,chain<T>& b,chain<T>& c){ chain<long long>::iterator p=a.begin(),q=b.begin();//为a和b分别定义一个迭代器 int id=0; while(p!=a.end() && q!=b.end()){ if(*p<*q)c.insert(id,*p),id++,p++;//将a中的一个元素插入c else c.insert(id,*q),id++,q++;//将b中的一个元素插入c } while(p!=a.end())c.insert(id,*p),id++,p++;//将剩余的元素插入c while(q!=b.end())c.insert(id,*q),id++,q++; } int main(){ chain<long long> a,b,c; int n,m; cin>>n>>m; SORT<long long>q(n); cin>>q; q.insertion_sort(); for(int i=0;i<n;i++)a.insert(i,q[i]); SORT<long long>p(m); cin>>p; p.insertion_sort(); for(int i=0;i<m;i++)b.insert(i,p[i]); merge(a,b,c); cout<<a.find()<<endl<<b.find()<<endl<<c.find()<<endl; return 0; }
1 #include<iostream> 2 #include<cstring> 3 #include<sstream> 4 using namespace std; 5 template<typename T> 6 class SORT{ 7 public: 8 SORT(){} 9 SORT(int _n); 10 ~SORT(); 11 12 T operator [] (int i)const{return a[i];}; 13 14 template<typename U> 15 friend istream & operator >> (istream & input,SORT<U> &); 16 17 template<typename U> 18 friend ostream & operator << (ostream & output,SORT<U> &); 19 20 void insert(int ,const T&); 21 void insertion_sort();//²åÈëÅÅÐò 22 private: 23 T *a; 24 int n; 25 }; 26 27 template<typename T> 28 SORT<T>::SORT(int _n){ 29 n=_n; 30 a=new T[n]; 31 } 32 33 template<typename T> 34 SORT<T>::~SORT(){ 35 delete []a; 36 } 37 38 template<typename T> 39 istream & operator >> (istream & input,SORT<T> & w){ 40 for(int i=0;i<w.n;i++)input>>w.a[i]; 41 return input; 42 } 43 44 template<typename T> 45 ostream & operator << (ostream & output,SORT<T> & w){ 46 for(int i=0;i<w.n;i++)output<<w.a[i]<<" "; 47 output<<endl; 48 return output; 49 } 50 51 template<typename T> 52 void SORT<T>::insert(int _n,const T& x){ 53 int i; 54 for(i=_n-1;i>=0&&x<a[i];i--)a[i+1]=a[i]; 55 a[i+1]=x; 56 } 57 58 template<typename T> 59 void SORT<T>::insertion_sort(){ 60 for(int i=1;i<n;i++){ 61 T t=a[i]; 62 insert(i,t); 63 } 64 } 65 66 template<class T> 67 struct chainNode{ 68 T element; 69 chainNode<T> *next; 70 71 chainNode(){} 72 chainNode(const T& element){this->element=element;} 73 chainNode(const T& element,chainNode<T>* next){ 74 this->element=element; 75 this->next=next; 76 } 77 }; 78 79 template<class T> 80 class chain{ 81 public: 82 chain(int initialCapacity=10); 83 chain(const chain<T>&); 84 ~chain(); 85 86 void insert(int theIndex,const T& theElement); 87 void erase(const T& val); 88 void reverse(); 89 int indexOf(const T& theElement)const; 90 T& get(int theIndex)const; 91 class iterator; 92 iterator begin(){return iterator(firstNode);} 93 iterator end(){return iterator(NULL);} 94 int find(); 95 void output( ostream &out)const; 96 97 98 template<class U> 99 friend void merge(const chain<U>&,const chain<U>&,chain<U>&); 100 protected: 101 chainNode<T>* firstNode; 102 int listSize; 103 }; 104 105 template<class T> 106 chain<T>::chain(int initialCapacity){ 107 firstNode=NULL; 108 listSize=0; 109 } 110 111 template<class T> 112 chain<T>::chain(const chain<T>& theList){ 113 listSize=theList.listSize; 114 if(listSize==0){ 115 firstNode=NULL; 116 return; 117 } 118 chainNode<T>* sourceNode=theList.firstNode; 119 firstNode=new chainNode<T>(sourceNode->element); 120 sourceNode=sourceNode->next; 121 chainNode<T>* targetNode=firstNode; 122 while(sourceNode!=NULL){ 123 targetNode->next=new chainNode<T>(sourceNode->element); 124 targetNode=targetNode->next; 125 sourceNode=sourceNode->next; 126 } 127 targetNode->next=NULL; 128 } 129 130 template<class T> 131 class chain<T>::iterator{ 132 public: 133 iterator(chainNode<T>* theNode=NULL){node=theNode;} 134 T& operator*()const{return node->element;} 135 T* operator->()const{return &node->element;} 136 iterator & operator++(){ 137 node=node->next; 138 return node; 139 } 140 iterator operator++(int){ 141 iterator old=*this; 142 node=node->next; 143 return old; 144 } 145 bool operator!=(const iterator right)const{ 146 return node!=right.node; 147 } 148 bool operator==(const iterator right)const{ 149 return node==right.node; 150 } 151 protected: 152 chainNode<T>* node; 153 }; 154 155 template<class T> 156 chain<T>::~chain(){ 157 while(firstNode!=NULL){ 158 chainNode<T>* nextNode=firstNode->next; 159 delete firstNode; 160 firstNode=nextNode; 161 } 162 } 163 164 template<class T> 165 void chain<T>::insert(int theIndex,const T& theElement){ 166 if(theIndex==0){ 167 firstNode=new chainNode<T>(theElement,firstNode); 168 listSize++; 169 return; 170 } 171 chainNode<T>* p=firstNode; 172 int id=0; 173 while(id<theIndex-1){ 174 p=p->next; 175 id++; 176 } 177 p->next=new chainNode<T>(theElement,p->next); 178 listSize++; 179 } 180 181 template<class T> 182 void chain<T>::erase(const T& theElement){ 183 if(firstNode->element==theElement){ 184 chainNode<T>* prefirstNode=firstNode; 185 firstNode=firstNode->next; 186 delete prefirstNode; 187 } 188 chainNode<T>* currentNode=firstNode; 189 while(currentNode->next!=NULL && currentNode->next->element!=theElement) 190 currentNode=currentNode->next; 191 if(currentNode->next==NULL){ 192 puts("-1"); 193 return; 194 } 195 chainNode<T>* p=currentNode->next; 196 currentNode->next=currentNode->next->next; 197 delete p; 198 listSize--; 199 } 200 201 template<class T> 202 int chain<T>::indexOf(const T& theElement)const{ 203 chainNode<T>* currentNode=firstNode; 204 int index=0; 205 while(currentNode!=NULL && currentNode->element!=theElement){ 206 currentNode=currentNode->next; 207 index++; 208 } 209 if(currentNode==NULL)return -1; 210 else return index; 211 } 212 213 template<class T> 214 T& chain<T>::get(int theIndex)const { 215 if(theIndex>=listSize)return firstNode->element; 216 chainNode<T>* currentNode=firstNode; 217 for(int i=0;i<theIndex;i++)currentNode=currentNode->next; 218 return currentNode->element; 219 } 220 221 template<class T> 222 void chain<T>::reverse(){ 223 if(listSize==0)return; 224 225 chainNode<T>* preNode=firstNode; 226 chainNode<T>* currentNode=firstNode->next; 227 chainNode<T>* nextNode; 228 firstNode->next=NULL; 229 while(currentNode!=NULL){ 230 nextNode=currentNode->next; 231 currentNode->next=preNode; 232 preNode=currentNode; 233 currentNode=nextNode; 234 } 235 firstNode=preNode; 236 } 237 238 template<class T> 239 int chain<T>::find(){ 240 int res=0;iterator p=firstNode; 241 for(int i=0;i<listSize;i++,p++) 242 res+=(i^(*p)); 243 return res; 244 } 245 246 template<class T> 247 void chain<T>::output( ostream &out)const{ 248 iterator p=firstNode; 249 // out<<listSize<<endl; 250 for(int i=0;i<listSize;i++,p++){ 251 out<<(*p)<<" "; 252 } 253 out<<endl; 254 } 255 256 template<class T> 257 ostream & operator << (ostream & out,const chain<T> & a){ 258 a.output(out);return out; 259 } 260 261 template<class T> 262 void merge(const chain<T>& a,const chain<T>& b,chain<T>& c){ 263 chain<long long>::iterator p=a.firstNode,q=b.firstNode;//这里的尖括号里需要给出一个明确的类型long long 264 int id1=0,id2=0; 265 while(id1<a.listSize && id2<b.listSize){ 266 if(*p<*q)c.insert(id1+id2,*p),id1++,p++; 267 else c.insert(id1+id2,*q),id2++,q++; 268 } 269 while(id1<a.listSize)c.insert(id1+id2,*p),id1++,p++; 270 while(id2<b.listSize)c.insert(id1+id2,*q),id2++,q++; 271 } 272 273 int main(){ 274 freopen("Cola.txt","r",stdin); 275 chain<long long> a,b,c; 276 int n,m,x; 277 cin>>n>>m; 278 279 SORT<long long>q(n); 280 cin>>q; 281 q.insertion_sort(); 282 for(int i=0;i<n;i++)a.insert(i,q[i]); 283 284 SORT<long long>p(m); 285 cin>>p; 286 p.insertion_sort(); 287 for(int i=0;i<m;i++)b.insert(i,p[i]); 288 289 merge(a,b,c); 290 cout<<a.find()<<endl<<b.find()<<endl<<c.find()<<endl; 291 return 0; 292 }
实验五-稀疏矩阵
矩阵
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; class illegalParameterValue{ public: illegalParameterValue():message("Illegal parameter value"){} illegalParameterValue(string theMessage){message=theMessage;} void outputMessage(){cout<<message<<endl;} private: string message; }; template<class T> class Matrix{ public: Matrix(int theRows=0,int theColumns=0); Matrix(const Matrix<T>&); ~Matrix(); template<class U> friend istream & operator>>(istream &input,Matrix<U> &); template<class U> friend ostream & operator<<(ostream &output,const Matrix<U> &); Matrix operator * (const Matrix<T>&)const; Matrix operator + (const Matrix<T>&)const; Matrix& operator = (const Matrix<T>&); private: int theRows,theColumns; T *element; }; template<class T> Matrix<T>::Matrix(int theRows,int theColumns){ if(theRows<0 || theColumns<0) throw illegalParameterValue("Rows and columns must be >= 0"); if((theRows == 0 || theColumns == 0) && (theRows!=0 || theColumns!=0)) throw illegalParameterValue("Either both or neither rows and columns should be zeros"); this->theRows=theRows; this->theColumns=theColumns; this->element=new T[theRows*theColumns]; } template<class T> Matrix<T>::Matrix(const Matrix<T>& a){ this->theRows=a.theRows; this->theColumns=a.theColumns; this->element=new T[a.theRows*a.theColumns]; for(int i=0;i<a.theRows*a.theColumns;i++){ element[i]=a.element[i]; } } template<class T> Matrix<T>::~Matrix(){ delete []element; } template<class S> istream & operator >> (istream &input,Matrix<S> &a){ input>>a.theRows>>a.theColumns; delete []a.element; a.element=new S[a.theRows*a.theColumns]; for(int i=0;i<a.theRows*a.theColumns;i++) input>>a.element[i]; return input; } template<class S> ostream & operator << (ostream &output,const Matrix<S> &a){ output<<a.theRows<<" "<<a.theColumns<<endl; for(int i=0;i<a.theRows*a.theColumns;i++){ output<<a.element[i]<<" "; if((i+1)%a.theColumns==0)output<<endl; } return output; } template<class T> Matrix<T> Matrix<T>::operator * (const Matrix<T> &a)const{ if(theColumns!=a.theRows){ cout<<"-1"<<endl; return a; } Matrix<T> res(theRows,a.theColumns); for(int i=1;i<=theRows;i++) for(int j=1;j<=a.theColumns;j++){ res.element[(i-1)*a.theColumns+j-1]=0; for(int k=1;k<=theColumns;k++){ res.element[(i-1)*a.theColumns+j-1]+=element[(i-1)*theColumns+k-1] * a.element[(k-1)*a.theColumns+j-1]; } } return res; } template<class T> Matrix<T> Matrix<T>::operator + (const Matrix<T> &a)const{ if(theRows!=a.theRows || theColumns!=a.theColumns){ cout<<"-1"<<endl; return a; } Matrix<T> res(theRows,theColumns); for(int i=0;i<theRows*theColumns;i++) res.element[i]=element[i]+a.element[i]; return res; } template<class T> Matrix<T>& Matrix<T>::operator = (const Matrix<T> &a){ if(this==&a)return *this; this->theRows=a.theRows; this->theColumns=a.theColumns; delete []element; element=new T[a.theRows*a.theColumns]; for(int i=0;i<theRows*theColumns;i++){ element[i]=a.element[i]; } return *this; } int main(){ int T,op; cin>>T; Matrix<int> p,q; while(T--){ cin>>op; switch(op){ case 1:cin>>p;break; case 2:cin>>q;p=p*q;break; case 3:cin>>q;p=p+q;break; default:cout<<p;break; } } system("pause"); return 0; } /* 11 1 3 3 3 4 0 0 2 1 4 1 1 2 3 4 1 2 3 4 2 3 4 5 3 4 5 6 4 2 2 2 1 2 3 4 */
稀疏矩阵
#include<iostream> #include<cstring> #include<sstream> using namespace std; class illegalParameterValue{ public: illegalParameterValue():message("Illegal parameter value"){} illegalParameterValue(string theMessage){message=theMessage;} void illegalIndex(string theMessage){message=theMessage;} private: string message; }; class illegalIndex{ public: illegalIndex():message("Illegal index"){} illegalIndex(string theMessage){message=theMessage;} private: string message; }; template<class T> void changeLength1D(T* &a,int oldLength,int newLength){ if(newLength<0) throw illegalParameterValue("new length must be >= 0"); T* temp=new T[newLength]; int number=min(oldLength,newLength); copy(a,a+number,temp); delete []a; a=temp; } template<class T> class matrixTerm{ public: int row,col; T value; operator T() const {return value;} matrixTerm<T> operator = (const matrixTerm<T> &x){ row=x.row;col=x.col;value=x.value; return *this; } }; template<class T> class linearList{ public: virtual ~linearList(){}; virtual bool empty()const=0; virtual int size()const=0; virtual T& get(int theIndex)const =0; virtual int indexOf(const T& theElement)const=0; virtual void erase(int theIndex)=0; virtual void insert(int theIndex,const T& theElement)=0; }; template<class T> class arrayList:public linearList<T>{ public: arrayList(int initialCapacity=10); arrayList(const arrayList<T>&); ~arrayList(){delete []element;} bool empty()const{return listSize==0;} int size()const{return listSize;} T& get(int theIndex)const; int indexOf(const T& theElement)const; void erase(int theIndex); void insert(int theIndex,const T& theElement); int capacity()const{return arrayLength;} arrayList& operator = (const arrayList<T> &a); template<class U> friend ostream & operator << (ostream& out,const arrayList<U> &); void reSet(int newSize); void set(int theIndex,T& theElement); void clear(); class iterator; iterator begin(){return iterator(element);} iterator end(){return iterator(element+listSize);} class iterator { public: typedef bidirectional_iterator_tag iterator_category;//μü′ú?÷ààDí?a???òμü′ú?÷ typedef T value_type;//?a???μààDí typedef ptrdiff_t difference_type;//2??μààDí typedef T* pointer;//???ò?a??μ?????ààDí typedef T& reference;//òyó?ààDí iterator(T* thePosition=0){position=thePosition;} T& operator* ()const{return *position;} T* operator->()const{return &*position;} iterator & operator ++(){++position;return *this;} iterator operator ++ (int){ iterator old=*this; ++position; return old; } iterator & operator --(){--position;return *this;} iterator operator --(int){ iterator old=*this; --position; return old; } bool operator != (const iterator right) const{ return position!=right.position; } bool operator == (const iterator right)const { return position==right.position; } protected: T* position; }; protected: void checkIndex(int theIndex)const; T* element; int arrayLength; int listSize; }; template<class T> arrayList<T>::arrayList(int initialCapacity){ if(initialCapacity<1){ ostringstream s; s<<"Initial capacity = "<<initialCapacity<<" Must be > 0"; throw illegalParameterValue(s.str()); } arrayLength=initialCapacity; element=new T[arrayLength]; listSize=0; } template<class T> arrayList<T>::arrayList(const arrayList<T>& theList){ arrayLength=theList.arrayLength; listSize=theList.listSize; element=new T[arrayLength]; copy(theList.element,theList.element+listSize,element); } template<class T> void arrayList<T>::checkIndex(int theIndex)const{ if(theIndex<0 || theIndex>=listSize){ ostringstream s; s<<"index = "<<theIndex<<" size = "<<listSize; throw illegalIndex(s.str()); } } template<class T> T& arrayList<T>::get(int theIndex)const{ checkIndex(theIndex); return element[theIndex]; } template<class T> int arrayList<T>::indexOf(const T& theElement)const{ for(int i=0;i<listSize;i++) if(element[i]==theElement){ return i; } return -1; } template<class T> void arrayList<T>::erase(int theIndex){ for(int i=theIndex+1;i<listSize;i++) element[i-1]=element[i]; listSize--; } template<class T> void arrayList<T>::insert(int theIndex,const T& theElement){ if(theIndex<0 || theIndex>listSize){ ostringstream s; s<<"index = "<<theIndex<<" size = "<<listSize; throw illegalIndex(s.str()); } if(listSize==arrayLength){ changeLength1D(element,arrayLength,2*arrayLength); arrayLength*=2; } for(int i=listSize-1;i>=theIndex;i--) element[i+1]=element[i]; element[theIndex]=theElement; listSize++; } template<class T> ostream & operator << (ostream& out,const arrayList<T>& x){ for(int i=0;i<x.listSize;i++) out<<x.element[i]<<" "; out<<endl; return out; } template<class T> void arrayList<T>::reSet(int newSize){ if(newSize>arrayLength){ delete []element; element=new T[newSize]; arrayLength=newSize; } listSize=newSize; } template<class T> void arrayList<T>::set(int theIndex,T& theElement){ checkIndex(theIndex); element[theIndex]=theElement; } template<class T> void arrayList<T>::clear(){ listSize=0; } template<class T> arrayList<T>& arrayList<T>::operator = (const arrayList<T> &a){ listSize=a.listSize; arrayLength=a.arrayLength; delete []element; element=new T[a.arrayLength]; copy(a.element,a.element+listSize,element); return *this; } template<class T> class sparseMatrix{ public: void transpose(sparseMatrix<T> &b); sparseMatrix<T> transpose(); istream& input(istream & in); sparseMatrix<T> operator + (sparseMatrix<T> &b); sparseMatrix<T> operator * (sparseMatrix<T> &b); sparseMatrix<T>& operator = (const sparseMatrix<T> &b); template<class U> friend ostream & operator <<(ostream &out,sparseMatrix<U>& x); template<class U> friend istream & operator >>(istream &in,sparseMatrix<U>& x);int rows,cols; private: arrayList<matrixTerm<T> > terms; }; template<class T> sparseMatrix<T>& sparseMatrix<T>::operator=(const sparseMatrix<T>& b){ rows=b.rows; cols=b.cols; terms=b.terms; return *this; } template<class T> sparseMatrix<T> sparseMatrix<T>::transpose(){ sparseMatrix<T> b; b.cols=rows; b.rows=cols; b.terms.reSet(terms.size()); int* colSize=new int[cols+1]; int* rowNext=new int[cols+1]; for(int i=1;i<=cols;i++)colSize[i]=0; for(arrayList<matrixTerm<int> >::iterator i=terms.begin();i!=terms.end();i++) colSize[(*i).col]++; rowNext[1]=0; for(int i=2;i<=cols;i++) rowNext[i]=rowNext[i-1]+colSize[i-1]; matrixTerm<T> mTerm; for(arrayList<matrixTerm<int> >::iterator i=terms.begin();i!=terms.end();i++){ int j=rowNext[(*i).col]++; mTerm.row=(*i).col; mTerm.col=(*i).row; mTerm.value=(*i).value; b.terms.set(j,mTerm); } return b; } template<class T> sparseMatrix<T> sparseMatrix<T>::operator + (sparseMatrix<T> &b){ if(rows!=b.rows || cols!=b.cols){ cout<<"-1"<<endl; return b; } sparseMatrix<T> c; c.rows=rows; c.cols=cols; c.terms.clear(); int cSize=0; arrayList<matrixTerm<int> >::iterator it=terms.begin(); arrayList<matrixTerm<int> >::iterator ib=b.terms.begin(); arrayList<matrixTerm<int> >::iterator itend=terms.end(); arrayList<matrixTerm<int> >::iterator ibend=b.terms.end(); while(it!=itend && ib!=ibend){ int tIndex=(*it).row*cols + (*it).col; int bIndex=(*ib).row*cols + (*ib).col; if(tIndex<bIndex){ c.terms.insert(cSize++,*it); it++; } else if(tIndex==bIndex){ if((*it).value+(*ib).value!=0){ matrixTerm<T> tmp; tmp.col=(*it).col; tmp.row=(*it).row; tmp.value=(*it).value+(*ib).value; c.terms.insert(cSize++,tmp); }it++;ib++; } else { c.terms.insert(cSize++,*ib); ib++; } } while(it!=itend){c.terms.insert(cSize++,*it);it++;} while(ib!=ibend){c.terms.insert(cSize++,*ib);ib++;} return c; } template<class T> sparseMatrix<T> sparseMatrix<T>::operator * (sparseMatrix<T>& b){ if(cols!=b.rows){ cout<<"-1"<<endl; return b; } sparseMatrix<T> c; c.rows=rows; c.cols=b.cols; c.terms.clear(); int cSize=0; b=b.transpose(); int *rowSize=new int[rows+1]; int *colNext=new int[rows+1]; int *rowSizeb=new int[b.rows+1]; int *colNextb=new int[b.rows+1]; for(int i=1;i<=rows;i++)rowSize[i]=0; for(arrayList<matrixTerm<int> >::iterator i=terms.begin();i!=terms.end();i++) rowSize[(*i).row]++; colNext[1]=0; for(int i=2;i<=rows;i++) colNext[i]=colNext[i-1]+rowSize[i-1]; for(int i=1;i<=b.rows;i++)rowSizeb[i]=0; for(arrayList<matrixTerm<int> >::iterator i=b.terms.begin();i!=b.terms.end();i++) rowSizeb[(*i).row]++; colNextb[1]=0; for(int i=2;i<=b.rows;i++) colNextb[i]=colNextb[i-1]+rowSizeb[i-1]; for(int i=1;i<=rows;i++){ for(int j=1;j<=b.rows;j++){ int tmp=0; int k=colNext[i],l=colNextb[j]; while(k<colNext[i]+rowSize[i] && l<colNextb[j]+rowSizeb[j]){ if(terms.get(k).col==b.terms.get(l).col){ tmp+=terms.get(k).value * b.terms.get(l).value; k++;l++; } else if(terms.get(k).col<b.terms.get(l).col){k++;} else l++; } if(tmp!=0){ matrixTerm<T> t; t.row=i;t.col=j;t.value=tmp; c.terms.insert(cSize++,t); } } } return c; } template<class T> istream & operator >> (istream & in,sparseMatrix<T> &a){ in>>a.rows>>a.cols; a.terms.clear(); T values; int Size=0; matrixTerm<T> t; for(int i=1;i<=a.rows;i++){ for(int j=1;j<=a.cols;j++){ in>>values; t.row=i;t.col=j;t.value=values; if(values!=0)a.terms.insert(Size++,t); } } return in; } template<class T> istream& sparseMatrix<T>::input(istream & in){ int Size; in>>rows>>cols>>Size; terms.reSet(Size); matrixTerm<T> mTerm; for(int i=0;i<Size;i++){ in>>mTerm.row>>mTerm.col>>mTerm.value; terms.set(i,mTerm); } return in; } template<class T> ostream & operator << (ostream & out,sparseMatrix<T> &a){ out<<a.rows<<" "<<a.cols<<endl; arrayList<matrixTerm<int> >::iterator it=a.terms.begin(); for(int i=1;i<=a.rows;i++){ for(int j=1;j<=a.cols;j++){ if(it!=a.terms.end() && (*it).col==j && (*it).row==i){ out<<(*it).value<<" "; it++; } else out<<"0 "; } out<<endl; } return out; } int main(){ int w,op; cin>>w; sparseMatrix<int> p,q; while(w--){ cin>>op; switch(op){ case 1:cin>>p;break; case 2:q.input(cin);p=p*q;break; case 3:q.input(cin);p=p+q;break; case 4:cout<<p;break; default:p=p.transpose();break; } } return 0; }
#include<iostream> #include<cstring> #include<sstream> using namespace std; class illegalParameterValue{ public: illegalParameterValue():message("Illegal parameter value"){} illegalParameterValue(string theMessage){message=theMessage;} void illegalIndex(string theMessage){message=theMessage;} private: string message; }; class illegalIndex{ public: illegalIndex():message("Illegal index"){} illegalIndex(string theMessage){message=theMessage;} private: string message; }; template<class T> void changeLength1D(T* &a,int oldLength,int newLength){//扩大数组长度 if(newLength<0) throw illegalParameterValue("new length must be >= 0"); T* temp=new T[newLength]; int number=min(oldLength,newLength); copy(a,a+number,temp); delete []a; a=temp; } template<class T> class matrixTerm{//存储一个非零元素所在的行、列以及它的值 public: int row,col; T value; operator T() const {return value;} matrixTerm<T> operator = (const matrixTerm<T> &x){ row=x.row;col=x.col;value=x.value; return *this; } }; template<class T> class linearList{ public: virtual ~linearList(){}; virtual bool empty()const=0; virtual int size()const=0; virtual T& get(int theIndex)const =0; virtual int indexOf(const T& theElement)const=0; virtual void erase(int theIndex)=0; virtual void insert(int theIndex,const T& theElement)=0; }; template<class T> class arrayList:public linearList<T>{ public: arrayList(int initialCapacity=10); arrayList(const arrayList<T>&); ~arrayList(){delete []element;} bool empty()const{return listSize==0;} int size()const{return listSize;} T& get(int theIndex)const; int indexOf(const T& theElement)const; void erase(int theIndex); void insert(int theIndex,const T& theElement); int capacity()const{return arrayLength;} arrayList& operator = (const arrayList<T> &a); template<class U> friend ostream & operator << (ostream& out,const arrayList<U> &); void reSet(int newSize); void set(int theIndex,T& theElement); void clear(); class iterator; iterator begin(){return iterator(element);} iterator end(){return iterator(element+listSize);} class iterator { public: typedef bidirectional_iterator_tag iterator_category;//迭代器类型 typedef T value_type;//元素值类型 typedef ptrdiff_t difference_type;//差值类型 typedef T* pointer;//指向元素的指针类型 typedef T& reference;//引用类型 iterator(T* thePosition=0){position=thePosition;}//构造函数 T& operator* ()const{return *position;}//解引用操作符 T* operator->()const{return &*position;} iterator & operator ++(){++position;return *this;}//前加 iterator operator ++ (int){ iterator old=*this; ++position; return old; } iterator & operator --(){--position;return *this;}//后加 iterator operator --(int){ iterator old=*this; --position; return old; } bool operator != (const iterator right) const{//测试是否相等 return position!=right.position; } bool operator == (const iterator right)const { return position==right.position; } protected: T* position;//指向元素的指针 }; protected: void checkIndex(int theIndex)const; T* element; int arrayLength; int listSize; }; template<class T> arrayList<T>::arrayList(int initialCapacity){//构造函数 if(initialCapacity<1){ ostringstream s; s<<"Initial capacity = "<<initialCapacity<<" Must be > 0"; throw illegalParameterValue(s.str()); } arrayLength=initialCapacity; element=new T[arrayLength]; listSize=0; } template<class T> arrayList<T>::arrayList(const arrayList<T>& theList){//复制构造函数 arrayLength=theList.arrayLength; listSize=theList.listSize; element=new T[arrayLength]; copy(theList.element,theList.element+listSize,element); } template<class T> void arrayList<T>::checkIndex(int theIndex)const{//确定索引在0和listSize-1之间 if(theIndex<0 || theIndex>=listSize){ ostringstream s; s<<"index = "<<theIndex<<" size = "<<listSize; throw illegalIndex(s.str()); } } template<class T> T& arrayList<T>::get(int theIndex)const{//返回索引为theIndex的元素,若此元素不存在,则抛出异常 checkIndex(theIndex); return element[theIndex]; } template<class T> int arrayList<T>::indexOf(const T& theElement)const{//返回元素theElement第一次出现的索引,若该元素不存在,则返回-1 for(int i=0;i<listSize;i++) if(element[i]==theElement){ return i; } return -1; } template<class T> void arrayList<T>::erase(int theIndex){//删除索引为theIndex的元素,若该元素不存在,则抛出异常 for(int i=theIndex+1;i<listSize;i++) element[i-1]=element[i]; listSize--; } template<class T> void arrayList<T>::insert(int theIndex,const T& theElement){//在索引theIndex处插入元素theElement if(theIndex<0 || theIndex>listSize){//无效索引 ostringstream s; s<<"index = "<<theIndex<<" size = "<<listSize; throw illegalIndex(s.str()); } if(listSize==arrayLength){//有效索引,判断数组是否已满 changeLength1D(element,arrayLength,2*arrayLength);//数组空间已满,数组长度倍增 arrayLength*=2; } for(int i=listSize-1;i>=theIndex;i--)//把元素向右移动一个位置 element[i+1]=element[i]; element[theIndex]=theElement; listSize++; } template<class T> ostream & operator << (ostream& out,const arrayList<T>& x){//重载<< for(int i=0;i<x.listSize;i++) out<<x.element[i]<<" "; out<<endl; return out; } template<class T> void arrayList<T>::reSet(int newSize){//把数组的元素个数改为newSize,必要时增大数组容量 if(newSize>arrayLength){ delete []element; element=new T[newSize]; arrayLength=newSize; } listSize=newSize; } template<class T> void arrayList<T>::set(int theIndex,T& theElement){//使元素theElement成为表中索引为theIndex的元素 checkIndex(theIndex); element[theIndex]=theElement; } template<class T> void arrayList<T>::clear(){//使表中的元素个数为0 listSize=0; } template<class T> arrayList<T>& arrayList<T>::operator = (const arrayList<T> &a){//重载= listSize=a.listSize; arrayLength=a.arrayLength; delete []element; element=new T[a.arrayLength]; copy(a.element,a.element+listSize,element); return *this; } template<class T> class sparseMatrix{ public: sparseMatrix<T> transpose();//转置函数 istream& input(istream & in);//输入函数,输入稀疏矩阵中每个非零元素 sparseMatrix<T> operator + (sparseMatrix<T> &b);//重载+ sparseMatrix<T> operator * (sparseMatrix<T> &b);//重载* sparseMatrix<T>& operator = (const sparseMatrix<T> &b);//重载* template<class U> friend ostream & operator <<(ostream &out,sparseMatrix<U>& x);//重载<<,用来输入稀疏矩阵中的每个元素,包括0元素 template<class U> friend istream & operator >>(istream &in,sparseMatrix<U>& x);//重载>>,用来输出稀疏矩阵中的每个元素,包括0元素 private: int rows,cols;//矩阵的行数、列数 arrayList<matrixTerm<T> > terms;//矩阵非零项数 }; template<class T> sparseMatrix<T>& sparseMatrix<T>::operator=(const sparseMatrix<T>& b){//重载= rows=b.rows; cols=b.cols; terms=b.terms;//这里直接调用arrayList的重载函数 return *this; } template<class T> sparseMatrix<T> sparseMatrix<T>::transpose(){//转置函数 sparseMatrix<T> b;//定义一个用于存储答案的稀疏矩阵类 b.cols=rows; b.rows=cols; b.terms.reSet(terms.size());//将b初始化为cols行rows列,有terms.size()个非零元的稀疏矩阵 int* colSize=new int[cols+1];//colSize[i]是输入矩阵第i列的非零元素的个数 int* rowNext=new int[cols+1];//rowNext[i]是转置矩阵第i行首个非零元素在b中的索引 for(int i=1;i<=cols;i++)colSize[i]=0; for(arrayList<matrixTerm<int> >::iterator i=terms.begin();i!=terms.end();i++) colSize[(*i).col]++; rowNext[1]=0; for(int i=2;i<=cols;i++) rowNext[i]=rowNext[i-1]+colSize[i-1]; matrixTerm<T> mTerm; for(arrayList<matrixTerm<int> >::iterator i=terms.begin();i!=terms.end();i++){ int j=rowNext[(*i).col]++;//rowNext[i]的值是b矩阵中第0行至第i-1行的元素个数 mTerm.row=(*i).col; mTerm.col=(*i).row; mTerm.value=(*i).value; b.terms.set(j,mTerm); } return b;//返回转置后的稀疏矩阵 } template<class T> sparseMatrix<T> sparseMatrix<T>::operator + (sparseMatrix<T> &b){//重载+ if(rows!=b.rows || cols!=b.cols){//判断运算是否合法 cout<<"-1"<<endl; return b; } sparseMatrix<T> c;//设置稀疏矩阵c的特征 c.rows=rows; c.cols=cols; c.terms.clear(); int cSize=0; arrayList<matrixTerm<int> >::iterator it=terms.begin();//定义*this和b的迭代器 arrayList<matrixTerm<int> >::iterator ib=b.terms.begin(); arrayList<matrixTerm<int> >::iterator itend=terms.end(); arrayList<matrixTerm<int> >::iterator ibend=b.terms.end(); while(it!=itend && ib!=ibend){//遍历*this和b,把相关的项相加 int tIndex=(*it).row*cols + (*it).col;//求出行主映射下两个点的编号 int bIndex=(*ib).row*cols + (*ib).col; if(tIndex<bIndex){//b项在后 c.terms.insert(cSize++,*it); it++; } else if(tIndex==bIndex){//两项在同一个位置 if((*it).value+(*ib).value!=0){ matrixTerm<T> tmp; tmp.col=(*it).col; tmp.row=(*it).row; tmp.value=(*it).value+(*ib).value; c.terms.insert(cSize++,tmp); }it++;ib++; } else {//*this项在后 c.terms.insert(cSize++,*ib); ib++; } } while(it!=itend){c.terms.insert(cSize++,*it);it++;}//复制剩余项 while(ib!=ibend){c.terms.insert(cSize++,*ib);ib++;} return c; } template<class T> sparseMatrix<T> sparseMatrix<T>::operator * (sparseMatrix<T>& b){//重载* if(cols!=b.rows){//判断运算是否合法 cout<<"-1"<<endl; return b; } sparseMatrix<T> c;//定义一个存储答案的稀疏矩阵对象 c.rows=rows;//设置稀疏矩阵c的特征 c.cols=b.cols; c.terms.clear(); int cSize=0; b=b.transpose();//将矩阵b转置,则矩阵乘法转化为*this矩阵的每一行乘以矩阵b的每一行 int *rowSize=new int[rows+1];//rowSize[i]表示*this矩阵第i行中非零元的个数 int *colNext=new int[rows+1];//colNext[i]表示*this矩阵第i行的首个非零元素在*this中的索引 int *rowSizeb=new int[b.rows+1];//rowSizeb[i]表示b矩阵第i行中非零元的个数 int *colNextb=new int[b.rows+1];//colNextb[i]表示b矩阵第i行的首个非零元素在b中的索引 //处理这四个数组 for(int i=1;i<=rows;i++)rowSize[i]=0; for(arrayList<matrixTerm<int> >::iterator i=terms.begin();i!=terms.end();i++) rowSize[(*i).row]++; colNext[1]=0; for(int i=2;i<=rows;i++) colNext[i]=colNext[i-1]+rowSize[i-1]; for(int i=1;i<=b.rows;i++)rowSizeb[i]=0; for(arrayList<matrixTerm<int> >::iterator i=b.terms.begin();i!=b.terms.end();i++) rowSizeb[(*i).row]++; colNextb[1]=0; for(int i=2;i<=b.rows;i++) colNextb[i]=colNextb[i-1]+rowSizeb[i-1]; //进行矩阵乘法 for(int i=1;i<=rows;i++){//枚举*this的每一行 for(int j=1;j<=b.rows;j++){//枚举b的每一列 int tmp=0; int k=colNext[i],l=colNextb[j];//k和l分别表示*this和b中枚举到的位置 while(k<colNext[i]+rowSize[i] && l<colNextb[j]+rowSizeb[j]){ if(terms.get(k).col==b.terms.get(l).col){//两个位置的列号相等 tmp+=terms.get(k).value * b.terms.get(l).value; k++;l++; } else if(terms.get(k).col<b.terms.get(l).col){k++;}//k的列号落后 else l++;//b的列号落后 } if(tmp!=0){//记录答案矩阵的第i行第j列 matrixTerm<T> t; t.row=i;t.col=j;t.value=tmp; c.terms.insert(cSize++,t); } } } return c; } template<class T> istream & operator >> (istream & in,sparseMatrix<T> &a){ in>>a.rows>>a.cols; a.terms.clear(); T values; int Size=0; matrixTerm<T> t; for(int i=1;i<=a.rows;i++){ for(int j=1;j<=a.cols;j++){ in>>values; t.row=i;t.col=j;t.value=values; if(values!=0)a.terms.insert(Size++,t); } } return in; } template<class T> istream& sparseMatrix<T>::input(istream & in){ int Size; in>>rows>>cols>>Size; terms.reSet(Size); matrixTerm<T> mTerm; for(int i=0;i<Size;i++){ in>>mTerm.row>>mTerm.col>>mTerm.value; terms.set(i,mTerm); } return in; } template<class T> ostream & operator << (ostream & out,sparseMatrix<T> &a){ out<<a.rows<<" "<<a.cols<<endl; arrayList<matrixTerm<int> >::iterator it=a.terms.begin(); for(int i=1;i<=a.rows;i++){ for(int j=1;j<=a.cols;j++){ if(it!=a.terms.end() && (*it).col==j && (*it).row==i){//这里需要加上it!=a.terms.end(),否则会有错误答案 out<<(*it).value<<" "; it++; } else out<<"0 "; } out<<endl; } return out; } int main(){ int w,op; cin>>w; sparseMatrix<int> p,q; while(w--){ cin>>op; switch(op){ case 1:cin>>p;break; case 2:q.input(cin);p=p*q;break; case 3:q.input(cin);p=p+q;break; case 4:cout<<p;break; default:p=p.transpose();break; } } return 0; }
实验六-栈
/* 一个栈的做法中,栈中的每个元素代表一个括号整体,比如下面这个式子 ((a+b)*c+(d+e)) 栈的第一层(栈底)是((a+b)*c+(d+e)) 第二层是(a+b) 第三层是(d+e) 很显然,需要从栈顶到栈底依次计算括号里的值,满足栈的特征 所以每当遇到左括号就push一个元素,遇到右括号就弹出一个元素,而计算时,只需要取出栈顶元素,然后进行更新后再放回去就可以 */ #include<iostream> #include<cstdio> #include<cstring> #include<sstream> #include<iomanip> using namespace std; class illegalParameterValue{ public: illegalParameterValue():message("Illegal parameter value"){} illegalParameterValue(string theMessage){message=theMessage;} void illegalIndex(string theMessage){message=theMessage;} private: string message; }; class stackEmpty{ public: stackEmpty():message("Stack is empty."){} stackEmpty(string theMessage){message=theMessage;} private: string message; }; template<class T> void changeLength1D(T* &a,int oldLength,int newLength){//扩大数组长度 if(newLength<0) throw illegalParameterValue("new length must be >= 0"); T* temp=new T[newLength]; int number=min(oldLength,newLength); copy(a,a+number,temp); delete []a; a=temp; } struct node{ node(){ans=0;p=1;} node(double _ans,double _p,char _op):ans(_ans),p(_p),op(_op){} double ans,p;//ans存储当前答案,p存储了一个缓冲值,由'+'或'-'将p更新到答案内,比如1*3+2*4+3*5,ans存储的是(1*3+2*4)=11,p存储的是3*5=15 char op;//距离当前位置最近的操作符 }; template<class T> class stack{ public: virtual ~stack(){} virtual bool empty()const=0; virtual int size()const=0; virtual T& top()=0; virtual void pop()=0; virtual void push(const T& theElement)=0; }; template<class T> class arrayStack:public stack<T>{ public: arrayStack(int initialCapacity=10); ~arrayStack(){delete []stack;} bool empty()const{return stackTop==-1;} int size()const{return stackTop+1;} T& top(){ if(stackTop==-1) throw stackEmpty(); return stack[stackTop]; } void pop(){ if(stackTop==-1) throw stackEmpty(); stackTop--; } void push(const T& theElement); private: int stackTop;//当前栈顶 int arrayLength;//栈容量 T *stack;//元素数组 }; template<class T> arrayStack<T>::arrayStack(int initialCapacity){ stack=new T[initialCapacity]; stackTop=-1; arrayLength=initialCapacity; } template<class T> void arrayStack<T>::push(const T& theElement){ if(stackTop==arrayLength){ changeLength1D(stack,arrayLength,arrayLength*2); arrayLength*=2; } stack[++stackTop]=theElement; }; void work(){ string s; arrayStack<node> st; cin>>s; s="("+s+")"; int len=s.length(); bool flag=0; double ans=0; for(int i=0;i<len;i++){ if(s[i]==')'){//遇到右括号,弹出这对括号内的值 double ansnow=st.top().ans+st.top().p;//把答案和缓冲值相加,作为此段表达式的值 st.pop();//扔掉这对括号内所有的值,因为这对括号已经计算完毕,有用的值已经存储到ansnow里了 if(st.empty()){//如果为空,说明已经扔掉的这对括号是最外层的括号,也就是表达式已经计算完了 ans=ansnow;//得到最终答案 break; } node newTop=st.top();//取出当前栈顶的元素,进行更新 st.pop(); switch(newTop.op){//距离当前数字最近的操作符 case '+':newTop.ans+=newTop.p;newTop.p=ansnow;break;//如果是加减法,则将缓冲值加入到当前的答案中 case '-':newTop.ans+=newTop.p;newTop.p=-1*ansnow;break;//然后将ansnow作为缓冲值放到p中 case '*':newTop.p*=ansnow;break;//如果是乘除运算符,就直接在缓冲值p上计算即可 case '/':newTop.p/=ansnow;break; case '$':newTop.p*=ansnow;break;//如果是'$',说明当前ansnow的位置是在括号内的第一个位置,前面没有+-*/运算,就直接加入到缓存中,用乘法而不直接赋值是考虑到(-(a+b)+c)这种情况 } st.push(newTop);//更新栈顶的ans } else if(s[i]=='('){ st.push(node(0,1,'$')); } else if(s[i]=='+' || s[i]=='-' || s[i]=='*' || s[i]=='/'){ node newTop=st.top(); st.pop(); if(s[i-1]=='('){//标记一下符号位(不是运算符),s[i-1]=='('说明这个为"(-1"这种形式 newTop.p=-1;//直接将临时变量置为-1 st.push(newTop); continue; } newTop.op=s[i]; st.push(newTop); } else { double x=0; while(s[i]<='9' && s[i]>='0'){ x=x*10+s[i]-'0'; i++; } i--; node newTop=st.top(); st.pop(); if(flag){ newTop.p=-1*x; flag=0; } else if(newTop.op=='+' || newTop.op=='-'){ newTop.ans+=newTop.p; if(newTop.op=='-')newTop.p=-1*x; else newTop.p=1*x; } else if(newTop.op=='*') newTop.p*=x; else if(newTop.op=='/') newTop.p/=x; else newTop.p*=x; st.push(newTop); } } printf("%.2f\n",ans); } int main(){ // freopen("Cola.txt","r",stdin); int T; cin>>T; while(T--){ work(); } return 0; }
#include<iostream> #include<cstdio> #include<cstring> #include<sstream> #include<iomanip> using namespace std; class illegalParameterValue{ public: illegalParameterValue():message("Illegal parameter value"){} illegalParameterValue(string theMessage){message=theMessage;} void illegalIndex(string theMessage){message=theMessage;} private: string message; }; class stackEmpty{ public: stackEmpty():message("Stack is empty."){} stackEmpty(string theMessage){message=theMessage;} private: string message; }; template<class T> void changeLength1D(T* &a,int oldLength,int newLength){//扩大数组长度 if(newLength<0) throw illegalParameterValue("new length must be >= 0"); T* temp=new T[newLength]; int number=min(oldLength,newLength); copy(a,a+number,temp); delete []a; a=temp; } template<class T> class stack{ public: virtual ~stack(){} virtual bool empty()const=0; virtual int size()const=0; virtual T& top()=0; virtual void pop()=0; virtual void push(const T& theElement)=0; }; template<class T> class arrayStack:public stack<T>{ public: arrayStack(int initialCapacity=10); ~arrayStack(){delete []stack;} bool empty()const{return stackTop==-1;} int size()const{return stackTop+1;} T& top(){ if(stackTop==-1) throw stackEmpty(); return stack[stackTop]; } void pop(){ if(stackTop==-1) throw stackEmpty(); stackTop--; } void push(const T& theElement); private: int stackTop;//当前栈顶 int arrayLength;//栈容量 T *stack;//元素数组 }; template<class T> arrayStack<T>::arrayStack(int initialCapacity){ stack=new T[initialCapacity]; stackTop=-1; arrayLength=initialCapacity; } template<class T> void arrayStack<T>::push(const T& theElement){ if(stackTop+1==arrayLength){ changeLength1D(stack,arrayLength,arrayLength*2); arrayLength*=2; } stack[++stackTop]=theElement; }; void work(){ string s; arrayStack<double> st1;//设两个栈,st1用来存数字,st2用来存符号 arrayStack<char>st2; cin>>s; s="("+s+")"; int len=s.length(); double ans=0; for(int i=len-1;i>=0;i--){//倒序压入栈,就可以顺序从栈中读取并计算 if(s[i]=='+' || s[i]=='-' ){//当读取到'+''-'运算时,把比它优先级高的'*'和'/'先计算出结果 while(!st2.empty() && ( st2.top()=='*' || st2.top()=='/')){ double op1=st1.top();st1.pop();//取出数字栈中的两个数字和符号栈中的一个符号,进行计算 double op2=st1.top();st1.pop(); switch(st2.top()){ case '*':st1.push(op1*op2);break; case '/':st1.push(op1/op2);break; } st2.pop(); } if(s[i-1]=='('){//当前面的一个字符是左括号时,说明这个负号是符号位,为了避免麻烦,前面加一个0,表示把-a变成0-a double x=st1.top();st1.pop(); st1.push(0); st1.push(x); } st2.push(s[i]); } else if(s[i]=='*' || s[i]=='/' || s[i]==')'){//'*/)'直接压入栈中 st2.push(s[i]); } else if(s[i]=='('){//遇到左括号,直接向下计算,一直到遇到右括号为止 while(st2.top()!=')'){ double op1=st1.top();st1.pop(); double op2=st1.top();st1.pop(); switch(st2.top()){ case '+':st1.push(op1+op2);break; case '-':st1.push(op1-op2);break; case '*':st1.push(op1*op2);break; case '/':st1.push(op1/op2);break; } st2.pop(); } st2.pop(); } else if(s[i]<='9' && s[i]>='0'){//将数字压入数字栈中 double x=0,base=1; while(s[i]<='9' && s[i]>='0'){ x=x+(s[i]-'0')*base; base*=10; i--; } i++; if(i-2>=0 && s[i-1]=='-' && s[i-2]=='('){ x=-x; i--; } st1.push(x); } } ans=st1.top(); printf("%.2f\n",ans); } int main(){ int T; cin>>T; while(T--){ work(); } return 0; }
实验七-队列
#include<iostream> #include<cstdio> #include<cstring> #include<sstream> using namespace std; class illegalParameterValue{ public: illegalParameterValue():message("Illegal parameter value"){} illegalParameterValue(string theMessage){message=theMessage;} void illegalIndex(string theMessage){message=theMessage;} private: string message; }; class queueEmpty{ public: queueEmpty():message("Queue empty"){} queueEmpty(string theMessage){message=theMessage;} private: string message; }; template<class T> class queue{ public: virtual ~queue(){} virtual bool empty()const=0; virtual int size()const=0; virtual T& front()=0; virtual T& back()=0; virtual void pop()=0; virtual void push(const T& theElement)=0; }; template<class T> class arrayQueue:public queue<T>{ public: arrayQueue(int initialCapacity=10); ~arrayQueue(){delete []queue;} bool empty()const{return theFront==theBack;} int size()const{ return (theBack-theFront+arrayLength)%arrayLength; } T& front(){ if(theFront==theBack) throw queueEmpty(); return queue[(theFront+1)%arrayLength]; } T& back(){ if(theFront==theBack) throw queueEmpty(); return queue[theBack]; } void pop(){ if(theFront==theBack) throw queueEmpty(); theFront=(theFront+1)%arrayLength; } void push(const T& theElement); private: int theFront; int theBack; int arrayLength; T *queue; }; template<class T> arrayQueue<T>::arrayQueue(int initialCapacity){ if(initialCapacity<1){ ostringstream s; s<<"Initial capacity = "<<initialCapacity<<" Must be > 0."; throw illegalParameterValue(s.str()); } arrayLength=initialCapacity; queue=new T[arrayLength]; theFront=0; theBack=0; } template<class T> void arrayQueue<T>::push(const T& theElement){ if((theBack+1)%arrayLength==theFront){ T* newQueue=new T[2*arrayLength]; int start=theFront+1; do{ newQueue[start%(arrayLength*2)]=queue[start%arrayLength]; start++; }while(start%arrayLength!=(theBack+1)%arrayLength); theBack=(start-1+arrayLength*2)%(arrayLength*2); arrayLength*=2; queue=newQueue; } theBack=(theBack+1)%arrayLength; queue[theBack]=theElement; } int main(){ int n; cin>>n; arrayQueue<int> q(n); for(int i=1;i<=n;i++){ q.push(i); } while(q.size()>=2){ q.pop(); int now=q.front(); q.pop(); q.push(now); } cout<<q.front()<<endl; return 0; }
实验八-散列表
#include<iostream> #include<cstdio> #include<cstring> #include<sstream> using namespace std; class hashTableFull{ public: hashTableFull():message("hashTable is full."){} hashTableFull(string theMessage){message=theMessage;} private: string message; }; template<class K,class E> class hashTable{ public: hashTable(int theDivisor=11); ~hashTable(){delete []table;} bool empty()const{return dSize==0;} int size()const {return dSize;} int find(const K&)const; void insert(const pair< K,E>&); void output(ostream& out)const; void erase(const K& theKey); protected: int search(const K&)const; pair<K,E>** table; int dSize; int divisor; }; template<class K,class E> hashTable<K,E>::hashTable(int theDivisor){ divisor=theDivisor; dSize=0; table=new pair<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{ int i=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> int hashTable<K,E>::find(const K& theKey)const{ int b=search(theKey); if(table[b]==NULL || table[b]->first!=theKey){ return -1; } return b; } template<class K,class E> void hashTable<K,E>::insert(const pair<K,E>& thePair){ int b=search(thePair.first); if(table[b]==NULL){ table[b]=new pair<K,E>(thePair); dSize++; // cout<<b<<endl; printf("%d\n",b); } else { if(table[b]->first==thePair.first){ table[b]->second=thePair.second; cout<<"Existed"<<endl; } else throw hashTableFull(); } } template<class K,class E> void hashTable<K,E>::output(ostream& out)const{ for(int i=0;i<divisor;i++) if(table[i]==NULL) out<<"NULL"<<endl; else out<<table[i]->first<<" "<<table[i]->second<<endl; } template<class K,class E> ostream& operator<<(ostream & out,const hashTable<K,E>& x){ x.output(out); return out; } template<class K,class E> void hashTable<K,E>::erase(const K& theKey){ int b=search(theKey); if(table[b]==NULL || table[b]->first!=theKey){ cout<<"Not Found"<<endl; return; } int cnt=0,pos=b; for(int i=(b+1)%divisor;i!=b && table[i]!=NULL;i=(i+1)%divisor){ int original=(table[i]->first)%divisor; if((original<=pos && pos<i) || (i<original && original<=pos) || (pos<i && i<original)){ cnt++; swap(table[pos],table[i]); pos=i; } } cout<<cnt<<endl; delete table[pos]; table[pos]=NULL; dSize--; } int main(){ //freopen("Cola.txt","r",stdin); int D,m,opt,x; cin>>D>>m; hashTable<int,int>q(D); for(int i=1;i<=m;i++){ cin>>opt>>x; if(opt==0){ q.insert(pair<int,int>(x,x)); } else if(opt==1){ cout<<q.find(x)<<endl; } else { q.erase(x); } //for(int j=0;j<D;j++)cout<<q.find(j)<<" ";cout<<endl; } return 0; }
#include<iostream> #include<cstdio> #include<cstring> #include<sstream> using namespace std; template<class K,class E> struct pairNode{ typedef pair<K,E> pairType; pairType element; pairNode<K,E>* next; pairNode(const pairType& thePair):element(thePair){} pairNode(const pairType& thePair,pairNode<K,E>* theNext):element(thePair){next=theNext;} }; template<class K,class E> class sortedChain{ public: sortedChain(){firstNode=NULL;dSize=0;} ~sortedChain(); bool empty()const{return dSize==0;} int size()const{return dSize;} pair<K,E>* find(const K&)const; void erase(const K&); void insert(const pair<K,E>&); void output(ostream& out)const; protected: pairNode<K,E>* firstNode; int dSize; }; template<class K,class E> sortedChain<K,E>::~sortedChain(){ while(firstNode!=NULL){ pairNode<K,E>* nextNode=firstNode->next; delete firstNode; firstNode=nextNode; } } template<class K,class E> pair<K,E>* sortedChain<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 ¤tNode->element; } cout<<"Not Found"<<endl; return NULL; } template<class K,class E> void sortedChain<K,E>::insert(const pair<K,E>& thePair){ pairNode<K,E>* p=firstNode; pairNode<K,E>* tp=NULL; while(p!=NULL && p->element.first<thePair.first){ tp=p; p=p->next; } if(p!=NULL && p->element.first==thePair.first){ p->element.second=thePair.second; return; } pairNode<K,E> *newNode=new pairNode<K,E>(thePair,p); if(tp==NULL)firstNode=newNode; else tp->next=newNode; dSize++; return; } template<class K,class E> void sortedChain<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 E> void sortedChain<K,E>::output(ostream& out)const{ for(pairNode<K,E>* i=firstNode;i!=NULL;i=i->next){ out<<i->element.first<<" "<<i->element.second<<" "; } } template<class K,class E> ostream& operator<< (ostream& out,const sortedChain<K,E>& x){ x.output(out);return out; } template<class K,class E> class hashChains{ public: hashChains(int theDivisor=11){ divisor=theDivisor; dSize=0; table=new sortedChain<K,E>[divisor]; } ~hashChains(){delete []table;} bool empty()const{return dSize==0;} int size()const{return dSize;} pair<K,E>* find(const K& theKey)const{ return table[theKey%divisor].find(theKey); } void insert(const pair<K,E>& thePair){ int homeBucket=thePair.first%divisor; int homeSize=table[homeBucket].size(); table[homeBucket].insert(thePair); if(table[homeBucket].size()>homeSize) dSize++; else cout<<"Existed"<<endl; } void erase(const K& theKey){ table[theKey%divisor].erase(theKey); } void output(ostream& out)const{ for(int i=0;i<divisor;i++) if(table[i].size()==0) out<<"NULL"<<endl; else out<<table[i]<<endl; } protected: sortedChain<K,E>* table; int dSize; int divisor; }; template<class K,class E> ostream& operator<<(ostream& out,const hashChains<K,E>& x){ x.output(out); return out; } int main(){ int D,m,opt,x; cin>>D>>m; hashChains<int,int>q(D); for(int i=1;i<=m;i++){ cin>>opt>>x; if(opt==0){ q.insert(pair<int,int>(x,x)); } else if(opt==1){ q.find(x); } else { q.erase(x); } } return 0; }
实验九-二叉树操作
#include<iostream> #include<cstdio> #include<sstream> #include<cstring> using namespace std; class illegalParameterValue{ public: illegalParameterValue():message("Illegal parameter value"){} illegalParameterValue(string theMessage){message=theMessage;} void illegalIndex(string theMessage){message=theMessage;} private: string message; }; int l[100010],r[100010],height[100010],Size[100010]; class queueEmpty{ public: queueEmpty():message("Queue empty"){} queueEmpty(string theMessage){message=theMessage;} private: string message; }; template<class T> class queue{ public: virtual ~queue(){} virtual bool empty()const=0; virtual int size()const=0; virtual T& front()=0; virtual T& back()=0; virtual void pop()=0; virtual void push(const T& theElement)=0; }; template<class T> class arrayQueue:public queue<T>{ public: arrayQueue(int initialCapacity=10); ~arrayQueue(){delete []queue;} bool empty()const{return theFront==theBack;} int size()const{ return (theBack-theFront+arrayLength)%arrayLength; } T& front(){ if(theFront==theBack) throw queueEmpty(); return queue[(theFront+1)%arrayLength]; } T& back(){ if(theFront==theBack) throw queueEmpty(); return queue[theBack]; } void pop(){ if(theFront==theBack) throw queueEmpty(); theFront=(theFront+1)%arrayLength; } void push(const T& theElement); private: int theFront; int theBack; int arrayLength; T *queue; }; template<class T> arrayQueue<T>::arrayQueue(int initialCapacity){ if(initialCapacity<1){ ostringstream s; s<<"Initial capacity = "<<initialCapacity<<" Must be > 0."; throw illegalParameterValue(s.str()); } arrayLength=initialCapacity; queue=new T[arrayLength]; theFront=0; theBack=0; } template<class T> void arrayQueue<T>::push(const T& theElement){ if((theBack+1)%arrayLength==theFront){ T* newQueue=new T[2*arrayLength]; int start=theFront+1; do{ newQueue[start%(arrayLength*2)]=queue[start%arrayLength]; start++; }while(start%arrayLength!=(theBack+1)%arrayLength); theBack=(start-1+arrayLength*2)%(arrayLength*2); arrayLength*=2; queue=newQueue; } theBack=(theBack+1)%arrayLength; queue[theBack]=theElement; } template<class T> struct binaryTreeNode{ T element; binaryTreeNode<T> *leftChild,*rightChild; binaryTreeNode(){leftChild=rightChild=NULL;} binaryTreeNode(const T& theElement):element(theElement){ leftChild=rightChild=NULL; } binaryTreeNode(const T& theElement,binaryTreeNode *theLeftChild,binaryTreeNode *theRightChild){ element=theElement; leftChild=theLeftChild; rightChild=theRightChild; } }; template<class T> void visit(binaryTreeNode<T> *t){ cout<<t->element<<" "; } template<class T> void preOrder(binaryTreeNode<T> *t){ if(t!=NULL){ visit(t); preOrder(t->leftChild); preOrder(t->rightChild); } } template<class T> void inOrder(binaryTreeNode<T> *t){ if(t!=NULL){ inOrder(t->leftChild); visit(t); inOrder(t->rightChild); } } template<class T> void postOrder(binaryTreeNode<T> *t){ if(t!=NULL){ postOrder(t->leftChild); postOrder(t->rightChild); visit(t); } } template<class T> void levelOrder(binaryTreeNode<T> *t){ arrayQueue<binaryTreeNode<T>*> q; q.push(t); while(!q.empty()){ t=q.front();q.pop(); visit(t); if(t->leftChild!=NULL)q.push(t->leftChild); if(t->rightChild!=NULL)q.push(t->rightChild); } } template<class T> class BinaryTree{ public: BinaryTree(binaryTreeNode<T> *r){root=r;size=1;} BinaryTree(){root=NULL;size=0;} binaryTreeNode<T>* Root(){return root;} void build(binaryTreeNode<T>* root); void tr_levelOrder(){ levelOrder(root); cout<<endl; } void count(binaryTreeNode<T>* root); private: binaryTreeNode<T> *root; int size; }; template<class T> void BinaryTree<T>::build(binaryTreeNode<T>* now){ // cout<<now->element<<endl; if(l[now->element]!=-1){ now->leftChild=new binaryTreeNode<int> (l[now->element]); size++; build(now->leftChild); } if(r[now->element]!=-1){ now->rightChild=new binaryTreeNode<int> (r[now->element]); size++; build(now->rightChild); } } template<class T> void BinaryTree<T>::count(binaryTreeNode<T>* now){ Size[now->element]=1; height[now->element]=1; int lh=0,rh=0; if(now->leftChild!=NULL){ count(now->leftChild); Size[now->element]+=Size[now->leftChild->element]; lh=height[now->leftChild->element]; } if(now->rightChild!=NULL){ count(now->rightChild); Size[now->element]+=Size[now->rightChild->element]; rh=height[now->rightChild->element]; } height[now->element]=max(lh,rh)+1; } int main(){ int n; cin>>n; for(int i=1;i<=n;i++){ cin>>l[i]>>r[i]; } binaryTreeNode<int> *root; root=new binaryTreeNode<int>(1); BinaryTree<int> tree(root); tree.build(root); tree.tr_levelOrder(); tree.count(root); for(int i=1;i<=n;i++) cout<<Size[i]<<" "; cout<<endl; for(int i=1;i<=n;i++) cout<<height[i]<<" "; cout<<endl; return 0; }
#include<iostream> #include<cstdio> #include<sstream> #include<cstring> using namespace std; class illegalParameterValue{ public: illegalParameterValue():message("Illegal parameter value"){} illegalParameterValue(string theMessage){message=theMessage;} void illegalIndex(string theMessage){message=theMessage;} private: string message; }; int l[100010],r[100010],height[100010],Size[100010]; class queueEmpty{ public: queueEmpty():message("Queue empty"){} queueEmpty(string theMessage){message=theMessage;} private: string message; }; template<class T> class queue{ public: virtual ~queue(){} virtual bool empty()const=0; virtual int size()const=0; virtual T& front()=0; virtual T& back()=0; virtual void pop()=0; virtual void push(const T& theElement)=0; }; template<class T> class arrayQueue:public queue<T>{ public: arrayQueue(int initialCapacity=10); ~arrayQueue(){delete []queue;} bool empty()const{return theFront==theBack;} int size()const{ return (theBack-theFront+arrayLength)%arrayLength; } T& front(){ if(theFront==theBack) throw queueEmpty(); return queue[(theFront+1)%arrayLength]; } T& back(){ if(theFront==theBack) throw queueEmpty(); return queue[theBack]; } void pop(){ if(theFront==theBack) throw queueEmpty(); theFront=(theFront+1)%arrayLength; } void push(const T& theElement); private: int theFront; int theBack; int arrayLength; T *queue; }; template<class T> arrayQueue<T>::arrayQueue(int initialCapacity){ if(initialCapacity<1){ ostringstream s; s<<"Initial capacity = "<<initialCapacity<<" Must be > 0."; throw illegalParameterValue(s.str()); } arrayLength=initialCapacity; queue=new T[arrayLength]; theFront=0; theBack=0; } template<class T> void arrayQueue<T>::push(const T& theElement){ if((theBack+1)%arrayLength==theFront){ T* newQueue=new T[2*arrayLength]; int start=theFront+1; do{ newQueue[start%(arrayLength*2)]=queue[start%arrayLength]; start++; }while(start%arrayLength!=(theBack+1)%arrayLength); theBack=(start-1+arrayLength*2)%(arrayLength*2); arrayLength*=2; queue=newQueue; } theBack=(theBack+1)%arrayLength; queue[theBack]=theElement; } template<class T> struct binaryTreeNode{ T element; binaryTreeNode<T> *leftChild,*rightChild; binaryTreeNode(){leftChild=rightChild=NULL;} binaryTreeNode(const T& theElement):element(theElement){ leftChild=rightChild=NULL; } binaryTreeNode(const T& theElement,binaryTreeNode *theLeftChild,binaryTreeNode *theRightChild){ element=theElement; leftChild=theLeftChild; rightChild=theRightChild; } }; template<class T> void visit(binaryTreeNode<T> *t){ cout<<t->element<<" "; } template<class T> void preOrder(binaryTreeNode<T> *t,void (*op)(binaryTreeNode<T>*)){ if(t!=NULL){ op(t); preOrder(t->leftChild,op); preOrder(t->rightChild,op); } } template<class T> void inOrder(binaryTreeNode<T> *t,void (*op)(binaryTreeNode<T>*)){ if(t!=NULL){ inOrder(t->leftChild,op); op(t); inOrder(t->rightChild,op); } } template<class T> void postOrder(binaryTreeNode<T> *t,void (*op)(binaryTreeNode<T>*)){ if(t!=NULL){ postOrder(t->leftChild,op); postOrder(t->rightChild,op); op(t); } } template<class T> void levelOrder(binaryTreeNode<T> *t,void (*op)(binaryTreeNode<T>*)){ arrayQueue<binaryTreeNode<T>*> q; q.push(t); while(!q.empty()){ t=q.front();q.pop(); op(t); if(t->leftChild!=NULL)q.push(t->leftChild); if(t->rightChild!=NULL)q.push(t->rightChild); } } template<class T> class BinaryTree{ public: BinaryTree(binaryTreeNode<T> *r){root=r;size=1;} BinaryTree(){root=NULL;size=0;} ~BinaryTree(); binaryTreeNode<T>* Root(){return root;} void build(binaryTreeNode<T>* root); void count(binaryTreeNode<T>* root); static void dispose(binaryTreeNode<T> *t) {delete t;} private: binaryTreeNode<T> *root; int size; }; template<class T> void BinaryTree<T>::build(binaryTreeNode<T>* now){ // cout<<now->element<<endl; if(l[now->element]!=-1){ now->leftChild=new binaryTreeNode<int> (l[now->element]); size++; build(now->leftChild); } if(r[now->element]!=-1){ now->rightChild=new binaryTreeNode<int> (r[now->element]); size++; build(now->rightChild); } } template<class T> void BinaryTree<T>::count(binaryTreeNode<T>* now){ Size[now->element]=1; height[now->element]=1; int lh=0,rh=0; if(now->leftChild!=NULL){ count(now->leftChild); Size[now->element]+=Size[now->leftChild->element]; lh=height[now->leftChild->element]; } if(now->rightChild!=NULL){ count(now->rightChild); Size[now->element]+=Size[now->rightChild->element]; rh=height[now->rightChild->element]; } height[now->element]=max(lh,rh)+1; } template<class T> BinaryTree<T>::~BinaryTree(){ postOrder(root,dispose); } int main(){ freopen("Cola.txt","r",stdin); int n; cin>>n; for(int i=1;i<=n;i++){ cin>>l[i]>>r[i]; } binaryTreeNode<int> *root; root=new binaryTreeNode<int>(1); BinaryTree<int> tree(root); tree.build(root); levelOrder(tree.Root(),visit); cout<<endl; tree.count(root); for(int i=1;i<=n;i++) cout<<Size[i]<<" "; cout<<endl; for(int i=1;i<=n;i++) cout<<height[i]<<" "; cout<<endl; return 0; }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int a[10010],b[10010],map[10010]; template<class T> struct binaryTreeNode{ T element; binaryTreeNode<T> *leftChild,*rightChild; binaryTreeNode(){leftChild=rightChild=NULL;} binaryTreeNode(const T& theElement):element(theElement){ leftChild=rightChild=NULL; } binaryTreeNode(const T& theElement,binaryTreeNode *theLeftChild,binaryTreeNode *theRightChild){ element=theElement; leftChild=theLeftChild; rightChild=theRightChild; } }; template<class T> void dfs(int al,int ar,int bl,int br,binaryTreeNode<T>* t){ int next_al,next_ar,next_bl,next_br; next_ar=al; next_bl=bl;//确定左子树的范围 next_br=map[a[al]]-1; if(next_bl<=next_br){ next_al=al+1; next_ar=al+(next_br-next_bl+1); t->leftChild=new binaryTreeNode<T>(a[next_al]); dfs(next_al,next_ar,next_bl,next_br,t->leftChild); } next_bl=map[a[al]]+1; next_br=br; if(next_bl<=next_br){ next_al=next_ar+1; next_ar=ar; t->rightChild=new binaryTreeNode<T>(a[next_al]); dfs(next_al,next_ar,next_bl,next_br,t->rightChild); } } template<class T> void postOrder(binaryTreeNode<T> *t){ if(t!=NULL){ postOrder(t->leftChild); postOrder(t->rightChild); cout<<t->element<<" "; } } int main(){ binaryTreeNode<int> *root; root=new binaryTreeNode<int>(1); int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++){ cin>>b[i]; map[b[i]]=i;//表示编号i在中序遍历中的位置 } dfs(1,n,1,n,root); postOrder(root); cout<<endl; return 0; }
实验十-堆及其应用
#include<iostream> #include<cstdio> #include<cstring> #include<sstream> using namespace std; class illegalParameterValue{ public: illegalParameterValue():message("Illegal parameter value"){} illegalParameterValue(string theMessage){message=theMessage;} void outputMessage(){cout<<message<<endl;} private: string message; }; class queueEmpty{ public: queueEmpty():message("Queue empty"){} queueEmpty(string theMessage){message=theMessage;} private: string message; }; template<class T> void changeLength1D(T* &a,int oldLength,int newLength){//扩大数组长度 if(newLength<0) throw illegalParameterValue("new length must be >= 0"); T* temp=new T[newLength]; int number=min(oldLength,newLength); copy(a,a+number,temp); delete []a; a=temp; } template<class T> class minHeap{ public: minHeap(int initialCapacity=10); ~minHeap(){ delete []heap; } bool empty()const{return heapSize==0;} int size()const{return heapSize;} const T& top(){ if(heapSize==0)throw queueEmpty(); return heap[1]; } void pop(); void push(const T&); void initialize(T*,int); void deactivateArray(){ heap=NULL; arrayLength=heapSize=0; } private: int heapSize; int arrayLength; T *heap; }; template<class T> minHeap<T>::minHeap(int initialCapacity){ if(initialCapacity<1){ ostringstream s; s<<"initial initialCapacity = "<<initialCapacity<<" Must be > 0"; throw illegalParameterValue(s.str()); } arrayLength=initialCapacity+1; heap=new T[arrayLength]; heapSize=0; } template<class T> void minHeap<T>::initialize(T *theHeap,int theSize){ delete []heap; heap=theHeap; heapSize=theSize; arrayLength=theSize+1; for(int root=heapSize/2;root>=1;root--){ T rootElement=heap[root]; int child=2*root; while(child<=heapSize){ if(child<heapSize && heap[child]>heap[child+1]) child++; if(rootElement <= heap[child])//满足小根堆 break; heap[child/2]=heap[child]; child*=2; } heap[child/2]=rootElement; } } template<class T> void minHeap<T>::push(const T& theElement){ if(heapSize == arrayLength-1){ changeLength1D(heap,arrayLength,2*arrayLength); arrayLength*=2; } int currentNode=++heapSize;//先把当前节点放到最后一位,currentNode表示当前节点的位置 while(currentNode!=1 && heap[currentNode/2]>theElement){//如果父亲节点的值大于当前节点的值,则把当前节点上移,父亲节点下移 heap[currentNode]=heap[currentNode/2]; currentNode/=2; } heap[currentNode]=theElement; } template<class T> void minHeap<T>::pop(){ if(heapSize==0)throw queueEmpty(); T lastElement=heap[heapSize--]; int currentNode=1,child=2; while(child<=heapSize){ if(child<heapSize && heap[child]>heap[child+1])//如果左儿子大于右二子,就选择右二子 child++; if(lastElement<=heap[child])//如果最后一个节点小于等于当前节点的儿子,那么最后一个节点应该放到当前节点的位置上,不需要再往下找 break; heap[currentNode]=heap[child];//将较小的儿子向父亲方向移动 currentNode=child; child*=2; } heap[currentNode]=lastElement; } template<class T> void heapSort(T a[],int n){ minHeap<T>heap(1); heap.initialize(a,n); for(int i=n-1;i>=1;i--){ T x=heap.top(); heap.pop(); a[i+1]=x; } heap.deactivateArray(); } //因为开的数组比较大,所以放在主函数里会运行错误 int *a,*b; int main(){ int n,m,op,x; cin>>n; a=new int[n+1]; minHeap<int> heap; for(int i=1;i<=n;i++)cin>>a[i]; heap.initialize(a,n); cout<<heap.top()<<endl; cin>>m; while(m--){ cin>>op; if(op==1){//push操作 cin>>x; heap.push(x); cout<<heap.top()<<endl; } else if(op==2){//pop操作 heap.pop(); cout<<heap.top()<<endl; } else {//排序操作 cin>>n; b=new int[n+1]; for(int i=1;i<=n;i++){ cin>>b[i]; } heapSort(b,n); for(int i=n;i>=1;i--){ cout<<b[i]<<" "; } cout<<endl; delete []b; } } return 0; }
#include<iostream> #include<cstdio> #include<cstring> #include<sstream> using namespace std; class illegalParameterValue{ public: illegalParameterValue():message("Illegal parameter value"){} illegalParameterValue(string theMessage){message=theMessage;} void outputMessage(){cout<<message<<endl;} private: string message; }; class queueEmpty{ public: queueEmpty():message("Queue empty"){} queueEmpty(string theMessage){message=theMessage;} private: string message; }; template<class T> void changeLength1D(T* &a,int oldLength,int newLength){//扩大数组长度 if(newLength<0) throw illegalParameterValue("new length must be >= 0"); T* temp=new T[newLength]; int number=min(oldLength,newLength); copy(a,a+number,temp); delete []a; a=temp; } int ans=0; template<class T> class minHeap{ public: minHeap(int initialCapacity=10); ~minHeap(){ //delete []heap; } bool empty()const{return heapSize==0;} int size()const{return heapSize;} const T& top(){ if(heapSize==0)throw queueEmpty(); return heap[1]; } void pop(); void push(const T&); void initialize(T*,int); void deactivateArray(){ heap=NULL; arrayLength=heapSize=0; } private: int heapSize; int arrayLength; T *heap; }; template<class T> minHeap<T>::minHeap(int initialCapacity){ if(initialCapacity<1){ ostringstream s; s<<"initial initialCapacity = "<<initialCapacity<<" Must be > 0"; throw illegalParameterValue(s.str()); } arrayLength=initialCapacity+1; heap=new T[arrayLength]; heapSize=0; } template<class T> void minHeap<T>::initialize(T *theHeap,int theSize){ delete []heap; heap=theHeap; heapSize=theSize; arrayLength=theSize+1; for(int root=heapSize/2;root>=1;root--){ T rootElement=heap[root]; int child=2*root; while(child<=heapSize){ if(child<heapSize && heap[child]>heap[child+1]) child++; if(rootElement <= heap[child])//满足小根堆 break; heap[child/2]=heap[child]; child*=2; } heap[child/2]=rootElement; } } template<class T> void minHeap<T>::push(const T& theElement){ if(heapSize == arrayLength-1){ changeLength1D(heap,arrayLength,2*arrayLength); arrayLength*=2; } int currentNode=++heapSize; while(currentNode!=1 && heap[currentNode/2]>theElement){ heap[currentNode]=heap[currentNode/2]; currentNode/=2; } heap[currentNode]=theElement; } template<class T> void minHeap<T>::pop(){ if(heapSize==0)throw queueEmpty(); T lastElement=heap[heapSize--]; int currentNode=1,child=2; while(child<=heapSize){ if(child<heapSize && heap[child]>heap[child+1]) child++; if(lastElement<=heap[child]) break; heap[currentNode]=heap[child]; currentNode=child; child*=2; } heap[currentNode]=lastElement; } template<class T> void heapSort(T a[],int n){ minHeap<T>heap(1); heap.initialize(a,n); for(int i=n-1;i>=1;i--){ T x=heap.top(); heap.pop(); a[i+1]=x; } heap.deactivateArray(); } template<class T> struct binaryTreeNode{ T element; binaryTreeNode<T> *leftChild,*rightChild; binaryTreeNode(){leftChild=rightChild=NULL;} binaryTreeNode(const T& theElement):element(theElement){ leftChild=rightChild=NULL; } binaryTreeNode(const T& theElement,binaryTreeNode *theLeftChild,binaryTreeNode *theRightChild){ element=theElement; leftChild=theLeftChild; rightChild=theRightChild; } }; template<class T> void postOrder(binaryTreeNode<T> *t,void (*op)(binaryTreeNode<T>*)){ if(t!=NULL){ postOrder(t->leftChild,op); postOrder(t->rightChild,op); op(t); cout<<1<<endl; } } template<class T> class BinaryTree{ public: BinaryTree(binaryTreeNode<T> *r){root=r;size=1;} BinaryTree(){root=NULL;size=0;} ~BinaryTree(); binaryTreeNode<T>* Root(){return root;} void makeTree(const T& element,BinaryTree<T>&,BinaryTree<T>&); void count(binaryTreeNode<T>* r,int dep); static void dispose(binaryTreeNode<T> *t) {delete t;} private: binaryTreeNode<T> *root; int size; }; template<class T> BinaryTree<T>::~BinaryTree(){ postOrder(root,dispose); } template<class T> void BinaryTree<T>::makeTree(const T& element,BinaryTree<T>& left,BinaryTree<T>& right){ root=new binaryTreeNode<T>(element,left.root,right.root); size=left.size+right.size+1; left.root=right.root=NULL; left.size=right.size=0; } template<class T> void BinaryTree<T>::count(binaryTreeNode<T>* r,int dep){ if(r->element!=0){//递归到叶子节点时,加入答案 ans+=dep*(r->element); return; } if(r->leftChild !=NULL)count(r->leftChild ,dep+1); if(r->rightChild!=NULL)count(r->rightChild,dep+1); } template<class T> struct huffmanNode{ BinaryTree<int> *tree;//一个huffmanNode包括权值和这颗树 T weight; operator T()const{return weight;} bool operator < (const huffmanNode& u){ return weight<u.weight; } }; template<class T> BinaryTree<int>* huffmanTree(T weight[],int n){ huffmanNode<T> *hNode=new huffmanNode<T>[n+1]; BinaryTree<int>emptyTree; for(int i=1;i<=n;i++){ hNode[i].weight=weight[i]; hNode[i].tree=new BinaryTree<int>; hNode[i].tree->makeTree(weight[i],emptyTree,emptyTree);//初始对每个权值建一棵树 } minHeap<huffmanNode<T> >heap(1); heap.initialize(hNode,n);//定义一个堆,并且将每棵树加入堆中 huffmanNode<T>w,x,y; BinaryTree<int>*z; for(int i=1;i<n;i++){ x=heap.top();heap.pop(); y=heap.top();heap.pop();//取出两个权值最小的树 z=new BinaryTree<int>; z->makeTree(0,*x.tree,*y.tree);//合并两棵树 w.weight=x.weight+y.weight;//合并两个树的权值 w.tree=z; heap.push(w);//将新的huffmanNode加入小根堆 delete x.tree; delete y.tree; } //经过n-1次合并,可以使n个节点合并成一棵树 return heap.top().tree; } char c[1000010]; int main(){ int *weight; scanf("%s",c); int len=strlen(c); weight=new int[27];//记录每个字母出现的次数 for(int i=1;i<=26;i++) weight[i]=0; for(int i=0;i<len;i++){ weight[c[i]-'a'+1]++; } int n=0; for(int i=1;i<=26;i++){ if(weight[i]>0){ weight[++n]=weight[i];//只保存出现过的字母,把没出现过的字母忽略 } } BinaryTree<int>* tree=huffmanTree(weight,n);//构建哈夫曼树 tree->count(tree->Root(),0);//计算哈夫曼树的WEP值 cout<<ans<<endl; delete []weight; return 0; }
实验十一-二叉搜索树
#include<iostream> #include<cstdio> #include<cstring> #include<utility> using namespace std; template<class T> struct binaryTreeNode{ T element; int leftSize; binaryTreeNode<T> *leftChild,*rightChild; binaryTreeNode(){leftChild=rightChild=NULL;leftSize=0;} binaryTreeNode(const T& theElement):element(theElement){ leftChild=rightChild=NULL; leftSize=0; } binaryTreeNode(const T& theElement,binaryTreeNode *theLeftChild,binaryTreeNode *theRightChild,int theLeftSize){ element=theElement; leftChild=theLeftChild; rightChild=theRightChild; leftSize=theLeftSize; } }; //---------------------------------------------------------------------------------------- template<class T> class BinaryTree{ public: BinaryTree(binaryTreeNode<T> *r){root=r;size=1;} BinaryTree(){root=NULL;size=0;} ~BinaryTree(); binaryTreeNode<T>* Root(){return root;} static void dispose(binaryTreeNode<T> *t) {delete t;} protected: binaryTreeNode<T> *root; int size; }; template<class T> void postOrder(binaryTreeNode<T> *t,void (*op)(binaryTreeNode<T>*)){ if(t!=NULL){ postOrder(t->leftChild,op); postOrder(t->rightChild,op); op(t); } } template<class T> BinaryTree<T>::~BinaryTree(){ postOrder(root,dispose); } template<class K,class E> void inOrderOutput(binaryTreeNode<pair<K,E> > *t){ if(t!=NULL){ inOrderOutput(t->rightChild); cout<<t->element.second<<" "; inOrderOutput(t->leftChild); } } //---------------------------------------------------------------------------------------- template<class K,class E> class binarySearchTree: public BinaryTree<pair<K, E> >{ public: bool empty()const{return BinaryTree<pair<K, E> >::size==0;} int Size()const{return BinaryTree<pair<K, E> >::size;} int find(K& theKey)const; int insert(const pair<K,E>& thePair); int erase(K& theKey); void ascend(){inOrderOutput(BinaryTree<pair<K, E> >::root);} int count(binaryTreeNode<pair<K,E> >* t); pair<K,E>* findRank(int rank,int &ans); int eraseRank(int rank); }; template<class K,class E> int binarySearchTree<K,E>::find(K& theKey)const{ int res=0; binaryTreeNode<pair<K,E> >*p=BinaryTree<pair<K, E> >::root; while(p!=NULL){ res^=p->element.first; if(theKey<p->element.first) p=p->leftChild; else { if(theKey>p->element.first) p=p->rightChild; else return res; } } return 0; } template<class K,class E> int binarySearchTree<K,E>::insert(const pair<K,E>& thePair){ binaryTreeNode<pair<K,E> > *p=BinaryTree<pair<K, E> >::root,*pp=NULL; int res=0; while(p!=NULL){ pp=p; res^=p->element.first; if(thePair.first<p->element.first) p=p->leftChild; else { if(thePair.first>p->element.first) p=p->rightChild; else { p->element.second=thePair.second; return 0; } } } binaryTreeNode<pair<K,E> >*newNode=new binaryTreeNode<pair<K,E> >(thePair); if(BinaryTree<pair<K, E> >::root!=NULL){ if(thePair.first<pp->element.first) pp->leftChild=newNode; else pp->rightChild=newNode; } else BinaryTree<pair<K, E> >::root=newNode; // res^=newNode->element.first; BinaryTree<pair<K, E> >::size++; //修改leftSize binaryTreeNode<pair<K,E> > *q=BinaryTree<pair<K, E> >::root; while(q!=NULL && q->element.first!=thePair.first){ if(thePair.first<q->element.first){ q->leftSize++; q=q->leftChild; } else if(thePair.first>q->element.first){ q=q->rightChild; } } return res; } template<class K,class E> int binarySearchTree<K,E>::erase(K& theKey){ binaryTreeNode<pair<K,E> >*p=BinaryTree<pair<K, E> >::root,*pp=NULL; int res=theKey; while(p!=NULL && p->element.first!=theKey){ pp=p; res^=p->element.first; if(theKey<p->element.first) p=p->leftChild; else p=p->rightChild; } if(p==NULL)return 0; //修改leftSize p=BinaryTree<pair<K, E> >::root; while(p!=NULL && p->element.first!=theKey){ if(theKey<p->element.first){ p->leftSize--; p=p->leftChild; } else p=p->rightChild; } if(p->leftChild!=NULL && p->rightChild!=NULL){//左右儿子都存在 binaryTreeNode<pair<K,E> >*s=p->rightChild,*ps=p; while(s->leftChild!=NULL){ s->leftSize--; ps=s; s=s->leftChild; } binaryTreeNode<pair<K,E> > *q=new binaryTreeNode<pair<K,E> >(s->element,p->leftChild,p->rightChild,p->leftSize); //把q放到p的位置上 if(pp==NULL)BinaryTree<pair<K, E> >::root=q; else if(p==pp->leftChild)pp->leftChild=q; else pp->rightChild=q; if(ps==p)pp=q; else pp=ps; delete p; p=s; } //p有最多一个儿子 binaryTreeNode<pair<K,E> >*c; if(p->leftChild != NULL) c=p->leftChild; else c=p->rightChild; if(p==BinaryTree<pair<K, E> >::root)BinaryTree<pair<K, E> >::root=c; else { if(p==pp->leftChild) pp->leftChild=c; else pp->rightChild=c; } BinaryTree<pair<K, E> >::size--; delete p; return res; } template<class K,class E> pair<K,E>* binarySearchTree<K,E>::findRank(int rank,int &res){ int leftSize=0;; binaryTreeNode<pair<K,E> >*p=BinaryTree<pair<K, E> >::root; while(p!=NULL){ res^=p->element.first; leftSize=p->leftSize; if(rank==leftSize+1)return &p->element; else if(rank<=leftSize){ p=p->leftChild; } else { p=p->rightChild; rank-=leftSize+1; } } res=0; return NULL; } template<class K,class E> int binarySearchTree<K,E>::eraseRank(int rank){ int res=0; pair<K,E>* del=findRank(rank,res); erase(del->first); return res; } int main(){ int m,a,b; cin>>m; binarySearchTree<int,int> tr; while(m--){ cin>>a>>b; if(a==0) cout<<tr.insert(pair<int,int>(b,b))<<endl; else if(a==1) cout<<tr.find(b)<<endl; else if(a==2) cout<<tr.erase(b)<<endl; else if(a==3){ int res=0; tr.findRank(b,res);//查找名次为b的元素 cout<<res<<endl; } else if(a==4) cout<<tr.eraseRank(b)<<endl;//删除名次为b的元素 } return 0; }
实验十二-图
#include<iostream> #include<cstdio> #include<cstring> #include<sstream> using namespace std; int *a,*vis,*tmp,step; void clear(int n){ for(int i=1;i<=n;i++) a[i]=0,vis[i]=0,tmp[i]=0; step=0; } class illegalParameterValue{ public: illegalParameterValue():message("Illegal parameter value"){} illegalParameterValue(string theMessage){message=theMessage;} void illegalIndex(string theMessage){message=theMessage;} private: string message; }; class queueEmpty{ public: queueEmpty():message("Queue empty"){} queueEmpty(string theMessage){message=theMessage;} private: string message; }; template<class T> class queue{ public: virtual ~queue(){} virtual bool empty()const=0; virtual int size()const=0; virtual T& front()=0; virtual T& back()=0; virtual void pop()=0; virtual void push(const T& theElement)=0; }; template<class T> class arrayQueue:public queue<T>{ public: arrayQueue(int initialCapacity=10); ~arrayQueue(){delete []queue;} bool empty()const{return theFront==theBack;} int size()const{ return (theBack-theFront+arrayLength)%arrayLength; } T& front(){ if(theFront==theBack) throw queueEmpty(); return queue[(theFront+1)%arrayLength]; } T& back(){ if(theFront==theBack) throw queueEmpty(); return queue[theBack]; } void pop(){ if(theFront==theBack) throw queueEmpty(); theFront=(theFront+1)%arrayLength; } void push(const T& theElement); private: int theFront; int theBack; int arrayLength; T *queue; }; template<class T> arrayQueue<T>::arrayQueue(int initialCapacity){ if(initialCapacity<1){ ostringstream s; s<<"Initial capacity = "<<initialCapacity<<" Must be > 0."; throw illegalParameterValue(s.str()); } arrayLength=initialCapacity; queue=new T[arrayLength]; theFront=0; theBack=0; } template<class T> void arrayQueue<T>::push(const T& theElement){ if((theBack+1)%arrayLength==theFront){ T* newQueue=new T[2*arrayLength]; int start=theFront+1; do{ newQueue[start%(arrayLength*2)]=queue[start%arrayLength]; start++; }while(start%arrayLength!=(theBack+1)%arrayLength); theBack=(start-1+arrayLength*2)%(arrayLength*2); arrayLength*=2; queue=newQueue; } theBack=(theBack+1)%arrayLength; queue[theBack]=theElement; } template<class T> struct chainNode{ T element; chainNode<T> *next; chainNode(){} chainNode(const T& _element){ element=_element; } chainNode(const T& _element,chainNode<T>* _next){ element=_element; next=_next; } }; template<class T> class graphChain{//因为要求bfs和dfs时按照最小的字典序输出,所以维护一个从小到大的有序链表 public: graphChain(); graphChain(const graphChain<T>&); ~graphChain(); void insert(const T& theElement);//将元素theElement插入到有序链表中 int erase(const T& val);//删除val出现的位置 int indexOf(const T& val);//返回val出现的位置 class iterator; iterator begin(){return iterator(firstNode);} iterator end(){return iterator(NULL);} //protected: chainNode<T>* firstNode;//链表的第一个节点 int listSize;//链表的长度 }; template<class T> class graphChain<T>::iterator{ public: iterator(chainNode<T>* theNode=NULL){node=theNode;}//构造函数 //解引用操作符 T& operator*()const{return node->element;} T* operator->()const{return &node->element;} //迭代器加法操作 iterator & operator++(){ node=node->next; return node; } iterator operator++(T){ iterator old=*this; node=node->next; return old; } //相等检验 bool operator!=(const iterator right)const{ return node!=right.node; } bool operator==(const iterator right)const{ return node==right.node; } protected: chainNode<T>* node; }; template<class T> graphChain<T>::graphChain(){ firstNode=NULL; listSize=0; } template<class T> graphChain<T>::graphChain(const graphChain<T>& theList){//需要维护一个有序链表 listSize=theList.listSize; if(listSize==0){//链表theList为空 firstNode=NULL; return; } //链表theList为非空 chainNode<T>* sourceNode=theList.firstNode; firstNode=new chainNode<T>(sourceNode->element);//复制链表theList的首元素 sourceNode=sourceNode->next; chainNode<T>* targetNode=firstNode; while(sourceNode!=NULL){//最后一个节点(结束的标志) targetNode->next=new chainNode<T>(sourceNode->element); targetNode=targetNode->next; sourceNode=sourceNode->next; } targetNode->next=NULL;//链表结束 } template<class T> graphChain<T>::~graphChain(){ while(firstNode!=NULL){ chainNode<T>* nextNode=firstNode->next; delete firstNode; firstNode=nextNode; } } template<class T> void graphChain<T>::insert(const T& theElement){ chainNode<T> *p=firstNode; chainNode<T> *tp=NULL; while(p!=NULL && p->element<theElement){ tp=p; p=p->next; } if(p!=NULL && p->element==theElement){ return; } chainNode<T> *newNode=new chainNode<T>(theElement,p); if(tp==NULL)firstNode=newNode; else tp->next=newNode; listSize++; } template<class T> int graphChain<T>::erase(const T& val){ chainNode<T> *p=firstNode; chainNode<T> *tp=NULL; while(p!=NULL && p->element<val){ tp=p; p=p->next; } if(p!=NULL && p->element==val){ if(tp==NULL)firstNode=p->next; else tp->next=p->next; delete p; listSize--; return 1; } else return 0; } template<class T> int graphChain<T>::indexOf(const T& val){ chainNode<T> *p=firstNode; int res=1; while(p!=NULL){ if(p->element==val)return res; p=p->next; res++; } return -1; } class edge{//边结构体 public: edge(int _v1,int _v2):v1(_v1),v2(_v2){} ~edge(){} int vertex1()const {return v1;} int vertex2()const {return v2;} private: int v1,v2; }; class graph{ protected: int n;//点数 int e;//边数 graphChain<int>* aList;//邻接链表 public: graph(int _n=0){ n=_n; e=0; aList=new graphChain<int>[n+1]; } ~graph(){delete []aList;} bool existEdge(int i,int j)const{//判断是否存在这条边 if(i<1 || i>n || j<1 || j>n || aList[i].indexOf(j)==-1 || aList[j].indexOf(i)==-1) return 0; else return 1; } void insertEdge(edge *theEdge){//插入边 int v1=theEdge->vertex1(); int v2=theEdge->vertex2(); if(v1<1 || v1>n || v2<1 || v2>n)return; if(aList[v1].indexOf(v2)==-1){ aList[v1].insert(v2); aList[v2].insert(v1); e++; } } void eraseEdge(int i,int j){//删除边 if(i>=1 && j>=1 && i<=n && j<=n){ e-=aList[i].erase(j); aList[j].erase(i); } } class Iterator{//迭代器,用来枚举与一个点相连的所有点 protected: chainNode<int>* currentNode; public: Iterator(chainNode<int> *theNode){currentNode=theNode;} ~Iterator(){} int next(){ if(currentNode==NULL)return 0; int nextNode=currentNode->element; currentNode=currentNode->next; return nextNode; } }; Iterator* iterator(int x){//新建一个迭代器 if(x>=1&&x<=n) return new Iterator(aList[x].firstNode); else return NULL; } int connect(int *);//查询连通子图 void dfs(int ,int *);//深度优先搜索 void bfs(int ,int *);//宽度优先搜索 int instance(int ,int);//查询两个点之间的最短距离 }; void graph::dfs(int from,int *path){//深度优先搜索,当前在from,路径记录在path中 Iterator *it=iterator(from); vis[from]=1; path[++step]=from;//step是当前走到了第几步 int to; while((to=it->next())!=0){ if(!vis[to]) dfs(to,path);//找到下一个未到达的位置,继续dfs } delete it; } void graph::bfs(int start,int *path){//宽度优先搜索,起点为start,路径记录在path中 arrayQueue<int> q;//定义一个用来存储节点的队列 q.push(start);//将起点入队 path[++step]=start;//记录路径 vis[start]=1;//标记起点已经到达过 int from,to; while(!q.empty()){ from=q.front();q.pop();//取出队列首节点 Iterator *it=iterator(from);//定义这个节点的迭代器 while((to=it->next())!=0){//枚举与此节点相连的所有点 if(!vis[to]){ path[++step]=to;//如果下一个节点未到达过,则将节点入队并标记,并且记录路径 q.push(to); vis[to]=1; } } delete it; } } int graph::connect(int *b){ int cnt=0;//cnt记录连通块的个数 for(int i=1;i<=n;i++){//枚举每个点 if(!vis[i]){ b[++cnt]=i;//如果这个点未遍历过,则说明它存在于另一个连通块,dfs遍历它所在的连通块 dfs(i,tmp); } } return cnt; } struct node{//节点和层次的结构体 int id,level; node(){} node(int x,int y):id(x),level(y){} }; int graph::instance(int s,int t){//计算s到t的最短距离,用bfs arrayQueue<node> q; q.push(node(s,0));//起点位于第0层,加入队列 vis[s]=1; node from; int to; while(!q.empty()){ from=q.front();q.pop();//取队列中的结构体 Iterator *it=iterator(from.id); while((to=it->next())!=0){ if(!vis[to]){ if(to==t)return from.level+1;//如果到达终点,则返回终点层次,因为图没有边权,所以这个就是最短距离 q.push(node(to,from.level+1));//向队列加入新节点 vis[to]=1; } } delete it; } return -1;//如果队列已经为空并且没有找到t,就说明从s不能到达t,返回-1 } int main(){ int n,m,s,t,op,x,y; cin>>n>>m>>s>>t; a=new int[n+1]; vis=new int[n+1]; tmp=new int[n+1]; graph g(n); while(m--){ cin>>op>>x>>y; if(op==0){ edge *e=new edge(x,y); g.insertEdge(e); } else g.eraseEdge(x,y); } clear(n); int cnt=g.connect(a); cout<<cnt<<endl; for(int i=1;i<=cnt;i++) cout<<a[i]<<" "; cout<<endl; clear(n); g.dfs(s,a); cout<<step<<endl; for(int i=1;i<=step;i++) cout<<a[i]<<" "; cout<<endl; clear(n); g.bfs(t,a); printf("%d\n",step); for(int i=1;i<=step;i++) cout<<a[i]<<" "; cout<<endl; clear(n); cout<<g.instance(s,t)<<endl; delete []a; delete []tmp; delete []vis; return 0; }