資料結構-2.單向連結串列的實現

ffff5發表於2024-08-05

節點結構體設計

struct LinkNode
{
	// 資料域
	void* data;
	// 指標域
	struct LinkNode * next;
};
  • data:一個 void* 型別的指標,指向節點儲存的資料。使用 void* 是為了連結串列能夠儲存不同型別的資料。
  • next:一個指向下一個 LinkNode 結構體的指標,形成連結串列的連結。

連結串列結構體設計

struct LList
{
	//頭節點
	struct LinkNode pHeader;
	//連結串列長度
	int m_size;
};
  • pHeader:連結串列的頭節點。雖然 pHeader 本身也是 LinkNode 型別,但它可以作為連結串列的起始節點,其 next 指標指向第一個實際的資料節點。
  • m_size:一個整數,表示連結串列中節點的數量。

初始化連結串列

LinkList init_LinkList()
{
	struct LList* myList = malloc(sizeof(struct LList));
	
	if (myList == NULL)
	{
		return NULL;
	}

	myList->pHeader.data = NULL;
	myList->pHeader.next = NULL;
	myList->m_size = 0;

	return myList;
}
  • 使用 malloc 分配 struct LList 的記憶體。
  • 初始化頭節點的 data 指標為 NULLnext 指標也為 NULL
  • 設定連結串列長度 m_size0

插入連結串列

void insert_LinkList(LinkList list, int pos, void* data)
{
	if (list == NULL) 
	{
		return;
	}
	if (data == NULL)
	{
		return;
	}
	// 將list還原成struct LList資料型別
	struct LList * myList = list;

	if (pos <0 || pos > myList->m_size)
	{
		//位置無效 強制尾插
		pos = myList->m_size;
	}
	//找到插入節點的前驅
	struct LinkNode * pCurrent = &myList->pHeader;
	for (int i = 0; i < pos; i++)
	{
		pCurrent = pCurrent->next;
	}
	//建立新節點
	struct LinkNode* newNode = malloc(sizeof(struct LinkNode));
	newNode->data = data;
	newNode->next = NULL;

	//建立節點關係

	newNode->next = pCurrent->next;
	pCurrent->next = newNode;

	//更新連結串列長度
	myList->m_size++;
}
  • 檢查 listdata 是否為空,若為空則返回。
  • 如果位置 pos 無效(負數或超出連結串列當前大小),將位置設定為連結串列末尾。
  • 透過遍歷找到插入位置的前驅節點 pCurrent
  • 建立新節點並插入連結串列中。
  • 更新連結串列長度 m_size

遍歷連結串列

void foreach_linkList(LinkList list,void(*myForeach)(void *))
{
	if (list == NULL)
	{
		return;
	}

	struct LList* mylist = list;

	struct LinkNode* pCurrent = mylist->pHeader.next;
	for (int i = 0; i < mylist->m_size; i++)
	{
		myForeach(pCurrent->data);
		pCurrent = pCurrent->next;
	}
}
  • 檢查 list 是否為空,若為空則返回。
  • 使用 pCurrent 遍歷連結串列,從頭節點的下一個節點開始。
  • 對每個節點的資料呼叫 myForeach,然後移動到下一個節點。

相關文章