C和指針_第12章_使用結(jié)構(gòu)和指針_學(xué)習(xí)筆記
2.單列表插入函數(shù)示例
#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.理解每個結(jié)構(gòu)體均有一個指針指向該結(jié)構(gòu)體,所以只需要一個指向當(dāng)前節(jié)點的指針和一個指向“當(dāng)前節(jié)點的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.函數(shù)不能越過鏈表尾部,所以采用判斷current值是否為空。防止越位
? ? 2.函數(shù)不能處理頭指針,所以采用將頭指針作為一個參數(shù)傳遞給函數(shù),即使用Node **而不是Node *。
? ? 3.為消除把節(jié)點插入鏈表起始位置作為特殊情況來處理的情況,采用linkp = ¤t->link來簡化,此時linkp指向的是指向結(jié)構(gòu)的link字段。只需2個指針而不是3個。
? ? 4.由于循環(huán)之前的最后一條語句和循環(huán)之前的語句相同,將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; }
? ? 簡化插入函數(shù):
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
總結(jié):
? ? 1.消除特殊情況使代碼易于維護。
? ? 2.通過提煉語句消除if中的重復(fù)語句。
? ? 3.不要僅僅根據(jù)代碼的大小評估其質(zhì)量。