LList需要注意一点就是fence的重新定义,这无非是方便了insert()操作而已,试想,如果fence还指向当前位置的话,那么进行insert操作的时候,当前位置的地址存储在上一个元素的next中,那么要想拿到上一个元素,对于单项链表必须从表头开始一个一个的移动,so 麻烦 !!!于是重新定义 fence使其指向当前位置的上一位置,这样的话上面的问题就解决了,不过又冒出一新的问题,拿第一个元素的上一个怎么处理啊,简单,加一个head节点即可,代表第0个位置,不存值。两中fence定义的图解如下:

原本fence定义:

修正后的Fence定义图:

Insert解析图,注意指针的改动顺序:

remove指针改动解析图:

#include<iostream>
using namespace std;

//定义链表的节点类型
//注意结构性开销
template<class Elem>
/**/class Link{
public:
Elem element;
//该节点的值
Link *next;

Link(Elem elemval,Link
*nextval = NULL){
element
= elemval;
next
= nextval;
}
Link(Link
*nextval = NULL){
next
= nextval;
}
//这两个构造函数仔细一看蛮有意思,两个构造函数
//但是结合默认参数已经包含了所有的四种参数
//传递形式

};
template
<class Elem>
class LList{
private:
Link
<Elem> *head;
//head指向的是第一个元素的前一个位置,即该位置没有值,
//这样设计是因为fence的定义为当前位置的前一个位置
//fence这样定义是因为方便之后的insert操作(结合指针链表特点think...)
Link<Elem> *tail;
//指向链表的最后一格元素,特点是next一定为NULL
Link<Elem> *fence;
//另一种解释这个意义为:Last element on left
int leftcnt;
int rightcnt;
void init(){ //初始化(在构造函数中调用)
head = tail = fence = new Link<Elem>;
leftcnt
= rightcnt = 0;
}
void removeAll(){
while(head!=NULL){
fence
= head;
head
= head->next;
delete fence;
}
}

public:
LList(){ init();}

~LList(){removeAll();}

void clear(){
removeAll();
init();
}

void setStart(){
fence
= head;
rightcnt
+=leftcnt;
leftcnt
= 0;
}

void setEnd(){
fence
= tail;
leftcnt
+=rightcnt;
rightcnt
= 0;
}

void next(){
//当fence不是tail时才可向下一个移动
//注意,每次对fence修改,同时要对影响到其他
//成员变量的值进行修改
//如leftcnt,rightcnt
if(fence!=tail){
fence
= fence->next;
leftcnt
++;
rightcnt
--;
}
else cout<<"已经是最后不能向后移动了!"<<endl;
}

int leftLength(){return leftcnt;}
int rightLenghth(){return rightcnt;}

bool getValue(Elem &it){
if(rightLength==0)
return false;
//不要忘记fence的定义,指向的是当前元素的上一位置
it = fence->next->element;
return true;
}
//在类外实现的函数
bool insert(Elem item);
bool append(Elem item);
bool remove(Elem &it);
void pre();
bool setPos(int pos);
void print();
bool find(Elem item);

};

template
<class Elem>
void LList<Elem>::pre(){
Link
<Elem>* temp = head;
while(temp->next!=fence)
temp
= temp->next;
fence
= temp;
leftcnt
--;
rightcnt
++;
}

template
<class Elem>
bool LList<Elem>::insert(Elem item){
fence
->next = new Link<Elem>(item,fence->next);
//fence=fence->next;当前位置即插入的位置,所以fence不用变

if(fence==tail)tail = fence->next;//注意对特殊情况的处理!!!
rightcnt++;//fence指向的是左边最后一个元素,所以是rightcnt加一
return true;
}

template
<class Elem>
bool LList<Elem>::append(Elem item){
tail
->next = new Link<Elem>(item,NULL);
tail
= tail->next;
rightcnt
++;
return true;
}

template
<class Elem>
bool LList<Elem>::remove(Elem &it){
if(fence->next==NULL)return false;
//此时fence指向tail组后一格元素,但是当前元素为最后元素的
//后一位置,该位置是逻辑上的,实际不存在,所以不能删除

it
= fence->next->element;
//记住删去值的信息,以便使用

//fence->next = fence->next->next;
//不建议这样写,因为这样写的话,欲删掉元素的地址即(原fence->next)
//将会丢失,这样在对其地址进行回收或者判断末尾操作的时候将无法进行
//所以先对fence->next保存一下

Link
<Elem> *ltemp = fence->next;
fence
->next = ltemp->next;

if(ltemp == tail)//如果删除的元素是尾巴,那么得从新给尾巴赋值
tail = fence;

delete ltemp;
//回收该内存
rightcnt--;
return true;
}

template
<class Elem>
bool LList<Elem>::setPos(int pos){
if(pos<0||pos>rightcnt+leftcnt)
return false;
fence
= head;
for(int i=0;i<pos;i++)
fence
=fence->next;

rightcnt
= rightcnt+leftcnt-pos;
leftcnt
= pos;
return true;
}

template
<class Elem>
void LList<Elem>::print(){
cout
<<"The list Is : < ";
Link
<Elem>* temp = head;

while(temp!=fence){
cout
<<temp->next->element<<" ";
temp
= temp->next;
}
cout
<<"| ";
while(temp->next!=NULL){
cout
<<temp->next->element<<" ";
temp
= temp->next;
}
cout
<<">"<<endl;
}

template
<class Elem>
bool LList<Elem>::find(Elem item){
if(leftcnt+rightcnt==0)return false;

Link
<Elem>* temp = head->next;
while(temp!=NULL){
if(temp->element==item)return true;
temp
=temp->next;
}
return false;
}

int main(){
LList
<int>list;
list.print();

for(int i=0;i<5;i++)
list.append(i
*2);
list.print();

list.next();
list.print();
list.insert(
5);
list.print();

int item;
list.remove(item);
cout
<<item<<" is removed !"<<endl;
list.print();

list.pre();
list.print();

if(list.find(6))cout<<"6 is in the list !"<<endl;
else cout<<"6 is not in the list!"<<endl;

if(list.find(7))cout<<"7 is in the list !"<<endl;
else cout<<"7 is not in the list !"<<endl;

list.setPos(
3);
list.print();
list.setPos(
0);
list.print();

return 0;
}
posted on 2011-05-29 00:26  geeker  阅读(519)  评论(0编辑  收藏  举报