Chinaunix首页 | 论坛 | 博客
  • 博客访问: 29145
  • 博文数量: 16
  • 博客积分: 600
  • 博客等级: 上士
  • 技术积分: 170
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-21 13:21
文章分类

全部博文(16)

文章存档

2011年(1)

2008年(15)

我的朋友
最近访客

分类: C/C++

2008-03-08 22:10:33

 

//可通用的单链表

#include<iostream.h>
#include<stdio.h>
class MultiNomial//多项式

{


public:
    int coefficient;
    int index;
    MultiNomial();//确保灵活性

    MultiNomial(int c,int i);//确保调用时方便

    ~MultiNomial();//直接用一个输出就行了,这里没有必要用delete

    friend istream& operator>>(istream& in, MultiNomial& a);//不定义display,按坐标形式输出

    friend ostream& operator<<(ostream& out,const MultiNomial& a);
    friend    MultiNomial operator+(    const MultiNomial& p,const MultiNomial& q);
    
     bool operator<(const MultiNomial& parameter);//这里要说明的是:这时的"=="是系统自带的

     bool operator<=(const MultiNomial& parameter);
     bool operator>(const MultiNomial& parameter);
     bool operator>=(const MultiNomial& parameter);
     bool operator==(const MultiNomial& parameter);
     bool operator!=(const MultiNomial& parameter);
    void pursuit();//求导

    void Negative();//将系数变成负的

};
MultiNomial operator+(const MultiNomial& p,const MultiNomial& q)
{
    return MultiNomial(p.coefficient+q.coefficient,p.index);
}

ostream& operator<<(ostream& out,const MultiNomial& a)
{
    out<<'('<<a.coefficient<<','<<a.index<<')'<<" ";
    return out;
}
void MultiNomial::pursuit()
{
    coefficient*=index;
    index-=1;
}
    
MultiNomial::MultiNomial()
{
    cout<<"输入单项式的参数:"<<endl;
  cin>>coefficient>>index;
  getchar();
  cout<<endl;
}
MultiNomial::MultiNomial(int c,int i)
{cout<<"单项式建立"<<endl;coefficient=c;index=i;}
MultiNomial::~MultiNomial()
{
    cout<<"单项式删除"<<endl;
}
istream& operator>>(istream& in, MultiNomial& a)
{
cout<<"进行单项式的输入"<<endl;
cout<<"其系数是"<<endl;
in>>a.coefficient;
getchar();
cout<<"其指数是:"<<endl;
in>>a.index;
getchar();
return in;
}
void MultiNomial::Negative()//单个点数据变负,在链表中要用到它的

{
    coefficient=-coefficient;
}
bool MultiNomial::operator<(const MultiNomial& parameter)
{ int i;
    cout<<"如果对系数进行比较请输入1,对指数比较请输入0"<<endl;
    cin>>i;
    getchar();
    if(i==1)
    {
        if(coefficient<parameter.coefficient)
            return true;
        else return false;
    }
    else
    {
        if(index<parameter.index)
            return true;
        else return false;
    }
}
bool MultiNomial::operator<=(const MultiNomial& parameter)
{
    int i;
    cout<<"如果对系数进行比较请输入1,对指数比较请输入0"<<endl;
    cin>>i;
    getchar();
    if(i==1)
    {
        if(coefficient<=parameter.coefficient)
            return true;
        else return false;
    }
    else
    {
        if(index<=parameter.index)
            return true;
        else return false;
    }
}
bool MultiNomial::operator>(const MultiNomial& parameter)
{
     int i;
    cout<<"如果对系数进行比较请输入1,对指数比较请输入0"<<endl;
    cin>>i;
    getchar();
    if(i==1)
    {
        if(coefficient>parameter.coefficient)
            return true;
        else return false;
    }
    else
    {
        if(index>parameter.index)
            return true;
        else return false;
    }
}
bool MultiNomial::operator>=(const MultiNomial& parameter)
{
    int i;
    cout<<"如果对系数进行比较请输入1,对指数比较请输入0"<<endl;
    cin>>i;
    getchar();
    if(i==1)
    {
        if(coefficient>=parameter.coefficient)
            return true;
        else return false;
    }
    else
    {
        if(index>=parameter.index)
            return true;
        else return false;
    }
}
bool MultiNomial::operator==(const MultiNomial& parameter)
{
    int i;
    cout<<"如果对系数进行比较请输入1,对指数比较请输入0"<<endl;
    cin>>i;
    getchar();
    if(i==1)
    {
        if(coefficient==parameter.coefficient)
            return true;
        else return false;
    }
    else
    {
        if(index==parameter.index)
            return true;
        else return false;
    }
}
bool MultiNomial::operator!=(const MultiNomial& parameter)        
{
    int i;
    cout<<"如果对系数进行比较请输入1,对指数比较请输入0"<<endl;
    cin>>i;
    getchar();
    if(i==1)
    {
        if(coefficient!=parameter.coefficient)
            return true;
        else return false;
    }
    else
    {
        if(index!=parameter.index)
            return true;
        else return false;
    }
}
//对于多项式的求和运算,就只要在SLink中对combine进行一个小的改变,即相等时的变化


