C++數據結構實驗04--線性表操作

#include"stdafx.h"
#include <iostream>  
#include<new.h>  


using namespace std;    
  
//節點類,定義了每個節點的存儲類型和指針名稱  
template<class T>    
class ChainNode{    
    public:    
        T data;    
        ChainNode<T> *link;    
};    
  
//鏈表類,封裝了鏈表操作的相應方法  
template<class T>    
class Chain{    
    public:    
        Chain(){first=0;}                        //構造函數,頭結點指向空值  
        ~Chain();                                //析構函數  
        bool IsEmpty()const{return first==0;}    //判斷是否爲空  
        int Length()const;                        //返回該鏈表的長度  
        bool Find(int k,T&x)const;                //返回第k個元素到x中  
        int Search(const T&x)const;                //返回x所在的位置    
        Chain<T>& Delete(int k,T& x);            //刪除第k個元素並把它返回到x中  
        Chain<T>& Insert(int k,const T&x);        //在第k個元素之後插入x  
        void Output(ostream& out) const;        //重載操作符的輸出函數  
        ChainNode<T> *first;                    //指向第一個節點的指針  
        ChainNode<T> *last;                        //指向最後一個節點的指針  
  
        void Erase();  
        void Zero(){first=0;};  
        Chain<T>& Append(const T&x);  
  
};  
  
//鏈表遍歷器類實現對鏈表的遍歷  
template<class T>  
class ChainIterator{  
    public:  
        T* Initialize(const Chain<T>&c){  
            location = c.first;  
            if(location){  
                return &location->data;  
            }  
            return 0;  
        }  
  
        T* Next(){  
            if(!location)  
                return 0;  
            location = location->link;  
            if(location)  
                return &location->data;  
            return 0;  
        }  
    private:  
        ChainNode<T>*location;  
};  
  
  
  
//鏈表的析構函數,用於刪除所有的鏈表中的節點  
template<class T>  
Chain<T>::~Chain(){  
    Erase();  
}  
  
  
//清除掉鏈表中的所有元素並且釋放內存  
template<class T>  
void Chain<T>::Erase(){  
    ChainNode<T>*next;  
    //指向下一個節點  
    while(first){  
        next=first->link;  
        delete first;  
        first = next;  
    }  
}  
  
  
//輸出鏈表  
template<class T>  
void Chain<T>::Output(ostream& out)const{  
    ChainNode<T>*current;  
    for(current=first;current;current=current->link){  
        out<<current->data;  
        if(!current->link){  
            out<<""<<endl;  
        }else{  
            out<<",";  
        }  
    }  
}  
//重載操作符  
template<class T>  
ostream& operator<<(ostream& out,const Chain<T>&x){  
    x.Output(out);  
    return out;  
}  
  
class OutOfBounds{    
    public:    
        OutOfBounds(){    
        cout<<"Out Of Bounds!"<<endl;    
        }    
};  
  
   
//內存不足的異常類    
class NoMem{    
    public:    
        NoMem(){    
            cout<<"No Memory!"<<endl;    
        }    
};    
//使new引發NoMem異常而不是xalloc異常    
//如果要恢復原始行爲可以做以下調用    
//_set_new_handler(Old_Handler);    
int my_new_handler(size_t size){    
    throw NoMem();    
}  
  
  
//確認鏈表的長度  
template<class T>  
int Chain<T>::Length()const{  
    ChainNode<T>*current = first;  
    int length = 0;  
    while(current){  
        length++;  
        current = current->link;  
    }  
    return length;  
}  
  
//在鏈表中查找第k個元素  
//存在就儲存到x中  
//不存在則返回false,否則返回true  
template<class T>  
bool Chain<T>::Find(int k,T&x)const{  
    if(k<1)  
        return false;  
    ChainNode<T>*current = first;  
    int index = 1;  
    while(index<k&& current){  
        current = current->link;  
        index++;  
    }  
    if(current){  
        x = current->data;  
        return true;  
    }  
    return false;  
}  
  
  
//在鏈表中搜索  
//查找x,如果發現則返回x的下標  
//如果x不存在則返回0  
template<class T>  
int Chain<T>::Search(const T&x)const{  
    ChainNode<T>*current = first;  
    int index = 1;  
    while(current&& current->data!=x){  
        current = current->link;  
        index++;  
    }  
    if(current){  
        return index;  
    }  
    return 0;  
}  
  
  
  
