剑指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<<" ";
    }
}

 

posted @ 2018-09-11 00:36  cs_wu  阅读(1730)  评论(0编辑  收藏  举报