template<class T>
struct Node//用class 与struct都一样的,在C++中没有区别

{
    
     public: T data;//数据成员设为公有易于访问

             Node* next;
             Node(const T& d): data(d),next(0){cout<<"新建结点"<<endl;}//常引用的好处,实参可以是常数

             Node(){
                 cout<<"无参的构造结点"<<endl;next=NULL;}//对next的值的添加,是为了在添加结点时,不出错,是个关键,否则不能运行

             ~Node()
             {
                 cout<<"结点的析构,释放结点空间"<<endl;//node的析构,会调用T的析构函数

             }
             T& GetElem()
             {
                 return data;
             }
};
template<class T>//这一行不可少

class SLink
{
    private:
        Node<T>* head;//指向头结点的头指针

        int length;//不包括头结点

    public:
        SLink();
        ~SLink();
        int GetLength();//要加上返回值型

        Node<T>* GetNode(int i);
        Node<T>* Find(const T& data);
        bool Add(int i,const T& a);
        bool Remove(int i);
        void Display();
        void Display(Node<T>* p);
        void Combine(Node<T>* p,Node<T>* q);//传递两个链表的头结点位置

        bool Exchange(int i,int j);
        Node<T>* Max();
        void SelectSort();
        void Reverse();
        Node<T>* HalfIndex(const T& a);
        void Sum(Node<T>* p,Node<T>* q);
        void Pursuit();
};
template<class T>
void SLink<T>::Pursuit()
{
    cout<<"进行求导数的运算开始"<<endl;
    Node<T>* pin=head->next;
    while(pin!=NULL)
    {
        (pin->data).pursuit();
        pin=pin->next;
    }
    cout<<"求导数运算结束"<<endl;
}

template<class T>
void SLink<T>::Sum(Node<T>* p,Node<T>* q)
{
    cout<<"当前正在进行求和,按的是指数来求的"<<endl;
    int i=1;
    while(p!=NULL && q!=NULL)
    {
        if(p->data>q->data)
        {
            Add(i,q->data);i++;q=q->next;}
        else if(p->data<q->data)
        {
            Add(i,p->data);i++;p=p->next;}
        else
        {     cout<<"存在可加的项,接下来按系数比较"<<endl;
         T a=q->data;
         a.Negative();
            if(p->data==a) cout<<"存在相反的项"<<endl;//这是在对象级的运算,这里的空语句有一定的好处

            else
            {
             cout<<"没有相反项"<<endl;
                Add(i,p->data+q->data);i++;
            
            }
            p=p->next;
            q=q->next;
        }
    }
        while(p!=NULL)
        {
            Add(i,p->data);i++;p=p->next;
        }
        while(q!=NULL)
        {
            Add(i,q->data);i++;q=q->next;}
        cout<<"求和运算结束"<<endl;
}

