給定乙個單鏈表,刪除該鍊錶中某些節點。乙個節點該不該刪除由函式remove()決定,該單鏈表刪除的函式原型為 struct listnode* removeif(struct listnode* head, removefn* remove)。下面給出三種解法,主要是想突出第三種使用二級指標的方法。
這個是我自己瞎憋出來的,跟第二種教科書上的方法非常類似,只是我少用了乙個變數,但是邏輯比第二種複雜。基本思路:
如果乙個節點不要刪除,則移動下乙個節點;
如果乙個節點需要刪除,則判斷它是不是頭節點,如果是則要將頭節點指標指到下乙個節點,這裡通過prev_node是否為空來判斷;如果不是,則prev_node不動,current_node移到下乙個節點。
struct listnode* removeif1(struct listnode* head, removefn* remove)
else
free(current_node);
current_node = (null == prev_node)?
head : prev_node->next;
} else
}return head;
}
多使用了乙個next變數,邏輯簡單清楚了一些。
struct listnode* removeif2(struct listnode* head, removefn* remove)
else
free(current_node);
} else
current_node = next_node;
}return head;
}
這個方法的優點在於不要判斷被刪除的節點是不是頭節點,邏輯更加清楚。基本原理其實就是只要遇到第乙個不要刪除的節點之後就不要處理頭節點問題了,因為此時頭節點已經確定下來。所以在else塊裡面會移動二級指標,因為此時的head已經確定了。而在if塊裡面,只是改變了ptr_current_node所指向的內容,如果頭節點還沒確定時,ptr_current_node與head相同,也就是改變了head指向的頭節點位置。這個方法確實效率更高,真是linus講的core low-level coding。
void removeif3(struct listnode** head, removefn * remove)
else
}}
#include#includestruct listnode
;struct listnode* createlist(int n)
return node;
}void removelist(struct listnode* head)
}int isremove(struct listnode* node)
typedef int removefn(struct listnode*);
void printlist(struct listnode* head)
if(head) printf("%d\n", head->val);
}int main()
輸出
$ ./a.out
test 1: 0, 2, 4
test 2: 0, 2, 4, 6
test 3: 0, 2, 4, 6, 8
雙向鍊錶(二級指標實現)
include include typedef struct newlist onelist int insertone onelist old flist,onelist old elist,int a else else if q data a q next null else if q dat...
鍊錶 二級指標的使用
博文的記錄源自閱讀著名的酷殼主頁 coolshell 並茂說明了這個問題 我們在刪除鍊錶的時候,常常需要記錄該結點在鍊錶中是否有前趨prev。如果有,那麼需要把prev next指向該結點的next域,然後再刪除該結點,這樣才能保證鍊錶不會因為刪除結點而 斷開 像這樣 void remove lis...
List二級鍊錶
二級鍊錶的實現,以及把二級鍊錶展開成一級鍊錶,關鍵是資料結構的設計,這裡我用了二級鍊錶的節點類,它包括了兩個指標,乙個指向乙個二級鍊錶節點,乙個指向單鏈表的頭結點。生成乙個二級鍊錶預設建構函式是只含有乙個頭結點為二級鍊錶節點 空 插入的時候是插入乙個單鏈表指標不為空,但是二級鍊錶節點為空的二級鍊錶節...