链表是面试重中之重,但题型比较死,考的是细心。这里做一个总结,给出模板实现。如果错误,请不吝指教!
1. 判断链表是否有环
2.求链表中间节点(偶数则返回前一个节点)
3.约瑟夫环问题
4. 链表逆序输出(递归)
5. 链表反转(非递归与递归)
6.两个有序单链表的合并(非递归与递归)
7.判断两个单链表是否相交
8.接题7,若相交求第一个交点
9. 删除链表某个节点
10. 求倒数第K个节点
11. 单链表排序
节点定义:
template<class T>
struct LNode
{
T value;
LNode *next;
};
1. 判断链表是否有环
template <typename T>
int IsCyclicList(LNode<T> *list)
{
LNode<T> *pSlow = list;
LNode<T> *pFast = list;
while(pFast != NULL && pFast->next != NULL)
{
pFast = pFast->next->next;
pSlow = pSlow->next;
if (pFast == pSlow)
return 1;
}
return 0;
}
2. 求单链表链表中间节点(偶数则返回前一个节点)
template <typename T>
int GetMidNode(LNode<T> *list)
{
if (NULL == list)
return NULL;
LNode<T> *pAhead = list;
LNode<T> *pBehind = list;
while(pAhead->next != NULL)
{
pAhead = pAhead->next;
if (pAhead->next != NULL)
{
pBehind = pBehind->next;
pAhead = pAhead->next;
}
}
return pBehind->value;
}
3. 约瑟夫环问题
template <typename T>
void joseph(LNode<T> *list, int m)
{
if (NULL == list)
return;
int count = m;
LNode<T> *cur = list;
while(cur->next != cur)
{
while ( count > 2) //默认当前节点报数为1,故此处取2;若当前节点报数为0,则此处取1
{
cur = cur->next;
--count;
}
LNode<T> *temp = cur->next;
cur->next = temp->next;
cur = cur->next;
delete temp;
count = m;
}
cout << cur->value << endl;
}
4. 单链表逆序输出(递归)
template <typename T>
void PrintFromLastToFirst(LNode<T> *list)
{
if (NULL == list)
return ;
PrintFromLastToFirst(list->next);
cout << list->value << " ";
}
5. 单链表反转(非递归与递归)
非递归法:
template <typename T>
LNode<T> * ReverseList_NoRecurse(LNode<T> *list)
{
if (NULL == list)
return NULL;
LNode<T> *pHead = list;
LNode<T> *pCur = pHead->next;
pHead->next = NULL;
while (pCur != NULL)
{
LNode<T> *temp = pCur->next;
pCur->next = pHead;
pHead = pCur;
pCur = temp;
}
return pHead;
}
递归法:
template <typename T>
LNode<T> *DoReverseList(LNode<T> *list, LNode<T> *&pre)
{
if (NULL == list->next)
{
pre = list;
return list;
}
LNode<T> * temp = DoReverseList(list->next, pre);
pre->next = list;
pre = list;
pre->next = NULL;
return temp;
}
template <typename T>
LNode<T> *ReverseList_Recurse(LNode<T> *list)
{
if (NULL == list || NULL == list->next )
return list;
LNode<T> *pre;
return DoReverseList(list,pre);
}
6.两个有序单链表的合并(非递归与递归)
非递归法:
template <typename T>
LNode<T> * MergeList_NoRecurse(LNode<T> *list1, LNode<T> *list2)
{
if (NULL == list1)
return list2;
if (NULL == list2)
return list1;
LNode<T> node; //附加头节点,方便处理
LNode<T> *temp = &node;
while(list1 != NULL && list2 != NULL)
{
if (list1->value < list2->value)
{
temp->next = list1;
list1 = list1->next;
}
else
{
temp->next = list2;
list2 = list2->next;
}
temp = temp->next;
}
if (NULL == list1)
temp->next = list2;
if (NULL == list2)
temp->next = list1;
return node.next;
}
递归法:
template <typename T>
LNode<T> * MergeList_Recurse(LNode<T> *list1, LNode<T> *list2)
{
if (NULL == list1)
return list2;
if (NULL == list2)
return list1;
LNode<T> *pHead = NULL;
if (list1->value < list2->value)
{
pHead = list1;
pHead->next = MergeList_Recurse(list1->next, list2);
}
else
{
pHead = list2;
pHead->next = MergeList_Recurse(list1, list2->next);
}
return pHead;
}
7.判断两个单链表是否相交
template <typename T>
int IsIntersect(LNode<T> *list1, LNode<T> *list2)
{
if (NULL == list1 || NULL == list2)
return 0;
while (list1->next != NULL)
list1 = list1->next;
while (list2->next != NULL)
list2 = list2->next;
return (list1==list2);
}
8.接题7,若相交求第一个交点
template <typename T>
LNode<T> * GetFirstIntersection(LNode<T> *list1, LNode<T> *list2)
{
if (NULL == list1 || NULL == list2)
return NULL;
LNode<T> *temp1 = list1;
LNode<T> *temp2 = list2;
int len1=0, len2=0;
while (temp1 != NULL)
{
len1++;
temp1 = temp1->next;
}
while (temp2 != NULL)
{
len2++;
temp2 = temp2->next;
}
if (len1 > len2)
{
int count = len1-len2;
while (count>0)
{
list1 = list1->next;
count--;
}
}
if (len1 < len2)
{
int count = len2-len1;
while (count>0)
{
list2 = list2->next;
count--;
}
}
while (list1->value != list2->value)
{
list1 = list1->next;
list2 = list2->next;
}
return list1;
}
9. 删除链表某个节点
template <typename T>
void DeleteNode(LNode<T> * &list, LNode<T> *pToBeDeleted)
{
if (NULL == list || NULL == pToBeDeleted)
return ;
if (list == pToBeDeleted) //删除头节点
{
list = list->next;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
else
{
if (NULL == pToBeDeleted->next ) //删除尾节点
{
LNode<T> *temp = list;
while (temp->next != pToBeDeleted)
temp = temp->next;
temp->next = NULL;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
else //删除中间节点
{
LNode<T> *temp = pToBeDeleted->next;
pToBeDeleted->value = temp->value;
pToBeDeleted->next = temp->next;
delete temp;
}
}
}
10. 求倒数第K个节点
template <typename T>
LNode<T> * FindKthToEnd(LNode<T> *list, int k)
{
if (NULL == list || k <= 0)
return NULL;
LNode<T> * pAhead = list;
LNode<T> *pBehind = list;
for (int i=0; i<k-1; i++)
{
if (pAhead->next != NULL)
pAhead = pAhead->next;
else
return NULL;
}
while (pAhead->next != NULL)
{
pAhead = pAhead->next;
pBehind = pBehind->next;
}
return pBehind;
}
11. 单链表排序
template <typename T>
LNode<T> * BubbleSort(LNode<T> *list)
{
if (NULL == list || NULL == list->next)
return NULL;
LNode<T> *pA = list;
LNode<T> *pB = list;
int tmp;
int flag = 1;
for (; pA != NULL && flag; pA = pA->next)
{
flag = 0;
for (pB = list; pB->next != NULL; pB = pB->next)
{
if (pB->value > pB->next->value)
{
tmp = pB->value;
pB->value = pB->next->value;
pB->next->value = tmp;
flag = 1;
}
}
}
return list;
}