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.理解每個(gè)結(jié)構(gòu)體均有一個(gè)指針指向該結(jié)構(gòu)體,所以只需要一個(gè)指向當(dāng)前節(jié)點(diǎn)的指針和一個(gè)指向“當(dāng)前節(jié)點(diǎn)的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; }
? ? 以上代碼為最終修改和簡(jiǎn)化后代碼,修改和簡(jiǎn)化有如下幾點(diǎn):
? ? 1.函數(shù)不能越過(guò)鏈表尾部,所以采用判斷current值是否為空。防止越位
? ? 2.函數(shù)不能處理頭指針,所以采用將頭指針作為一個(gè)參數(shù)傳遞給函數(shù),即使用Node **而不是Node *。
? ? 3.為消除把節(jié)點(diǎn)插入鏈表起始位置作為特殊情況來(lái)處理的情況,采用linkp = ¤t->link來(lái)簡(jiǎn)化,此時(shí)linkp指向的是指向結(jié)構(gòu)的link字段。只需2個(gè)指針而不是3個(gè)。
? ? 4.由于循環(huán)之前的最后一條語(yǔ)句和循環(huán)之前的語(yǔ)句相同,將current的賦值嵌入到while表達(dá)式中。消除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; }
? ? 簡(jiǎn)化插入函數(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; }
? ? 再一步簡(jiǎn)化:
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;
? ? 再簡(jiǎn)化:
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.消除特殊情況使代碼易于維護(hù)。
? ? 2.通過(guò)提煉語(yǔ)句消除if中的重復(fù)語(yǔ)句。
? ? 3.不要僅僅根據(jù)代碼的大小評(píng)估其質(zhì)量。