64,682
社区成员
发帖
与我相关
我的任务
分享
template<typename T>
class Node
{
public:
T element;
Node<T> *next;
Node() //构造函数
{
next = NULL;
}
Node(T element)
{
this->element = element;
next = NULL;
}
};
template<typename T>
class LinkedList
{
public:
LinkedList(); //创建一个默认的链表
void addFirst(T element);
void addLast(T element);
T getFirst();
T getLast();
T removeFirst() throw(runtime_error);
T removeLast();
void add(T element); //在链尾添加元素
void add(int index, T element); //在指定位置添加元素
void clear();
bool contains(T element); //如果列表中包含指定元素,则返回为真
T get(int index); //返回列表中指定的元素
int indexOF(T element); //返回列表中第一个匹配元素的节点下标
bool isEmpty();
int lastIndexOF(T element); //返回列表中最后一个匹配元素的节点下标
void remove(T element);
int getSize();
T removeAt(int index); //删除指定位置元素,并将其返回
T set(int index, T element); //将指定位置元素设置为新值,并返回原址
private:
Node<T> *head, *tail;
int size;
};
template<typename T>
void LinkedList<T>::remove(T element)
{//从列表中删除指定元素
if(size == 0)
throw runtime_error("链表长度为0\n");
else
{
Node<T> *temp = head;
for(int i = 0; i < size - 1; i++)
{
if(temp->element == element)
{
temp = temp->next->next;
--size;
}
else
temp = temp->next;
}
if(temp->element == element)
{
removeLast();
--size;
}
}
}
//如果单链表有重复出现的,也可这样,just try!
template<typename T>
void LinkedList<T>::remove(T element)
{//从列表中删除指定元素
if(size == 0)
throw runtime_error("链表长度为0\n");
else
{
Node<T> *temp , *pre;
bool flag;
for(int i = 0; i < size ; i++)
{
temp=head;
flag=0;//看是否在一次while中存在有与element相同的node;
while(element!=temp->element && temp->next!=NULL) //查找要删除的结点
{
pre=temp; //记录
temp=temp->next; //temp后移一个结点
}
if(element==temp->element)
{
flag=1;
if(temp==head)//如果是头部
{
head=head->next;
}
else
{
pre->next=temp->next;//其他情况
}
delete temp;//不知可否
--size;
}
if (!flag)
{
break;//没有与element相同的node
}
}
}
}
else
{
pre->next=temp->next;//其他情况
}
delete temp;//不知可否
主要是head你也用来存放数据了,编码复杂度得到了空前的提升。
1.从head开始扫描,遇到NULL结束扫描,如果head==NULL同样可以马上结束,所以这一点OK。
2.如果current不等于指定元素n,current=current->next;
3.如果current等于n,则要发生删除动作,删除一个结点有难度么? 当然没有,为什么没难度?
因为你应该在类中实现一个删除指定结点的函数,removeElem(Node *),删除逻辑都转移到这个
函数中去。
删除前你就应该记录下current->next是什么,因为那将是你搜索的下一个结点,也就是接下来的
current=current->next;
逻辑就是这样的,复杂的东西都在removeElem里,包括你删除的是head(1,判断head==tail 2,temp=head;head=head->next;delete temp;3,如果1中为true,tail=NULL;),删除的是tail(1,判断head==tail,2,temp=tail;tail=tail->pre;delete temp;3,如果1中为true,head=NULL.),删除非head非tail(普通删除即可,因为起码有3个结点了~)。 removeElem当然不会包括删除NULL的情况,因为remove(T elem)上边3个步骤里保证一定是传入一个非NULL结点。 如果你考虑把removeElem(Node *)当做一个接口提供给用户,那么必须处理NULL的情况。
template<typename T>
void LinkedList<T>::remove(T element)
{//从列表中删除指定元素
if(size == 0)
throw runtime_error("链表长度为0\n");
else
{
Node<T> *temp = head, *pre;
while(element!=temp->element && temp->next!=NULL) //查找要删除的结点
{
pre=temp; //记录
temp=temp->next; //temp后移一个结点
}
if(element==temp->element)
{
if(temp==head)//如果是头部
{
head=head->next;
}
else
{
pre->next=temp->next;//其他情况
}
delete temp;//不知可否
--size;
}
else
{
cout<<"not found\n";
}
/*
for(int i = 0; i < size - 1; i++)
{
if(temp->element == element)
{
temp = temp->next->next;
--size;
}
else
temp = temp->next;
}
if(temp->element == element)
{
removeLast();
--size;
}*/
}
}