c语言链表以及面试题

#ifndef __PNODE_H__     //不带头结点的链表
#define __PNODE_H__

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

typedef int DataType;

typedef struct Node
{
	DataType data;
	struct Node *next;
}Node, *PNode;


void InitList(PNode* pHead);  //链表初始化
void PushBack(PNode* pHead, DataType data);//尾插
void PopBack(PNode* pHead);//尾删
void PushFront(PNode* pHead, DataType data);//头插
void PopFront(PNode* pHead);//头删
PNode Find(PNode pHead, DataType data);//找数据是data的这个节点
void Insert(PNode pos, DataType data);//插入
PNode ByeNode(DataType data);//申请一个新的节点,并初始化
void PrintList(PNode pHead); //打印链表

void Remove(PNode* pHead, DataType data);//删除链表中第一个data元素
void RemoveAll(PNode* pHead, DataType data);//删除链表中所有的data元素
void Erase(PNode* pHead, PNode pos);//删除pos位置的元素
void Destroy(PNode* pHead);//销毁链表
int Empty(PNode pHead);//判断链表是否为空
int Size(PNode pHead);//求链表中节点的个数
PNode LastNode(PNode pHead); //找最后一个节点的位置

void PrintListFromT2H(PNode pHead); //倒着打印链表中的内容(使用递归)
void DeleteNotTail(PNode pos);   //删除无头单链表的非尾节点(假删除)
void InsertNotHead(PNode pHead, PNode pos, DataType data);  // 在无头单链表的一个非头节点前插入一个节点(假删除) 
void JosephCircle(PNode* pHead, int M);  //单链表实现约瑟夫环(JosephCircle) 
PNode FindMidNode(PNode pHead);  //查找单链表的中间节点,要求只能遍历一次链表(快慢指针)
PNode FindLastKNode(PNode pHead, int k);  // 查找单链表的倒数第k个节点,要求只能遍历一次链表(快慢指针)

PNode ReverseList(PNode pHead);//逆置单链表
void BubbleSort(PNode pHead);
PNode MergeList(PNode pList1, PNode pList2);//合并两个有序的单链表,合并后仍然有序
int IsCross(PNode pHead1, PNode pHead2);//判断两个不带环单链表是否相交
PNode GetCrossNode(PNode pHead1, PNode pHead2);//求两个不带环链表的交点

PNode HasCircle(PNode pHead);//判断链表是否带环
int GetCirclrLen(PNode pMeetNode);//求带环链表环的长度
PNode GetEnterNode(PNode pHead, PNode pMeetNode);// 获取环的入口点
int IsCrossWithCircle(PNode pHead1, PNode pHead2);//判断两个链表是否相交(可能带环)
void UnionSet(Node* l1, Node* l2);//求两个已排序单链表中相同的数据--打印出来

void OddEven(PNode *pHead);//奇数在前,偶数在后,且都进行颠倒

#endif //__PNODE_H__




#include "PNode.h" 

void InitList(PNode* pHead)
{
	assert(pHead);

	*pHead = NULL;
}

PNode ByeNode(DataType data)
{
	PNode pNode = (PNode)malloc(sizeof(Node));
	if (pNode != NULL)
	{
		pNode->data = data;
		pNode->next = NULL;
	}
	else
	{
		printf("空间申请失败!\n");
	}
	return pNode;
}

void PushBack(PNode* pHead, DataType data)
{
	assert(pHead);

	PNode pTmp = *pHead;

	if (NULL == *pHead)
	{
		*pHead = ByeNode(data);
	}
	else
	{
		while (pTmp->next)
		{
			pTmp = pTmp->next;
		}
		pTmp->next = ByeNode(data);
	}
}

void PopBack(PNode* pHead)
{
	assert(pHead);

	PNode pTmp = *pHead;

	while (pTmp->next->next)
	{
		pTmp = pTmp->next;
	}
	free(pTmp->next);
	pTmp->next = NULL;
}

void PushFront(PNode* pHead, DataType data)
{
	assert(pHead);

	PNode pTmp = ByeNode(data);

	pTmp->next = *pHead;
	(*pHead) = pTmp;
}

void PopFront(PNode* pHead)
{
	assert(pHead);

	PNode pTmp = (*pHead);

	*pHead = pTmp->next;
	free(pTmp);
}

PNode Find(PNode pHead, DataType data)
{
	assert(pHead);

	PNode pTmp = pHead;
	while (pTmp)
	{
		if (pTmp->data == data)
		{
			return pTmp;
		}
		pTmp = pTmp->next;
	}
	return NULL;
}

void Insert(PNode pos, DataType data)
{
	assert(pos);

	PNode pTmp = ByeNode(data);
	pTmp->next = pos->next;
	pos->next = pTmp;
}

void PrintList(PNode pHead)
{
	assert(pHead);

	PNode pTmp = pHead;
	while (pTmp)
	{
		printf("%d ",pTmp->data);
		pTmp = pTmp->next;
	}
	printf("\n");
}

void Remove(PNode* pHead, DataType data)
{
	assert(pHead);

	Erase(pHead,Find(*pHead,data));
}