//從鏈表中刪除一個元素  
//將第k個元素取至x  
//然後從鏈表中刪除第k個元素  
//如果不存在則引發異常OutOfBounds  
template<class T>  
Chain<T>& Chain<T>::Delete(int k,T& x){  
    if(k<1||!first){  
        throw OutOfBounds();  
    }      
    ChainNode<T>*p = first;  
    if(k==1){  
        first = first->link;  
    }else{  
        ChainNode<T>*q = first;  
        for(int index = 1;index<k-1&&q;index++){  
            q = q->link;  
            //此時q指向要刪除的前一個節點  
        }  
        if(!q||!q->link){  
            throw OutOfBounds();  
        }  
        p = q->link;  
        if(p==last)  
            last=q;  
        q->link=p->link;  
        //從鏈表中刪除該節點  
        x = p->data;  
        delete p;  
        return *this;  
    }  
}  
  
  
//在第k個位置之後插入元素  
//不存在則報OutOfBounds異常  
//沒有足夠內存則報NoMem異常  
template<class T>  
Chain<T>& Chain<T>::Insert(int k,const T&x){  
    if(k<0){  
        throw OutOfBounds();  
    }      
    ChainNode<T>*p = first;  
  
    for(int index = 1;index<k && p;index++){  
        p = p->link;  
    }  
    if(k>0 && !p){  
        throw OutOfBounds();  
    }  
    ChainNode<T>*y = new ChainNode<T>;  
    y->data = x;  
    if(k){  
        y->link=p->link;  
        p->link=y;  
    }else{  
        //作爲第一個元素插入  
        y->link = first;  
        first = y;  
    }  
    if(!y->link)  
        last=y;  
    return *this;  
}  
  
  
//在鏈表右端添加一個數據  
template<class T>  
Chain<T>& Chain<T>::Append(const T&x){  
    ChainNode<T>*y;  
    y = new ChainNode<T>;  
    y->data = x;  
    y->link = 0;  
    if(first){  
        last->link = y;  
        last = y;  
    }else{  
        first = last = y;  
    }  
    return *this;  
}  
  
template <class T>  
void InsertSort(T& array, int length){  
    int i, j, key;  
  
    for (i = 1; i < length; i++){  
        key = array[i];  
        //把i之前大於array[i]的數據向後移動  
        for (j = i - 1; j >= 0 && array[j] > key; j--){  
            array[j + 1] = array[j];  
        }  
        //在合適位置安放當前元素  
        array[j + 1] = key;  

    }  

  
  
int _tmain(int argc, _TCHAR* argv[]) 
{  
    int count = 0;  
  
    //收集輸入的內容至鏈表a當中  
    Chain<int> a;  
      
    cout<<"創建鏈表並輸出鏈表"<<endl; 
int inputNumber[10];  
    int count1 = 0;  
    cout<<"Input"<<endl;  
    for(int i =0;i<10;i++){  
        int a;  
        cin>>a;  
        if(a==0){  
            break;  
        }  
        inputNumber[i]=a;  
        count1++;  
    }  
InsertSort(inputNumber[i],count1);
for (int i = 0; i < count1; i++)
{
a.Insert(i,*b[i]);

        


        count++;  
    }  
      
    cout<<"Output1"<<endl;  
    cout<<a<<endl;  
     
cout<<"搜索鏈表的某個數據,若沒有返回0"<<endl; 
    cout<<"Input2"<<endl;  
    int q;  
    cin>>q;  
    cout<<"Output2"<<endl;  
    cout<<a.Search(q)<<endl;  
      






  //創建鏈表遍歷器,並反序輸出
cout<<"創建鏈表遍歷器,並反序輸出"<<endl; 
cout<<"Input3"<<endl;  
    while(true)  
    {  
        int b;  
        cin>>b;  
        if(b==0)break;  
        a.Append(b);  
        count++;  
    }  
int *x;
int *d[100];
int i=0;
ChainIterator<int> c;
x=c.Initialize(a);


while (x&&i<a.Length())
{
d[i]=x;
x=c.Next();
i++;
}
    cout<<"Output3"<<endl; 


for (int i =a.Length()-1; i >=0; i--)
{
cout<<*d[i]<<endl;
}  
   










//創建兩個有序鏈表,通過鏈表遍歷器合併這兩個有序鏈表
cout<<"創建兩個有序鏈表,通過鏈表遍歷器合併這兩個有序鏈表"<<endl;
    Chain<int> w;  
    count = 0;  
    cout<<"Input4"<<endl;  
     cout<<a<<endl; 
    while(true){  
        int b;  
        cin>>b;  
        if(b==0)break;  
        w.Append(b);  
        count++;  
    }  
cout<<w<<endl;
    //直接將w鏈表遍歷加在a鏈表的尾部  
    cout<<"Output4"<<endl;  
    ChainNode<int>*current = w.first;  
    while (current)  
    {  
        a.Append(current->data);  
        current= current->link;  
    }  
    cout<<a<<endl; 
system("pause");
    return 0;  
}  
發佈了27 篇原創文章 · 獲贊 9 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章