数据结构实验结果

实验一-递归

#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;
}
1-1 P1001 子集的价值

 

#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;
}
1-2 P1002 全排列问题

 

实验二-排序

#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;
} 
2-1 P1003 排序算法

 

实验三-数组

#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;
}
3-1 P1004 通讯录

 

#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;
}
4-1 P1005 链表实现

 

#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;
}
4-2 P1006 链表合并(友元函数)

 

  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 }
4-2 P006 链表合并(友元函数实现)

 

实验五-稀疏矩阵

矩阵

#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
*/
5-1 P1008

 

稀疏矩阵

#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;
}
5-1 P1008 稀疏矩阵

 

#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;
}
5-1 P1008 稀疏矩阵(有注释)

 

实验六-栈

/*
一个栈的做法中,栈中的每个元素代表一个括号整体,比如下面这个式子
((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;
}
6-1 P1010 算术表达式(一个栈)

 

#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;
}
6-1 P1010 算术表达式(两个栈)

 

实验七-队列

#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;
}
7-1 P1011 卡片游戏

 

实验八-散列表

#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;
}
8-1 P1012 线性开型寻址

 

#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 &currentNode->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;
}
8-2 P1013 链表散列

 

实验九-二叉树操作

#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;
}
9-1 P1014 二叉树基础

 

#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;
}
9-1 P1014 二叉树基础(用到函数指针)

 

#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;
}
9-2 P1015 二叉树遍历

 

实验十-堆及其应用

#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;
}
10-1 P1016 堆的操作

 

#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;
}
10-2 P1017 霍夫曼编码

 

实验十一-二叉搜索树

#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;
}
11-1 P1018 二叉搜索树

 

实验十二-图

#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;
}
12-1 P1019 图论基础

 

posted @ 2020-09-16 19:39  Echo宝贝儿  阅读(36)  评论(0编辑  收藏  举报