void RemoveAll(PNode* pHead, DataType data)
{
	assert(pHead);
	
	PNode pTmp = *pHead;
	PNode del;

	while (del=Find(pTmp, data))
	{
		Erase(pHead, del);
	}
}

void Erase(PNode* pHead, PNode pos)
{
	assert(pHead);

	PNode pTmp = *pHead;
	
	if (Empty(*pHead))
	{
		printf("链表为空!\n");
	}
	else
	{
		while (pTmp->next != pos && pTmp->next!=NULL)
		{
			pTmp = pTmp->next;
		}
		if (pTmp->next == NULL)
			printf("未找到该位置!\n");
		else
		{
			pTmp->next = pos->next;
			free(pos);
			pos = NULL;
		}
	}
}

void Destroy(PNode* pHead)
{
	assert(pHead);
	
	PNode pTmp = *pHead;
	while (pTmp)
	{
		*pHead = (*pHead)->next;
		free(pTmp);
		pTmp = *pHead;
	}
	*pHead = NULL;
}

int Empty(PNode pHead)
{
	if (NULL == pHead)
		return 1;
	else
		return 0;
}

int Size(PNode pHead)
{
	assert(pHead);

	int count = 0;
	PNode pTmp = pHead;

	while (pTmp)
	{
		pTmp = pTmp->next;
		count++;
	}
	return count;
}

void PrintListFromT2H(PNode pHead)
{
	assert(pHead);
	if (pHead->next)
	{
		PrintListFromT2H(pHead->next);
	}
	printf("%d ",pHead->data);
}

void DeleteNotTail(PNode pos)
{
	assert(pos);
	if (NULL == pos->next)
	{
		printf("该节点是尾节点!\n");
		return;
	}

	PNode pTmp = pos->next;

	pos->data = pTmp->data;
	pos->next = pTmp->next;
	free(pTmp);
}

void InsertNotHead(PNode pHead, PNode pos, DataType data)
{
	assert(pHead && pos);

	PNode pTmp = ByeNode(data);

	if (pos == pHead)
	{
		printf("该节点是第一个节点!\n");
		free(pTmp);
		return;
	}

	pTmp->next = pos->next;
	pos->next = pTmp;
	pTmp->data = pos->data;
	pos->data = data;
}

PNode LastNode(PNode pHead)
{
	assert(pHead);

	PNode pTmp = pHead;
	while (pTmp->next)
	{
		pTmp = pTmp->next;
	}
	return pTmp;
}

void JosephCircle(PNode* pHead, int M)
{
	assert(pHead);

	PNode pTmp = *pHead;
	int count = 0;

	while (pTmp != pTmp->next)
	{
		count = M;
		while (--count)
		{
			pTmp = pTmp->next;
		}
		PNode pDel = pTmp->next;
		pTmp->data = pDel->data;
		pTmp->next = pDel->next;
		free(pDel);
	}
}

PNode FindMidNode(PNode pHead)
{
	assert(pHead);

	PNode pFast = pHead;
	PNode pSlow = pHead;

	while (pFast && pFast->next)//前者是个数为偶数时的结束条件,后者为奇数个时的结束条件
	{
		pFast = pFast->next->next;
		pSlow = pSlow->next;
	}

	return pSlow; //当为偶数个时,返回中间两个数的后一个数的地址
}

PNode FindLastKNode(PNode pHead, int k)
{
	assert(pHead);

	PNode pFast = pHead;
	PNode pSlow = pHead;

	while (--k) 
	{
		if (pFast->next == NULL) 
		{
			return NULL;
		}
		pFast = pFast->next;
	}

	while (pFast->next)
	{
		pFast = pFast->next;
		pSlow = pSlow->next;
	}

	return pSlow;
}

PNode ReverseList(PNode pHead)
{
	assert(pHead);

	PNode pCur = pHead;
	PNode pPre = pCur->next;
	PNode pSav = pPre->next;

	if (NULL == pHead->next)
	{
		return pHead;
	}

	while (pSav)
	{
		pPre->next = pCur;
		pCur = pPre;
		pPre = pSav;
		pSav = pSav->next;
	}

	pPre->next = pCur;
	pHead->next = NULL;
	pHead = pPre;

	return pHead;
}

void BubbleSort(PNode pHead)//升序
{
	assert(pHead);

	PNode pEnd = NULL;
	PNode pFirst = NULL;
	PNode pSecond = NULL;

	if (NULL == pHead->next)
	{
		return;
	}

	while (pEnd != pHead)
	{
		pFirst = pHead;
		pSecond = pFirst->next;
		while (pSecond != pEnd)
		{
			if (pFirst->data > pSecond->data)
			{
				DataType tmp = pFirst->data;
				pFirst->data = pSecond->data;
				pSecond->data = tmp;
			}
			pFirst = pFirst->next;
			pSecond = pSecond->next;
		}
		pEnd = pFirst;
	}
}

