#pragma once
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
typedef int DataType;
typedef struct Node
{
struct Node* _pNext;
DataType _data;
}Node, *PNode;
链表部分的面试题认真去完成,非常重要,非常重要,非常重要!!!
// 从尾到头打印单链表
//利用递归的方法来实现
void PrintListFromTail2Head(PNode* pHead)
{
PNode pCur = pHead;
assert(pHead)
if (pHead != NULL)
{
if (pHead->pNext != NULL)
{
printListFormTail2Head(pHead->pNext);
}
}
printf("%d\t", pHead->data);
}
// 删除无头单链表的非尾结点,要求:不能遍历链表
void DeleteNotTailNode(PNode pos)
{
PNode pCur = NULL;
if (pos)
{
pCur = pos->_pNext;
pos->_data = pCur->_data;
pos->_pNext = pCur->_pNext;
free(pCur);
}
}
// 在无头单链表pos位置前插入值为结点data的结点
void InsertPosFront(PNode pos, DataType data)
{
PNode pNew = NULL;
if (NULL != pos)
{
pNew = BuySListPNode(pos->_data);//新建节点
pos -> _data = data;//将要插入节点的值给pos
pNew->_pNext = pos->_pNext;
pos->_pNext = pNew;
}
}
// 用单链表模拟实现约瑟夫环
void JosephCircle(PNode* pHead, const int M)
{
PNode car = NULL;
PNode Del = NULL;
int num = M;
assert(pHead);
car = (*pHead);
if (M != 1)
{
while (car->_pNext != car)
{
num = M;
while (--num > 1)
{
car = car->_pNext;
}
Del = car->_pNext;
car->_pNext = Del->_pNext;
car = car->_pNext;
free(Del);
}
car->_pNext = NULL;
(*pHead) = car;
}
else if (M == 1)
{
PNode pre = (*pHead);
while (car->_pNext != pre)
{
Del = car;
car = Del->_pNext;
free(Del);
}
car->_pNext = NULL;
}
(*pHead) = car;
}
// 使用冒泡排序方法对单链表进行排序
void BubbleSort(PNode pHead)
{
pNode cur = NULL;
pNode teil = NULL;
assert(pList);
cur = pList->pHead;
while (cur != teil)
{
while (cur->next != teil)
{
if (cur->data > cur->next->data)
{
DataType tmp = cur->data;
cur->data = cur->next->data;
cur->next->data = tmp;
}
cur = cur->next;
}
teil = cur;
cur = pList->pHead;
}
return;
}
// 单链表的逆置--三个指针
void ReverseSList(PNode* pHead)
{
PNode pCur = NULL, pNext = NULL, pPre = NULL;
assert(pHead);
if (NULL == *pHead)
return;
pCur = *pHead;
while (pCur)
{
pNext = pCur->_pNext;
pCur->_pNext = pPre;
pPre = pCur;
pCur = pNext;
}
*pHead = pPre;
}
// 单链表的逆置--头插法
PNode ReverseSListOP(PNode pHead)
{
PNode s; //创建新链表
PNode pCur = NULL;
if (NULL == pHead || NULL == pHead->_pNext)
return NULL;
pCur = pHead;
SListInit(&s);
while (pCur)
{
SListPushFront(&s, pCur->_data);
pCur = pCur->_pNext;
}
return s;
}
// 合并两个有序链表,合并之后依然有序
PNode MergeSList(PNode pHead1, PNode pHead2)
{
PNode pCur1 = NULL, pCur2 = NULL;//pNewNode=NULL;
assert(pHead1);
assert(pHead2);
pCur1 = pHead1;
pCur2 = pHead2;
//pNewNode=pHead1;
while (pCur1)
{
if (NULL != pCur2) //链表2不为空
{
if (pCur2->_data <= pCur1->_data)
{
InsertPosFront(pCur1, pCur2->_data);
pCur2 = pCur2->_pNext;
}
else
pCur1 = pCur1->_pNext;
}
else //链表2为空
break;
}
if (NULL == pCur1 && pCur2 != NULL)
{
InsertPosFront(pCur1, pCur2->_data);
pCur2 = pCur2->_pNext;
}
return pHead1;
}
// 查找链表的中间结点,要求只能遍历一次链表
PNode FindMiddleNode(PNode pHead)
{
PNode pFast = NULL, pSlow = NULL;
if (NULL == pHead)
return NULL;
pFast = pHead;
pSlow = pHead;
while (pFast && pFast->_pNext)
{
pFast = pFast->_pNext->_pNext;
pSlow = pSlow->_pNext;
}
return pSlow;
}
// 查找链表的倒数第K个结点,要求只能遍历链表一次
PNode FindLastKNode(PNode pHead, int K)
{
PNode pFast = NULL, pSlow = NULL;
if (NULL == pHead)
return NULL;
pFast = pHead;
pSlow = pHead;
while (--K)
pFast = pFast->_pNext; //此时pFast指向的k个节点
while (pFast && pFast->_pNext)
{
pFast = pFast->_pNext; //快慢一起走
pSlow = pSlow->_pNext;
}
return pSlow;
}
// 删除链表的倒数第K个结点,要求只能遍历链表一次
PNode DeleteLastKNode(PNode pHead, int K)
{
PNode pTail1 = pHead1, pTail2 = pHead2;
if (NULL == pHead1 || NULL == pHead2)
return 0;
while (pTail1->_pNext)
pTail1 = pTail1->_pNext;
while (pTail2->_pNext)
pTail2 = pTail2->_pNext;
if (pTail1 == pTail2)
return 1;
else
return 0;
}
// 判断单链表是否相交?链表不带环
int IsCrossWithoutCircle(PNode pHead1, PNode pHead2)
{
PNode pMeet1 = NULL, pMeet2 = NULL, pCur = NULL;
if (NULL == pHead1 || NULL == pHead2)
return 0;
//是否带环
pMeet1 = IsCircle(pHead1);
pMeet2 = IsCircle(pHead2);
pCur = pMeet1;
if (pMeet1 && pMeet2) //两个链表都带环(交点在:①环外(一个交点),②环内(即两个链表的入环节点,两个交点))
{
do
{
if (pCur == pMeet2)
return 1;
pCur = pCur->_pNext;
} while (pCur != pMeet1);
}
else if (IsCrossWithoutCircle(pHead1, pHead2)) // 两个链表都不带环
return 1;
return 0;
}
// 求不带环单链表相交交点
PNode GetCrossNode(PNode pHead1, PNode pHead2)
{
PNode pCur1 = pHead1, pCur2 = pHead2;
int size1 = 0, size2 = 0, gap = 0;
while (pCur1)
{
size1++;
pCur1 = pCur1->_pNext;
}
while (pCur2)
{
size2++;
pCur2 = pCur2->_pNext;
}
gap = size1 - size2;
pCur1 = pHead1, pCur2 = pHead2;
if (gap >= 0)
{
while (gap--) //size1>=size2,pCur1先走gap步
pCur1 = pCur1->_pNext;
while (pCur1 != pCur2)
{
pCur1 = pCur1->_pNext;
pCur2 = pCur2->_pNext;
}
return pCur1;
}
else
{
while (gap--) //size1<size2,pCur2先走gap步
pCur2 = pCur2->_pNext;
while (pCur1 != pCur2)
{
pCur1 = pCur1->_pNext;
pCur2 = pCur2->_pNext;
}
return pCur1;
}
}
// 判断链表是否带环
PNode IsCircle(PNode pHead)
{
PNode pFast = pHead, pSlow = pHead;
if (NULL == pHead)
return NULL;
while (pFast && pFast->_pNext)
{
pFast = pFast->_pNext->_pNext;
pSlow = pSlow->_pNext;
if (pFast == pSlow)
return pFast; //返回快慢指针相遇节点
}
return NULL;
}
// 求环的长度
int GetCircleLen(PNode pHead)
{
PNode pMeetNode = IsCircle(pHead); //将判断链表是否带环时 快慢指针的相遇节点返回
PNode pCur = pMeetNode;
int count = 1;
while (pCur->_pNext != pMeetNode)
{
count++;
pCur = pCur->_pNext;
}
return count;
}
// 求环的入口点--注意推断过程
PNode GetEnterNode(PNode pHead, PNode pMeetNode)
{
PNode pMeetNode = NULL;
if (NULL == pHead)
return NULL;
pMeetNode = IsCircle(pHead); //找到快慢指针 相遇节点
while (pHead != pMeetNode)
{
pHead = pHead->_pNext;
pMeetNode = pMeetNode->_pNext;
}
return pMeetNode;
}
// 判断链表是否带环,链表可能带环
int IsListCrossWithCircle(PNode pHead1, PNode pHead2)
{
}
// 复杂链表的复制
PCListNode CopyComplexList(PCListNode pHead)
{
PCListNode pNew;
pNew = (PCListNode)malloc(sizeof(CListNode));
if (NULL == pNew)
return NULL;
pNew->_data = data;
pNew->_pNext = NULL;
pNew->_pRandom = NULL;
return pNew;
}
总结链表和顺序表的优缺点
浙公网安备 33010602011771号