今天晚上用模板方法把雙向鏈表實現了下,由於有點小粗心,在 insert中手抖了下,把tail->prev 打成了 tail->next,由於錯誤是發生在drop函數執行時,讓我一直去調drop函數,調了半天還是一樣錯誤,最後我系統在vs中監視了下值的變化,終於看到是insert出錯了。 看來程序員離不開調試呀。
另外,昨天說的模板輸出重載,我說要在友元的實現時加上 <>, 但是今天我在gcc中測試了下,居然說找不到匹配的函數,導致編譯不通過,真心蛋疼,vs和g++的區別還真心大,看來改天要好好專研下模板輸出重載,知道的朋友希望能夠告知下。
對數據結構的實現,其實都很簡單,思想就是:
1、定義結點結構類,包含數據域和指針域
2、定義 鏈表(樹,圖)結構,其中封裝包含幾個結點,作為數據接口,因為節點定義指向自身類型的指針,因此而後所有的操作都圍繞這個數據接口進行。
對於雙向鏈表來說,結點定義很簡單,一個數據域,一個next指針,表示以後他將指向下一個結點; 一個prev指針,表示它將指向前一個結點。
template<typename T> **
由於鏈式結構添加的結點都要new出來,且結點類包含了數據域,因此需要對結點類進行構造函數的編寫,一般兩個,帶數據域的(以後new來做鏈表中結點),默認無參的(用於new給head和tail的);析構函數就不用了,因為其指針域所指向的東西是由表結構new出來的,操作應該留給表。
結點類定義好了後,我們定義下鏈表類,主要部分就是要包含下 head 指針, tail 指針。
另外,所有的表(樹,圖結構)包含個 “表示長度的數據”,如size, 這樣求length()操作只要O(1)的復雜度,要不然就要遍歷整個鏈表,復雜度就是O(n)了。
,head->prev 指向自身或NULL;
,tail->next指向自身或NULL; 這樣規定了head,tail後,後面的操作就會很順暢,我們就可以next/prev到底了,哈哈。
空的條件為: size == 0 或者 head->next == NULL 或者 tail->prev == NULL ,看個人喜好。
剩下一些增刪改查操作,別手抖寫錯了指向關系就行,另外可以加上一個位置判斷,看看是從頭或從尾開始,哪邊移動的少。
函數寫法可以給的建議是:
若只是訪問不修改,成員函數為const;
若需要操作類類型,則用 & 或 const&;
好的,直接上代碼:
先是頭文件,注意最後一行;
View Code接著是實現文件:
View Code最後是測試文件:
View Code結果如下圖所示:
補充: 其實還可以重載更多的操作符,有心情的朋友可以自己添加下,比如++(int), ++操作等。甚至,可以加入個迭代器類,這樣更方便使用,有時間可以實現下哦。
另外,心細,心細,手別抖。 自勉下!