1.讲解:
线性表两种分类:
顺序表,链表
线性表>记录(数据元素)>数据项
顺序表:只有唯一一个节点只存在一个后继,不存在前驱,只有唯一一个节点存在前驱,不存在后继,中间所有的节点都存在位移的前驱和后继
顺序表的优点:可以随机存取,方便访问,存储密度大,空间利用率高
顺序表缺点:难以实现插入数据的操作,而且空间一旦定义就会固定,不能动态控制空间内存的大小
链表的缺点:不能随机存取,空间访问麻烦指针域会占用部分内存空间,
链表优点:可以方便实现数据节点的插入
顺序存储类就不过多讲解了
链式存储类中我们来实现一下抽象链表类
节点对象<抽象链表对象<单链表对象
2.代码:
#include"iostream"
#include"cstdio"
#include"cstring"
#include"cstdlib"
using namespace std;
template<typename T>
class listnode
{
public:
listnode()
{
next=NULL;
}
listnode(T item,listnode<T>* another)
{
data=item;
next=another;
}
T data;
listnode<T>* next;
};
template<typename T>
class ablist
{
public:
ablist()
{
head=NULL;
length=0;
}
ablist(ablist<T>& a) //注意这里必须是引用,因为涉及到指针,不用引用的话,不会完整的复制过来
{
head=NULL;
length=0;
listnode<T>* p=head;
listnode<T>* help=a.head;
while(help!=NULL)
{
p=new listnode<T>(help->data,NULL);
p=p->next;
help=help.next;
}
}
~ablist()
{
listnode<T>* p=head->next;
while(head->next!=NULL)
{
head->next=head->next->next;
free(p);
p=head->next;
}
free(head);
}
listnode<T>* gethead()
{
return head;
}
listnode<T>* getnext(listnode<T>& n)
{
return n.next;
}
T getnumber(int i) //取出第i个元素
{
listnode<T>* p=head;
for(int j=1;j<i;j++) p=p->next;
return p->data;
}
bool setnumber(T k,int i)
{
listnode<T>* p=head;
for(int j=1;j<i;j++)
{
if(p==NULL) return false;
p=p->next;
}
p->data=k;
return true;
}
listnode<T>* find(int i)
{
listnode<T>* p=head;
for(int j=1;j<i;j++)
{
if(p==NULL) return NULL;
p=p->next;
}
return p;
}
listnode<T>* find1(T num)
{
listnode<T>* p=head;
while(p!=NULL)
{
if(p->data==num) return p;
p=p->next;
}
return NULL;
}
void listempty()
{
listnode<T>* p=head->next;
while(head->next!=NULL)
{
head->next=head->next->next;
free(p);
p=head->next;
}
free(head);
head=NULL;
length=0;
}
int returnlength()
{
return length;
}
virtual bool insert(T,int)=0;
virtual bool delete_(int)=0;
virtual bool remove(T)=0;
protected:
listnode<T>* head; //这一点可以学习一下,都定义成模板,通过外包类模板模范子类的模板
int length;
};
template<typename T>
class singlelist:public ablist<T> //万分小心,学习一下,在模板类继承的时候,我们的因为偏特化的存在,必须要用this才可以看到父类成员
{
public:
singlelist()
{}
bool insert(T num,int i)
{
if(i==0)
{
this->head=new listnode<T>(num,NULL);
this->length++;
return true;
}
i++;
listnode<T>* p=this->find(i-1);
if(p==NULL) return false;
listnode<T>* help=new listnode<T>(num,NULL);
help->next=p->next;
p->next=help;
this->length++;
return true;
}
bool delete_(int i)
{
listnode<T>* p=this->find(i-1);
if(p==NULL||p->next==NULL) return false;
else
{
listnode<T>* help=p->next;
T num=p->next->data;
p->next=p->next->next;
free(help);
this->length--;
return true;
}
}
bool remove(T num)
{
listnode<T>* help=NULL;
listnode<T>* p=this->head;
while(p!=NULL)
{
if(p->data==num) break;
else help=p;
p=p->next;
}
if(p==NULL) return false;
help->next=help->next->next;
free(p);
this->length--;
return true;
}
void print()
{
listnode<T>* p=this->head;
while(p!=NULL)
{
cout<<p->data<<' ';
p=p->next;
}
cout<<endl;
}
};
int main()
{
singlelist<int> my;
my.insert(1,my.returnlength());
my.insert(2,my.returnlength());
my.insert(4,my.returnlength());
my.insert(7,my.returnlength());
my.insert(3,my.returnlength());
my.insert(8,my.returnlength());
my.insert(9,my.returnlength());
my.print();
my.delete_(5);
my.print();
my.remove(8);
my.print();
return 0;
}
3.应用:单链表进行加法运算:
#include"iostream"
#include"cstdlib"
#include"cstdio"
using namespace std;
class point
{
public:
point(int n,int m):ceof(n),exp(m){
next=NULL;
}
friend ostream& operator<<(ostream& out,point& p)
{
printf("%+dx^%d",p.ceof,p.exp);
}
int getceof()
{
return ceof;
}
int getexp()
{
return exp;
}
point* next;
private:
int ceof;
int exp;
};
class singlelist
{
public:
singlelist()
{
head=new point(0,0);
head->next=NULL;
num=0;
}
void insert(int ceof,int exp)
{
point* p=new point(ceof,exp);
point* help=head;
while(help->next!=NULL&&help->next->getexp()>=p->getexp()) help=help->next;
p->next=help->next;
help->next=p;
num++;
}
void add(singlelist& a,singlelist& b)
{
point* heada=a.head->next;
point* headb=b.head->next;
point* headc;
point* help=head;
while(heada!=NULL&&headb!=NULL)
{
if(heada->getexp()==headb->getexp())
{
headc=new point(heada->getceof()+headb->getceof(),heada->getexp());
heada=heada->next;
headb=headb->next;
}
else
{
if(heada->getexp()<headb->getexp())
{
headc=new point(headb->getceof(),headb->getexp());
headb=headb->next;
}
else
{
headc=new point(heada->getceof(),heada->getexp());
heada=heada->next;
}
}
help->next=headc;
help=help->next;
headc=headc->next;
}
if(heada==NULL)
{
while(headb!=NULL)
{
headc=new point(headb->getceof(),headb->getexp());
headc=headc->next;
headb=headb->next;
}
}
else
{
while(heada!=NULL)
{
headc=new point(heada->getceof(),heada->getexp());
headc=headc->next;
heada=heada->next;
}
}
}
void print()
{
point* p=head->next;
while(p!=NULL)
{
if(p->getceof()!=0) cout<<*p;
p=p->next;
}
}
private:
point* head;
int num;
};
int main()
{
singlelist a;
singlelist b;
singlelist c;
a.insert(4,21);
a.insert(5,10);
a.insert(7,4);
a.insert(1,1);
b.insert(5,12);
b.insert(-5,10);
b.insert(11,4);
b.insert(1,1);
c.add(a,b);
c.print();
return 0;
}