C和指针_第12章_使用结构和指针_学习笔记
扫描二维码
随时随地手机看文章
2.单列表插入函数示例
#include#includetypedef 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#includetypedef 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.不要仅仅根据代码的大小评估其质量。