上一节
删除:删除操作包括链表删除链表的开头以及返回其中的储存信息的值,这个操作是由成员函数deleteFromHead()实现的。将第一个节点的信息临时储存到本地变量el中,然后重置head这样第2个节点就变成了第一个节点。两种特殊情况:一种试图从空链表删除一个节点。如果试图这样做,程序有可能崩溃。第二种情况是删除节点的链表只有一个节点。在这种情况下,链表就会变成空的,这就要要求tail和head设置为null。
第一种情况结论方法:
- 使用assert语句
Int IntSLList::delete FromHead(){
Assert(! isEmpty());
Int el=head->info;
………
Return el;
}
检测条件!isEmpty(),如果条件是false。程序终止。但是即使没有返回值,也希望程序继续运行。 - 抛出异常并由用户捕获该异常。如下所示:
int IntSLList::FromHead(){
if(isEmpty())
throw(“Empty”);
int el=head->info;
………
return el;
}
在调用程序(或者调用程序的调用程序中),带字符串参数的throw语句应该有对应的try-catch语句。并且有用于捕获异常的字符串参数。
Void f(){
………
Try{
N=list.deleteFromHead;
}
Catch(char*s){
Cerr<<”Error:”<<s<<endl;
}
…………
}
这种方法调用程序可以控制异常的情况,不会像使用assert语句那样使程序崩溃。用户负责try-catch语句提供异常处理程序,如果没有提供这样的语句,那么抛出异常时程序会崩溃。当试图从空链表上删除数字时,函数f()会输出一条链表为空的信息,另一个函数g()可以在这种情况下将某个值赋给n,而函数h()则可能发现这种情况对程序有害而中止。 - 在程序代码中有isEmpty()用户可以这样使用这个函数
If (!list.isEmpty())
N=list. DeleteFromHead();
Else 不删除
不能在deleFromHead()中使用if无法解决问题而且必须加上else语句,否则程序报错,而且使用了返回值等于0会导致混淆。所以在调用deleteFromHead()之前必须使用if检测是否链表为空。代码如下:
Int IntSLList::ddeleteFromHead(){
If(!isEmpty()){
………
Return el;
}
Else
Return 0;
}
如果返回的是一个指向整数的指针而不是一个返回一个整数
N=*list. deleteFromHead();
如果返回的是一个空指针将会导致程序崩溃。因此在调用之前,调用程序必须检测链表是否为空,是否使用了指针变量
Int *p=list.deleFromHead();
在调用之后再检测p是否为空。在这两张情况下,deleteFromHead()中的if语句就是多余的。
第二种结论的方法:
这种情况下是待删除节点的链表只有一个节点,在这种情况下,链表会变成空的,这就需要将tail和head设置为null,
另外一种删除操作从链表的末尾删除节点。问题在于删除最后一个节点之后,tail节点无法直接指向他的前驱结点,所以使用一个临时变量tmp通过临时变量循环迭代到最后一个节点的前驱节点,在用tail指向这个节点
遍历操作简化代码
For(;head->next!=tail;head=head->head->next);
链表只能遍历一次,且无法访问链表的开头,因为head永久的指向最后一个节点的前驱结点并且这个节点将会变成最后一个节点,很明显在这样的情况下临时节点非常重要,使得程序可以像原来一样访问链表的开头。
与Fead类似删除最后一个节点存在两种特殊情况,如果链表为空,就不能删除任何节点,在这种情况下由用户程序来决定怎样处理,。第二种情况就是删除链表最后一个节点之后链表为空,应该吧head和tail设置成null。
在deleteFromtail()中最耗时的就是for循环遍历。
还有一种:前面讨论的这两种删除操作从开头或者末尾删除一个节点。如果要是删除一个包含特定整数的节点而不关心这个节点在链表中的位置,就需要使用不同的方法,首先找到这个节,将前驱结点与后续节点链接,从而将其从链接删除。查找并删除含有某个整数的节点比前面的删除操作复杂成员函数deleteNode()实现了这一功能。使用两个指针pred和tmp,这两个变量在for循环中初始化,分别指向第一个节点和第二个节点,开始迭代当tmp指向包含删除的节点时退出循环,执行pred->next=tmp->next,然后通过tmp将空间释放。
还有几种情况 - 试图从空链表中删除节点,此时函数立刻退出
- 从单节点链表中删除唯一节点head和tail都设置为null
- 从至少有两个节点中删除第一个节点,此时需要更新head
- 同上最后一个节点更新tail
- 链表中不包含任何数字的节点,不进行任何操作。
查找:
查找已有的链表,已确定其中是否包含某个数字,从函数的头开始,用一个临时变量tmp扫描整个链表,如果含有搜寻的整数跳出循环如果没有直到最后一个节点为空。如果不为空返回true,如果为空,返回false。在函数isInList()函数中执行。