数据结构之单链表常见面试题

逆序打印单链表

     逆序打印单链表有两种方法,分别是递归和非递归。

-----------------------------//递归实现逆序打印-----------------------------------

void PrintTailToHead(pList *pplist)
{
  	if (*pplist == NULL)   //空链表
		return;            
	if ((*pplist)->next == NULL)  //链表只有一个节点
	{
		printf("%d\n", (*pplist)->data);
		return;
	}
    PrintTailToHead((*pplist)->next);
    printf("%d\n",(*pplist)->data);
}

-----------------------------------------------------------------------------------


---------------------------------//非递归实现逆序打印---------------------------------
void PrintTailToHeadNor(pList *pplist)
{
	pNode cur = NULL;
	pNode tail = NULL;
	cur = *pplist;
	if (*pplist == NULL)
		return;
	if ((*pplist)->next == NULL)
	{
		printf("%d\n", (*pplist)->data);
		return;
	}
	while (*pplist != tail)
	{
		cur = *pplist;
		while (cur->next != tail)
		{
			cur = cur->next;
		}
		printf("%d->", cur->data);
		tail = cur;
	}
	printf("NULL\n");
}
------------------------------------------------------------------------------------

 

删除一个无头单链表的非尾节点 

---------------------------------------------------------------------------------
void EraseNotTailNode(pNode pos)
{
	pNode del = NULL;
	if (pos == NULL || pos->next == NULL)
		return;
	del = pos->next;
	pos->data = del->data;
	pos->next = del->next;
	free(del);
	del = NULL;
}
---------------------------------------------------------------------------------

 

在无头单链表的一个节点前插入一个节点(不能遍历链表)

----------------------------------------------------------------------------------
pNode BuyNode(DataType d)//创建新节点
{
	pNode newNode = (pNode)malloc(sizeof(Node));
	if (newNode == NULL)
	{
		perror("BuyNode : :malloc");
		return NULL;
	}
	newNode->data = d;
	newNode->next = NULL;
	return newNode;
}

void InsertPosFrontNotTailNode(pNode pos, DataType x)
{
	pNode newNode = NULL;
	if (NULL == pos)
		return;
	newNode = BuyNode(pos->data);
	newNode->next = pos->next;
	pos->next = newNode;
	pos->data = x;
}
----------------------------------------------------------------------------------

查找链表的中间节点(只遍历一次) 

        该问题涉及到了快慢指针问题:分别定义一个快指针(走两步)和慢指针(走一步),当快指针遍历完整个链表时,慢指针刚好指向链表中间节点,这样我们通过只遍历一次链表的方式得到链表中间节点。

------------------------------------------------------------------------------------
pNode FindMiddleNode(pNode pHead)//快慢指针问题
{
	pNode Fast = pHead;
	pNode Slow = pHead;//节点个数为奇数,查找到的是中间节点;节点个数为偶数,查找到的是后一个节点。
	if (NULL == pHead)
		return NULL;
	while (Fast && Fast->next)
	{
		Fast = Fast->next->next;
		Slow = Slow->next;
	}
	return Slow;
}
------------------------------------------------------------------------------------

判断单链表是否带环

      判断链表带环问题时,分别定义一个快指针(走两步)和慢指针(走一步),如果两个指针最终相遇,即证明单链表带环。

----------------------------------------------------------------------------------
pNode HasListCircle(pNode pHead) 
{
	pNode Fast = pHead;
	pNode Slow = pHead;
	while (Fast && Fast->next)
	{
		Fast = Fast->next->next;
		Slow = Slow->next;
		if (Fast == Slow)
			return Fast;
	}
	return NULL;
}
----------------------------------------------------------------------------------

求带环链表的入口点

      求解此问题首先得确定目标链表带环,且得求出相遇点。

----------------------------------------------------------------------------------
pNode EntryNodeListCircle(pNode pHead, pNode meet) 
{
	assert(pHead);
	Node* cur = pHead;
	Node* met = meet;
	if (NULL == meet)
		return 0;
	while (cur != met)
	{
		cur = cur->next;
		met = met->next;
	}
	return met;
}

----------------------------------------------------------------------------------

求带环链表中环的长度

----------------------------------------------------------------------------------
int GetCircleLen(pNode meet)
{
	int count = 1;
	Node* cur = meet;
	if (NULL == meet)
		return 0;
	while (cur->next != meet)
	{
		count++;
		cur = cur->next;
	}
	return count;
}
----------------------------------------------------------------------------------

查找单链表的倒数第K个节点

-----------------------------------------------------------------------------------
pNode FindLastKNode(pNode pHead, int k)
{
	pNode Fast = pHead;
	pNode Slow = pHead;
	if (NULL == pHead || k <= 0)
		return NULL;
	while (k--)
	{
		if(NULL == Fast)
			return NULL;
		Fast = Fast->next;
	}
	while (Fast)
	{
		Fast = Fast->next;
		Slow = Slow->next;
	}
	return Slow;
}
-----------------------------------------------------------------------------------

单链表的逆置(不带环)

--------------------------------------------------------------------------------------
void Reverse_Link(pList *pplist)
{
	pNode pre = NULL;
	pNode cur = NULL;
	pNode next = NULL;
	assert(pplist!= NULL);
	cur = *pplist;
	while (cur)
	{
		next = cur->next;
		cur->next = pre;
		pre = cur;
		cur = next;
	}
	*pplist = pre;
}
--------------------------------------------------------------------------------------

冒泡排序单链表

----------------------------------------------------------------------------------
void BubbleSort(pNode pHead)
{
	pNode TailNode = NULL;
	if (NULL == pHead || NULL == pHead->next)
		return;
	while (TailNode != pHead)
	{
		pNode pre = pHead;
		pNode cur = pre->next;
		while (cur != TailNode)
		{
			if (pre->data > cur->data)
			{
				DataType tmp = pre->data;
				pre->data = cur->data;
				cur->data = tmp;
			}
			pre = cur;
			cur = cur->next;
		}
		TailNode = pre;
	}
}
----------------------------------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/ENSHADOWER/article/details/82925980
今日推荐