链表:
数组在程序设计语言中非常有用的数据结构。
数组的局限性:
- 编译期就必须知道数组的大小。
- 数组在计算机内存中是以相同的距离间隔开的。
链表较数组的优势在于插入一个数据,不需要移动其他数据。链表是节点的集合,节点中储存着数据并连接到其他的节点。通过这种方式,节点可以位于内存中任何一种位置。每个节点存储着链表中的其他节点的地址,因此数据很容易从一个节点到达另一个节点。最灵活实现方式使用指针。
单向链表:
如果一个节点将指向另外一个节点的指针作为数据成员,那么多个这样的节点可以连接起来,值用一个变量就能够访问整个节点序列。这样的节点序列就是最常用的链表实现方法。链表是由每个包含某些信息以及指向链表中另一个节点的指针的节点组成的数据结构。如果节点中只包含后继节点的链接,就是单向链表。代码如下:
class IntSLLNode
{
public:
InSLLNode()
{next=0;}
InSLLNode(int i,InSLLNode *in =0)
{
info=i;
next=in;
}
int info;
InSLLNode *next;
}
节点包含两个数据成员:info和next。info成员用于储存信息,next用于将节点连接起来,组成链表。next是用来维持链表辅助数据成员。
InSLLNode的定义用到了自身,因为next指向的是刚刚定义的,同样类型的节点。包含这种成员的对象称为自我引用对象。
节点的定义包含两个构造类,第一个构造初始化next,第二个构造给info和next赋值。第二个构造函数第二个参数有初始值考虑了用户只提供一个参数的情况。
创建单向链表代码:
*******intSLList.h*******
#ifndef INT_LINKED_LIST
#DEFINE INT_LINKED_LIST
class IntSLLNode{
public:
IntSLLNode()
{
next=0;
}
IntSLLNode(int el,IntSLLNode *ptr=0)
{
info=el; next=ptr;
}
int info;
IntSLLNode *next;
};
class IntSLList{
public:
IntSLList()
{
hesd=tail=0;
}
~IntSLList();
int isEmpty()
{return head==0;}
void addToHead(int);
void addToTail(int);
void deleteFromHead();
void deleteFromTail();
void deleteNode(int);
bool isInList(int)const;
private:
IntSLLNode *head,*tail;
};
************intSLList.cpp****
IntSLList::~IntSLLNode()
{
for(IntSLLNode *p;!isEmpty();){
p=head-->next;
delete head;
head=p;
}
}
void IntSLList::addToHead(int el)
{
head=new IntSLLNode(el,head);
if(tail==0)
tail=head;
}
void IntSLList::addToTail(int el)
{
if(tail!=0)
{
tail-->next=new IntSLLNode(el);
tail=tail-->next;
}
else haed=tail=new IntSLLNode(el);
}
int IntSLList::deleteFromHead(){
int el=head->info;
IntSLLNode *tmp=head;
if(head=tail)//只有一个节点
head=tail=0;
else head=head-->next;
delete tmp;
return el;
}
int InSLList::deleteFromTail()
{
int el=tail-->info;
if(head==tail)
{
delete head;
head=tail=0;
}
else{
IntSLLNode *tmp;
for(tmp=head;tmp-->next!=tail;tmp=tmp-->next)
{
delete tail;
tail=tmp;
taill-->next=0;
}
}
return el;
}
void InSLList::deleteNode(int el){
if(head!=0)
if(head==tail&&el==head-->info)
{
delete hesd;
head=tail=0;
}
else if(el==head-->info)
{
IntSLLNode *tmp=head;
head=head-->next;
delete tmp;
}
else {
IntSLLNode *pred,*tmp;
for(pred=head,tmp=head-->next;tmp!=0&&!(tmp-->info==el);pred=pred->next,tmp=tmp->next);
if(tmp!=0)
{
pred->next=tmp->next;
if(tmp==tail)
tail=pred;
delete tmp;
}
}
}
bool IntSLList::isInList(int el)const{
IntSLLNode *tmp;
for(tmp=head;tmp!=0&&!(tmp->info==el);tmp=tmp->next);
return tmp!=0;
}