template<class T>
SLink<T>::SLink()
{
    cout<<"创建链表"<<endl;
    head=new Node<T> ;
    length=0;
    cout<<"创建工作完成"<<endl;
}
template<class T>
int SLink<T>::GetLength()//当这个类产生派生类,可直接通过这个接口来访问

{
    return length;
}
template<class T>
Node<T>* SLink<T>::GetNode(int i)//I表示位置

{
    
    if(i<1 || i>length)
    {
        cout<<"不存在这样的结点元素"<<endl;
        return NULL;
    }
    Node<T>* pin=head->next;
    int flag=1;//记录位置

    while(flag!=i)
    {
        pin=pin->next;
        flag++;
    }
    return pin;
}
template<class T>
Node<T>* SLink<T>::Find(const T& data)
{
    
    Node<T>* pin=head->next;

    while( pin->data!=data)//顺序不一样,执行的效率会不一样

    {
        pin=pin->next;
        if(pin==NULL)
    {
        cout<<"没有找到这个元素"<<endl;//这个if放在外面时,可读性也有影响,可见这个代码的位置也可是可读性的一种

        return NULL;
    }
    }
    
    cout<<"找到这样的元素"<<endl;
    return pin;
}
template<class T>
bool SLink<T>::Add(int i,const T& a)// i表示的是位置//SLink易忘记

{
    
    if(i<1 || i>length+1)
    {
        cout<<"不能插入元素"<<endl;
        return false;
    }
    int location=1;
    Node<T>* pin=head;


    Node<T>* p=new Node<T> (a);//这里没有传Node型号参数,故要用到new,这里不用Node时,我们函数调用时更简单,整个框架都简单了

    
    while(location!=i)//千万不能写成i-1,location反映了pin指的位置

    {
        pin=pin->next;
        location++;
    }
  
  p->next=pin->next;
  pin->next=p;
  length++;
  return true;
}
template<class T>
bool SLink<T>::Remove(int i)
{

    if(i<1 || i>length)
    {
        cout<<"没有这样的结点元素"<<endl;
        return false;
    }
    int location=1;
    Node<T>* pin=head;//pin移动一次,指向i,pin一定指向i-1

    while(location!=i)//反正i总是大于等于1

    {
        pin=pin->next;
        location++;//循环执行i-1次

    }
    Node<T>* temp=NULL,*q=NULL;
    q=pin->next;
    temp=pin->next->next;
    
    delete q;
    pin->next=temp;
    length--;
    cout<<"删了该元素"<<endl;
    return true;
}
template<class T>
void SLink<T>::Display()
{
    
Node<T>* pin;
pin=head->next;
while(pin!=NULL)
{
    cout<<pin->data<<" ";
    pin=pin->next;
}
cout<<'\n';
}
template<class T>
void SLink<T>::Display(Node<T>* p)
{
    cout<<p->data<<endl;
}
template<class T>
SLink<T>::~SLink()
{
/*    Node* first=head;
    Node* rear=head->next;
    while(first!=NULL)
    {
        if(rear!=NULL)
        {
            delete first;
            first=rear;
            rear=rear->next;
        }
        else
        {
            delete first;
            break;
        }
    }*/

    //上面的这段代码的思想在双链时可到,但是此处没有这个必要

    cout<<"链表的析构"<<endl;
    Node<T>* pin=head->next;
  while(pin!=NULL)
  {
     head->next=pin->next;
     delete pin;
     pin=head->next;
  }
  delete head;
}
template<class T>
void SLink<T>::Combine(Node<T>* p,Node<T>* q)//逐位的连接

