2.单列表插入函数示例
#include <stdlib.h>
#include <stdio.h>
typedef struct Node{
struct Node *link;
int value;
}Node;
int sll_insert( register Node **rootp, int new_value )
{
register Node *current;
register Node *new;
//1.注意链表是否到尾部
//2.理解每个结构体均有一个指针指向该结构体,所以只需要一个指向当前节点的指针和一个指向“当前节点的link字段”的指针
while( ( current = *rootp ) != NULL && current->value < new_value )
rootp = ¤t->link;
new = (Node *)malloc( sizeof( Node ) );
if( new == NULL )
return 0;
else
new->value = new_value;
new->link = current;
*rootp = new;
return 1;
}
以上代码为最终修改和简化后代码,修改和简化有如下几点:
1.函数不能越过链表尾部,所以采用判断current值是否为空。防止越位
2.函数不能处理头指针,所以采用将头指针作为一个参数传递给函数,即使用Node **而不是Node *。
3.为消除把节点插入链表起始位置作为特殊情况来处理的情况,采用linkp = ¤t->link来简化,此时linkp指向的是指向结构的link字段。只需2个指针而不是3个。
4.由于循环之前的最后一条语句和循环之前的语句相同,将current的赋值嵌入到while表达式中。消除current的冗余赋值。
3.双向链表
#include <stdlib.h>
#include <stdio.h>
typedef struct Node{
struct Node *fwk;
struct Node *bwk;
int value;
}Node;
int sll_insert( Node **rootp, int new_value )
{
Node *this;
Node *next;
Node *newNode;
for( this = *rootp ;( next = this->fwk ) != NULL; this = next )
{
if( next->value == new_value )
return 0;
if( next->value > new_value )
break;
}
newNode = (Node *)malloc( sizeof( Node ) );
if( newNode == NULL )
return -1;
else
newNode->value = new_value;
if( next != NULL)
{
if( this != rootp )
{
newNode->bwk = this;
newNode->fwk = next;
this->fwk = newNode;
next->bwk = newNode;
}
else
{
newNode->bwk = NULL;
newNode->fwk = next;
rootp->fwk = newNode;
next->bwk = newNode;
}
}
else
{
if( this != rootp )
{
newNode->bwk = this;
newNode->fwk = NULL;
this->fwk = newNode;
rootp->bwk = newNode;
}
else
{
newNode->bwk = NULL;
newNode->fwk = NULL;
rootp->fwk = newNode;
rootp->bwk = newNode;
}
}
return 1;
}
简化插入函数:
if( next != NULL)
{
newNode->fwk = next;
if( this != rootp )
{
newNode->bwk = this;
this->fwk = newNode;
}
else
{
newNode->bwk = NULL;
rootp->fwk = newNode;
}
next->bwk = newNode;
}
else
{
newNode->fwk = NULL;
if( this != rootp )
{
newNode->bwk = this;
this->fwk = newNode;
}
else
{
newNode->bwk = NULL;
rootp->fwk = newNode;
}
rootp->bwk = newNode;
}
再一步简化:
newNode->fwk = next;
if( this != rootp )
{
newNode->bwk = this;
this->fwk = newNode;
}
else
{
newNode->bwk = NULL;
rootp->fwk = newNode;
}
if( next != NULL)
next->bwk = newNode;
else
rootp->bwk = newNode;
再简化:
int sll_insert( register Node **rootp, int new_value )
{
register Node *this;
register Node *next;
register Node *newNode;
for( this = *rootp ;( next = this->fwk ) != NULL; this = next )
{
if( next->value == new_value )
return 0;
if( next->value > new_value )
break;
}
newNode = (Node *)malloc( sizeof( Node ) );
if( newNode == NULL )
return -1;
else
newNode->value = new_value;
newNode->fwk = next;
this->fwk = newNode;
if( this != rootp )
newNode->bwk = this;
else
newNode->bwk = NULL;
if( next != NULL)
next->bwk = newNode;
else
rootp->bwk = newNode;
return 1;
}
倘若丧心病狂,那么如下定是极好的:
newNode->fwk = next;
this->fwk = newNode;
newNode->bwk = ( this != rootp) ? this : NULL;
( next != NULL ? next : rootp )->bwk = newNode
总结:
1.消除特殊情况使代码易于维护。
2.通过提炼语句消除if中的重复语句。
3.不要仅仅根据代码的大小评估其质量。