PNode MergeList(PNode pList1, PNode pList2)
{
	PNode q1 = pList1;
	PNode q2 = pList2;
	PNode qNew = NULL;
	PNode qNewEnd = qNew;

	if (pList1 == NULL)
	{
		return pList2;
	}
	if (pList2 == NULL)
	{
		return pList1;
	}

	if (q1->data < q2->data)
	{
		qNew = q1;
		qNewEnd = q1;
		q1 = q1->next;
	}		
	else
	{
		qNew = q2;
		qNewEnd = q2;
		q2 = q2->next;
	}
		
	while (q1 && q2)
	{
		if (q1->data < q2->data)
		{
			qNewEnd->next = q1;
			qNewEnd = q1;
			q1 = q1->next;
		}
		else
		{
			qNewEnd->next = q2;
			qNewEnd = q2;
			q2 = q2->next;
		}
	}
	
	if (q1 == NULL)
	{
		qNewEnd->next = q2;
	}
	if (q2 == NULL)
	{
		qNewEnd->next = q1;
	}
	return qNew;
}

int IsCross(PNode pHead1, PNode pHead2)
{
	PNode pHead1EndN = NULL;
	PNode pHead2EndN = NULL;

	if (pHead1 == NULL || pHead2 == NULL)
	{
		return 0;
	}

	pHead1EndN = LastNode(pHead1);
	pHead2EndN = LastNode(pHead2);

	if (pHead1EndN == pHead2EndN)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

PNode GetCrossNode(PNode pHead1, PNode pHead2)
{
	int twoListOfSub = 0;
	PNode p1 = pHead1;
	PNode p2 = pHead2;

	if (!IsCross(pHead1, pHead2))
	{
		return NULL;
	}

	twoListOfSub = Size(pHead1) - Size(pHead2);
	if (twoListOfSub >= 0)
	{
		while (twoListOfSub--)
		{
			p1 = p1->next;
		}
		while (p1 != p2)
		{
			p1 = p1->next;
			p2 = p2->next;
		}
		return p1;
	}
	else
	{
		twoListOfSub = 0 - twoListOfSub;
		while (--twoListOfSub)
		{
			p2 = p2->next;
		}
		while (p1 != p2)
		{
			p1 = p1->next;
			p2 = p2->next;
		}
		return p1;
	}

}

PNode HasCircle(PNode pHead)
{
	assert(pHead);
	PNode pFast = pHead;
	PNode pSlow = pHead;

	while (pFast && pFast->next)
	{
		pFast = pFast->next->next;
		pSlow = pSlow->next;
		if (pFast == pSlow)
		{
			return pFast;
		}
	}
	return NULL;
}

int GetCirclrLen(PNode pMeetNode)
{
	PNode pPre = pMeetNode->next;
	int count = 1;

	if (NULL == pMeetNode)
	{
		return 0;
	}
	while (pPre != pMeetNode)
	{
		pPre = pPre->next;
		count++;
	}
	return count;
}

PNode GetEnterNode(PNode pHead, PNode pMeetNode)
{
	assert(pHead);
	PNode pHOne = pHead;
	PNode pMTwo = pMeetNode;

	if (NULL == pMeetNode)
	{
		return NULL;
	}
	
	while (pHOne != pMTwo)
	{
		pHOne = pHOne->next;
		pMTwo = pMTwo->next;
	}
	return pHOne;
}

int IsCrossWithCircle(PNode pHead1, PNode pHead2)
{
	PNode pMeet1 = NULL;
	PNode pMeet2 = NULL;

	if (pHead1 == NULL || pHead2 == NULL)
	{
		return 0;
	}
	pMeet1 = HasCircle(pHead1);
	pMeet2 = HasCircle(pHead2);
	
	if (pMeet1 && pMeet2)
	{
		PNode pTmp1 = pMeet1;
		if (pMeet1 == pMeet2)
		{
			return 2;
		}
		while (pMeet1->next != pTmp1)
		{
			pMeet1 = pMeet1->next;
			if (pMeet1 == pMeet2)
			{
				return 2;
			}
		}
		return 0;
	}
	if (pMeet1 == NULL && pMeet2 == NULL)
	{
		return IsCross(pHead1, pHead2);
	}

	return 0;
}

void UnionSet(Node* l1, Node* l2)
{
	assert(l1 && l2);

	PNode pL1 = l1;
	PNode pL2 = l2;

	while (pL1 != NULL && pL2 != NULL)
	{
		if (pL1->data < pL2->data)
		{
			pL1 = pL1->next;
		}
		else if(pL1->data > pL2->data)
		{
			pL2 = pL2->next;
		}
		else
		{
			printf("%d ", pL1->data);
			while (pL1->next && pL1->data == pL1->next->data)
			{
				pL1 = pL1->next;
			}
			while (pL2->next && pL2->data == pL2->next->data)
			{
				pL2 = pL2->next;
			}
			pL1 = pL1->next;
			pL2 = pL2->next;
		}
	}
}

void OddEven(PNode *pHead)
{
	assert(pHead);

	int count = 0;
	PNode pOdd = NULL;
	PNode pEven = NULL;
	PNode pPre = (*pHead)->next;

	if ((*pHead)->next == NULL)
	{
		return;
	}
	
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值