隨想錄(再談鏈表)

來源:互聯網
上載者:User

【 聲明:著作權,歡迎轉載,請勿用於商業用途。  聯絡信箱:feixiaoxing @163.com】


    在軟體開發中,我想鏈表是除了數組之外,用的最多的一種資料結構。但是,如何把鏈表結構和資料本身能夠完美地融合在一起,這本身確是一件複雜的事情。但是linux kernel在這方面為我們做出了示範,讓我們在充分地享受方便的同時,無需考慮鏈表的一些具體操作。那麼,在linux kernel下面,鏈表是怎麼做到的呢?我們可以自己編寫一個代碼示範一下,基本原理都是一樣的,可能在實現方式上略有不同。


(1)定義鏈表的基本結構

typedef struct _LINK_NODE{struct _LINK_NODE* prev;struct _LINK_NODE* next;}LINK_NODE;

(2)定義鏈表的基本操作

void link_init(struct _LINK_NODE* pNode){ASSERT(NULL != pNode);pNode->prev = NULL;pNode->next = NULL;}void link_add(struct _LINK_NODE* pNode, struct _LINK_NODE* head){ASSERT(NULL != pNode && NULL != head);pNode->next = head->next;pNode->prev = head;head->next = pNode;if(pNode->next)pNode->next->prev = pNode;}void link_del(struct _LINK_NODE* pNode){ASSERT(NULL != pNode);pNode->prev->next = pNode->next;if(pNode->next)pNode->next->prev = pNode->prev;}

    這裡定義了鏈表的三個基本操作,即初始化、添加和刪除。我們在這裡設計的時候,為了說明方便,考慮的情況比較簡單。這裡編寫的代碼其實是有三個基本前提的:鏈表存在一個head節點,這個節點永遠不刪除;鏈表添加的資料都是放在head後面的;鏈表雖然是雙向鏈表,但本身並不是迴圈鏈表。

(3)在資料中嵌套使用LINK_NODE

typedef struct _DATA_TYPE{LINK_NODE head;int value;}DATA_TYPE;

    這裡定義了一個簡單的資料類型,即為DATA_TYPE。可是,我們記得前面定義的操作都是 關於 LINK_NODE的,那麼我們如何才能利用LINK_NODE資料本身訪問到DATA_TYPE資料本身呢?其實不難,轉化一下資料即可。

(4)利用pNode訪問pData
    現在假設存在這樣的一個節點pNode,它的地址就是在DATA_TYPE中head的地址,那麼怎麼才能進行轉化呢?我們看看下面的代碼是怎麼做的?大家也可以自己在編譯器上試一試?

#define GET_DATA_ADDRESS(pNode, DATA, head) \(DATA*)((char*)(pNode) - (&((DATA*)(0))->head))

    這是一個宏,如果需要實際運算的話,應該這麼做。

DATA_TYPE* pData =  GET_DATA_ADDRESS(pNode, DATA_TYPE, head);

    這中間其實存在一個技巧。那就是我們既然知道pNode的地址,那麼只需要知道pNode和pData之間的位移值就可以了。兩者相減一下,獲得值就是pData的數值,所以,這裡可以利用(&((DATA*)(0))->head)擷取這個位移值,就是這麼簡單。

(5)利用pNode遍曆pData
    因為這裡的pNode是一個鏈表,所以利用pNode遍曆pData就十分方便了。根據上面開發的思路,我們這裡依然可以利用宏的方法實現pData和pNode之間的自動轉換。

#define FOR_EACH_DATA(pNode, pData, DATA, head) \for(; \    pNode && (pData = GET_DATA_ADDRESS(pNode, DATA, head));\pNode = pNode->next)

    使用的話依然十分簡單,簡單輸入資料和資料結構類型即可,

FOR_EACH_DATA(pNode, pData, DATA_TYPE, head){printf("pData->value = %d\n", pData->value);}

(6)其他

    通常為了使用方便,鏈表還會引申出更多的功能,比如自訂head節點,添加list的統計函數,或者是修改添加的方式、刪除的方式等等。這些功能朋友們自己根據需要可以獨立完成。當然,如果大家的思維再發散一下,也可以把這種方法推廣到二叉樹、平衡二叉樹或者是紅/黑樹狀結構上面。總之一句話,鏈表是我們在編程中使用得最多地一種技巧方法,希望朋友們可以多多掌握。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.