单链表表示的多项式相乘

来源:互联网 发布:数据恢复精灵要钱吗 编辑:程序博客网 时间:2024/05/21 10:12

      没想到我的第一个数据结构程序竟然写了3个礼拜多,无聊的电工实习和更无聊的期中考试耽误我不少时间,编写过程中的困难也大大超出了我的预计。以下是我写的代码,其中肯定有很多不妥的矛盾的地方,希望可以得到指正。

//LinkList.h
#ifndef LINKLIST_H
#define LINKLIST_H


template 
<class T>
struct Node
{
    T coef;
    T exp;
    Node
<T> *
next;
}
;

template 
<class T>

class LinkList
{
public
:
    LinkList();
    LinkList(T a[][
2],int
 n);
    
~
LinkList();
    
void Insert(T a,T b,int
 loc);
    
void Delete(int
 loc);
    
void
 Print();
    LinkList
<T> operator+(LinkList<T> &
l2);
    LinkList
<T> operator*(LinkList<T> &
l2);
private
:
    Node
<T> *
first;
}
;

#endif

//LinkList.cpp
#include "LinkList.h"

template 
<class T>
LinkList
<T>::LinkList()
{
    first
=new Node<T>
;
    first
->next=
NULL;
}


template 
<class T>
LinkList
<T>::LinkList(T a[][2],int n)
{
    first
=new Node<T>
;
    first
->next=
NULL;
    
for(int i=1;i<=n;i++
)
        Insert(a[i
-1][0],a[i-1][1
],i);
}


template 
<class T>
LinkList
<T>::~LinkList()
{
    
//
}


template 
<class T>
void LinkList<T>::Insert(T a,T b,int loc)
{
    
    Node
<T> *
temp;
    temp
=new Node<T>
;    
    temp
->coef=
a;
    temp
->exp=
b;

    Node
<T> *p=
first;
    
for(int i=1;i<loc;i++
)
        p
=p->
next;
    temp
->next=p->
next;
    p
->next=
temp;
}


template 
<class T>
void LinkList<T>::Delete(int loc)
{
    Node
<T> *p=
first;
    
for(int i=1;i<loc;i++
)
        p
=p->
next;
    Node
<T> *q=p->
next;
    p
->next=p->next->
next;
    delete q;
}


template 
<class T>
void LinkList<T>::Print()
{
    Node
<T> *p=first->
next;
    
while
(p)
    
{
        cout
<<p->coef<<"x^"<<p->exp<<" "
;
        p
=p->
next;
    }

    cout
<<endl;
}


template 
<class T>
LinkList
<T> LinkList<T>::operator+(LinkList<T> &l2)
{
    LinkList
<T>
 sum;
    Node
<T> *p=first->
next;
    Node
<T> *q=l2.first->
next;
    Node
<T> *r=
sum.first;
    
int loc=1
;
    
while(p &&
 q)
    
{
        
if(p->exp<q->
exp)
        
{
            sum.Insert(p
->coef,p->
exp,loc);
            loc
++
;
            p
=p->
next;
        }

        
else if(p->exp>q->exp)
        
{
            sum.Insert(q
->coef,q->
exp,loc);
            loc
++
;
            q
=q->
next;
        }

        
else
        
{
            
if(p->coef+q->coef==0
)
            
{
                p
=p->
next;
                q
=q->
next;
            }

            
else
            
{
                sum.Insert(p
->coef+q->coef,p->
exp,loc);
                p
=p->
next;
                q
=q->
next;
                loc
++
;
            }

        }
    
    }

    
while(p)
    
{
        sum.Insert(p
->coef,p->
exp,loc);
        p
=p->
next;
        loc
++
;
    }

    
while(q)
    
{
        sum.Insert(q
->coef,q->
exp,loc);
        q
=q->
next;
        loc
++
;
    }

    
return sum;
}


template
<class T>
LinkList
<T> LinkList<T>::operator*(LinkList<T> &l2)
{
    LinkList
<T>
 sum;
    Node
<T> *p=first->
next;
    Node
<T> *
q;
    
int loc=1
;
    
while
(p)
    
{
        LinkList
<T> *temp=new LinkList<T>
;
        q
=l2.first->
next;
        
while
(q)
        
{
            temp
->Insert(p->coef*q->coef,p->exp+q->
exp,loc);
            loc
++
;
            q
=q->
next;
        }

        sum
=sum+(*temp);
        delete temp;
        loc
=1
;
        p
=p->
next;
    }

    
return sum;
}

       上述代码中各项的实现方法我就不做具体分析了,很多书上都有而且肯定比我分析得好,有看不懂的地方也可以问我。这里要讲的是一些容易出错的地方,相信很多人在写链表时也和我一样遇到过许多莫名的错误,甚至让人觉得是电脑的问题。但是电脑毕竟是很按部就班的机器,绝大多数错误都源于代码中的bug。这些错误的代码的共同点是让人觉得理所当然,当然也就很难发现,发现了才意识到是多么愚蠢的错误。我曾一度这样定义插入函数:

template <class T>
void LinkList<T>::Insert(T a,T b,int loc)
{
    
    Node
<T> *
temp;
    temp
->coef=
a;
    temp
->exp=
b;

    Node
<T> *p=
first;
    
for(int i=1;i<loc;i++
)
        p
=p->
next;
    temp
->next=p->
next;
    p
->next=
temp;
}

      这段代码看起来貌似没有什么错误,其实在声明*temp时并没有为它分配空间,导致当程序执行到  temp->coef=a  时,没有一个可以存放a的值的空间。注意了,如果已有另一个Node<T>型的指针p,那么 Node<T> *temp;  temp=p;  自然是合法的,因为系统会把temp指向p所指向的数据空间。将这两种情况放在一起就会发现很容易混淆,而像这样的问题编译器是不会通知你的。由于在构造函数中调用了插入函数,使得我根本无法定义一个链表,最后通过断点步进才找到了错误的地方,在此要顺便感谢一下Samson的帮助。其实在写程序的过程中像这样的低级错误在所难免,所以不应忽视一下细节上的问题。

      关于这个程序的分析只能暂时写到这里,程序中还有一些让人困惑的地方目前我还不能做出明确的解释(比如链表的析构函数为什么为空),只能以后再做补充。最后要说明一下在这个程序中并没有使用迭代器类,关于迭代器会在我以后的文章中做初步的讨论。

 

原创粉丝点击