{
    int i=1;
    while(p!=NULL && q!=NULL)
    {
        if(p->data>q->data)
        {
            Add(i,q->data);i++;q=q->next;}
        else if(p->data<q->data)
        {
            Add(i,p->data);i++;p=p->next;}
        else
        {
            Add(i,p->data);i++;p=p->next;
            Add(i,q->data);i++;q=q->next;
        }
    }
        while(p!=NULL)
        {
            Add(i,p->data);i++;p=p->next;
        }
        while(q!=NULL)
        {
            Add(i,q->data);i++;q=q->next;}
}
template<class T>
bool SLink<T>::Exchange(int i,int j)
{
    Node<T>* p=GetNode(i);
    
    Node<T>* q=GetNode(j);
    T temp;
    cout<<"要进行交换时,要定义临时变量"<<endl;
    temp=p->data;
    p->data=q->data;
    q->data=temp;
    return true;
}
template<class T>
Node<T>* SLink<T>::Max()
{
    Node<T>* later=head->next;//存放最大元素地址

    Node<T>* pin=later->next;
    while(pin!=NULL)
    {
        if(pin->data>later->data)
        
        later=pin;
        pin=pin->next;//这个语句要写在if外

    }
    cout<<"最大元素是"<<later->data<<endl;
    return later;
}
template<class T>
void SLink<T>::SelectSort()
{
    cout<<"开始排序"<<endl;
    int i,k;
    for(i=1;i<length;i++)
    {
        k=i;//当I要更新是,i指向下一次要比较的起点,而将i给k时,是把当前的起点给它

        for(int j=i+1;j<=length;j++)
        {
            Node<T>* p=GetNode(k);Node<T>* q=GetNode(j);
        
                if(p->data>q->data)
            
         k=j;//但是k会自动变化的,指向最小位置


        }
            Exchange(k,i);//将当前要交换的i与k交换

    }
    cout<<"结束排序"<<endl;
}
template<class T>
void SLink<T>::Reverse()//可用于判断回文,即先将其倒序,再比较字符串否相等

{
    int i=length;//这里可以看到一点,一个判断回文的问题(复杂问题),在经过我们的一步步分解之后,能够较快的解决.(简单问题),这是一种重要的思路

    int j=1;//当然,这其中什么才是最基本的呢?这就是数据结构要学习的.

    while(i>j)
    {
        Exchange(i,j);
        i--;
        j++;
    }
}
template<class T>
Node<T>* SLink<T>::HalfIndex(const T& a )
{
    Node<T>* pin=new Node<T>(a);
    int head=1;
    int end=length;
    Node<T>* p;
    while(head<=end)
    {
        p=GetNode((head+end)/2);
        if(p->data<pin->data)
           head=1+(head+end)/2;
        else if(p->data==pin->data)
        {cout<<"有这样的元素"<<endl; return p;}
            else end=(end+head)/2-1;
            
    }
    cout<<"没有这样的元素"<<endl;
    return NULL;
}
/*对于某些函数要返回指针的原由,这里作几点说明:
   1.关键字的检索,如Find,由于这是一个结点,可以说这是一个数据元素,它可能包含多个数据项,若我们想知道这个结点的其它的信息,如成绩的查询
                 是以学号来看的.即按学号搜索,若要知道该学生的各科分数,则不仅是返回某一项,而是所有的成绩.

   2.单链表不是可实现机随访问的,能得其地址,固然好,因为以后要访问它,是比较困难的.
 排序的问题:
 这里用的是模板,可谓是泛型的编程,我们只要T数据类型有“==”、“>=”、“<=”、“!=”的重载即可扩充排序这个基本的算法*/


void main()
{
    SLink<MultiNomial> a,b,j;//第一数是没有用的.

    MultiNomial h(3,5),c(-2,12),d(7,10),e(1,4),f(2,12),g(8,11);
    a.Add(1,h);
    a.Add(2,c);
    a.Add(3,d);
    a.Display();
    //\\\\\\\\\a.Pursuit();

    //a.Display();

    b.Add(1,e);
    b.Add(2,f);
    b.Add(3,g);
    b.Display();
    a.SelectSort();
    a.Display();
    b.SelectSort();
    b.Display();
    Node<MultiNomial>* pin=a.GetNode(1),*q=b.GetNode(1);
    j.Sum(pin,q);
    j.Display();
    
}        
        
        
        

    
            


    

阅读(623) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:编程控制技巧

给主人留下些什么吧!~~