劍指offer 6:鏈表(從頭到尾打印鏈表)


鏈表的數據結構

struct ListNode
{
	int value;
	ListNode* next;
};

  那么在鏈表的末尾添加一個節點的代碼如下:

void insert(ListNode** pHead, int value)
{
	ListNode* pNew = new ListNode;
	pNew->value = value;
	pNew->next = NULL;
	if (*pHead == NULL)
	{
		*pHead = pNew;
	}
	else
	{
		ListNode* temp = *pHead;
		while (temp->next != NULL)
		{
			temp = temp->next;
		}
		temp->next = pNew;
	}
}

  在上面的代碼中,我們要特別注意函數的第一個參數是pHead是一個指向指針的指針。當我們往一個空鏈表中插入一個節點時,新插入的節點就是鏈表的頭指針。由於此時會改動頭指針,因此必須把pHead參數設為指向指針的指針,否則出了這個函數pHead仍然是一個空指針。

這這里指針的指針可以這樣理解——pHead是一個指向指針的指針,*pHead是一個指針,鏈表的結點也是指針類型,那么pHead就可以指向多個指針,這樣就可以把鏈表的所有結點連接起來形成一條鏈。

  由於鏈表中的內存不是一次性分配的,因而我們無法保證鏈表的內存和數組一樣時連續的。因此,如果想在鏈表中找到它的第i個節點,那么我們只能從頭節點開始,沿着指向下一個節點的指針遍歷鏈表,它的時間效率為O(n)。而在數組中,我們可以根據下標在O(1)時間內找到第i個元素。下面是在鏈表中找到第一個含有某值的節點並刪除該節點的代碼:

void RemoveNode(ListNode** pHead, int value)
{
	if (pHead == NULL && (*pHead) == NULL)//如果鏈表為空
	{
		return;
	}
	ListNode* pdelete = NULL;
	if ((*pHead)->vaule == value)
	{
		pdelete = *pHead;
		*pHead = (*pHead)->next;
	}
	else
	{
		ListNode* pNode = *pHead;
		while (pNode->next != NULL && pNode->next->value != value)
		{
			pNode = pNode->next;
		}
		if (pNode->next != NULL && pNode->next->value == value)
		{
			pdelete = pNode->next;
			pNode->next = Pnode->next->next;
		}
	}
	if (pdelete != NULL)
	{
		delete pdelete;
		pdelete = NULL;
	}
}

 

從尾到頭打印鏈表

我們可以用棧實現這種順序。每經過一個節點的時候,把該節點放到一個棧中。當遍歷完整個鏈表后,再從棧頂開始逐個輸出節點的值,此時輸出的結點的順序已經反轉過來了。這種思路的實現代碼如下:

void printf_RList(ListNode *pHead)
{
	stack<ListNode*>nodes;
	ListNode* pNode = pHead;
	while (pNode != NULL)
	{
		nodes.push(pNode);
		pNode = pNode->next;
	}
	while (!nodes.empty())
	{
		pNode = node.top();
		cout << pNode << " ";
		nodes.pop();
	}
}

  既然想到了用棧來解決這個函數,而遞歸在本質上就是一個棧結構,於是很自然地又想到了用遞歸來實現。要實現反過來的鏈表,我們每訪問到一個節點的時候,先遞歸輸出它后面的節點,再輸出該節點自身,這樣鏈表的輸出結果就反過來了。

基於這樣的思路不難寫出如下代碼:

void printf_RList(ListNode* pHead)
{
    if (pHead != NULL)
    {
        if (pHead->next != NULL)
        {
            printf_RList(pHead->next);
        }
        cout << pHead->value<<" ";
    }
}

 


免責聲明!

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



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