線性表的兩種存儲方式解析.


順序存儲:

typedef struct _tag_LinkNode
{
	int length;
	int capacity;
	void **node;
}Link;

用以上結構體表達,length表示線性表目前有多少元素,capacity表示整個線性表的容量(創建之時已固定)

而這個node,最不容易理解,可以抽象為一個指針數組.每個元素都指向一個業務節點的內存地址,在創建之時必須與capacity動態綁定,代表可以容納多少個業務節點.

在封裝內部方法時,核心思想是業務層將業務節點轉換成void *傳遞進來.保存在**node數組指針中,(unsigned int)類型也可以保存指針值.

內部再提供一個方法,將數組指針的某一個指針返回給業務層,業務層再根據實際情況進行指針轉換,拿到數據進行操作.

 

鏈式存儲:

typedef struct _tag_LinkListNode  //h頭文件
{
	struct _tag_LinkListNode* next;
}LinkListNode;


typedef struct _tag_LinkList    //內部封裝
{
	//這個句柄里面,需要保存所有節點信息。需要有一個起始點
	//就是帶頭節點的鏈表。。。
	LinkListNode header;
	int length;
}TLinkList;


typedef struct Teacher    //上層業務
{
	LinkListNode node;
	char name[64];
	int age;
}Teacher;

 

如代碼所示,頭文件定義的這個節點,是所有實現的核心,內部封裝需要包含它,業務節點也需要包含它,但均要將其放在第一個域中,

用圖來表示

 

TLinklist其實就是左邊最大的那個,與我以前所學習的不一樣.以前學習的只是定義一個節點,將指針域放在其中,而這里,定義的是個鏈表,不包含業務數據,將業務數據與鏈表算法分離開來,實現低耦合,其技術的精華之處在以下代碼
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos)
{
	int i = 0;

	TLinkList *tList  = NULL;
	LinkListNode *current = NULL;

	tList = (TLinkList *)list;
	//准備環境讓輔助指針變量 指向鏈表頭節點
	current = &tList->header;
	for (i=0; i<pos &&(current->next!=NULL); i++)
	{
		current = current->next;
	}

	//讓node節點鏈接后續鏈表
	node->next = current->next ;
	//讓前邊的鏈表。鏈接node
	current->next = node;
	tList->length ++;	
	return 0;
}

在17行的node->next = current->next ,這個node就是業務層傳遞進來的業務節點,將其轉換成了LinkListNode,

關鍵來了,在業務節點里,node在第一個域,以前學習過->,.其實就是尋址操作(然后自動加*號取值)

而使用第一個域node,對於業務節點,只偏移了四個字節,前面說過,node就

是業務層傳遞進來的業務節點,雖然類型發生了變化,但里面的內容沒變,偏移的四個字節剛好只是訪問了業務節點中的node域,進而實現的業務節點的串連

17行的這個node就是間接地操作業務節點中的node

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM