问题集锦
从尾到头打印单链表
删除一个无头单链表的非尾节点(不能遍历链表)
在无头单链表的一个节点前插入一个节点(不能遍历链表)
单链表实现约瑟夫环(JosephCircle)
逆置/反转单链表
单链表排序(冒泡排序&快速排序)
合并两个有序链表,合并后依然有序
查找单链表的中间节点,要求只能遍历一次链表
查找单链表的倒数第k个节点,要求只能遍历一次链表
删除链表的倒数第K个结点
判断单链表是否带环?若带环,求环的长度?求环的入口点?并计算
每个算法的时间复杂度&空间复杂度。
判断两个链表是否相交,若相交,求交点。(假设链表不带环)
判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
复杂链表的复制。一个链表的每个节点,有一个指向next指针指向
下一个节点,还有一个random指针指向这个链表中的一个随机节点
或者NULL,现在要求实现复制这个链表,返回复制后的新链表。
求两个已排序单链表中相同的数据。
头文件代码
#ifndef __CODE_H__
#define __CODE_H__
#include
#include
typedef int DataType;
typedef struct SListNode
{
DataType _a;
struct SListNode* _next;
}SListNode;
void SListPushBack(SListNode* pHead, DataType x);
void SListPrint(SListNode* pHead);
void SLitsPrintTailToHead(SListNode* pHead);
void SListPrintTailToHeadR(SListNode* pHead);
void SListDelNonTailNode(SListNode* pos);
void SListInsertFrontNode(SListNode* pos, DataType x);
SListNode* SListJosephCircle(SListNode* pHead, int k);
SListNode* SListReverse(SListNode* list);
// 升序
void SListBubbleSort(SListNode* list);
SListNode* SListMerge(SListNode* list1, SListNode* list2);
SListNode* SListFindMidNode(SListNode* list);
SListNode* SListFindTailKNode(SListNode* list, size_t k);
// 链表带环问题
SListNode* SListIsCycle(SListNode* list);
int SListCycleLen(SListNode* meetNode);
SListNode* SListEntryNode(SListNode* list, SListNode* meetNode);
// 链表相交问题
SListNode* SListIsCrossNode(SListNode* list1, SListNode* list2);
SListNode* SListCrossNode(SListNode* list1, SListNode* list2);
// 复杂链表复制
typedef struct ComplexListNode
{
int _data;
struct ComplexListNode* _next;
struct ComplexListNode* _random;
}ComplexListNode;
ComplexListNode* CopyComplexList(ComplexListNode* list);
void UnionSet(SListNode* l1, SListNode* l2);
#endif//__CODE_H__
函数功能实现代码
#include <stdio.h>
#include "code.h"
void SListPushBack(SListNode* pHead, DataType x)
{
assert(pHead);
while (pHead->_next != NULL)
{
pHead = pHead->_next;
}
pHead->_next = (SListNode*)malloc(sizeof(SListNode));
pHead = pHead->_next;
pHead->_a = x;
pHead->_next = NULL;
}
void SListPrint(SListNode* pHead)
{
//assert(pHead);
while (pHead != NULL)
{
printf("%d ", pHead->_a);
pHead = pHead->_next;
}
printf("\n");
}
void SLitsPrintTailToHead(SListNode* pHead)
{
assert(pHead);
SListNode* start = pHead;
if (start->_next == NULL)
{
printf("%d ", start->_a);
return;
}
else
{
SLitsPrintTailToHead(start->_next);
printf("%d ", start->_a);
}
}
void SListPrintTailToHeadR(SListNode* pHead)
{
assert(pHead);
SListNode* p1 = pHead;
SListNode* p2 = p1->_next;
}
void SListDelNonTailNode(SListNode* pos)
{
assert(pos);
if (NULL == pos->_next)
{
return;
}
else
{
SListNode* pNode=pos->_next;
pos->_a = pos->_next->_a;
pos->_next = pNode->_next;
free(pNode);
pNode = NULL;
}
}
void SListInsertFrontNode(SListNode* pos, DataType x)
{
assert(pos);
SListNode* pNode=(SListNode*)malloc(sizeof(SListNode));
pNode->_a = pos->_a;
pNode->_next = pos->_next;
pos->_next = pNode;
pos->_a = x;
}
SListNode* SListJosephCircle(SListNode* pHead, int k)
{
assert(pHead);
assert(k > 0);
SListNode* p1 = pHead;
SListNode* p2 = pHead;
while (p2 != p2->_next)
{
for (int i = 0; i < k-1; i++)
{
p1 = p2;
p2 = p2->_next;
}
p1->_next = p2->_next;
free(p2);
p2 = p1->_next;
}
return p2;
}
SListNode* SListReverse(SListNode* list)
{
assert(list);
assert(list->_next);
SListNode* p1 = list;
SListNode* p2 = p1->_next;
SListNode* p3 = p2->_next;
p1->_next = NULL;
while (p2 != NULL)
{
p2->_next = p1;
p1 = p2;
p2 = p3;
if (p3 != NULL)
{
p3 = p3->_next;
}
}
return p1;
}
SListNode* SListFindMidNode(SListNode* list)
{
assert(list);
SListNode* pfast = list;
SListNode* pslow = list;
while (pfast->_next != NULL && pfast!=NULL)
{
pfast = pfast->_next->_next;
pslow = pslow->_next;
}
return pslow;
}
SListNode* SListFindTailKNode(SListNode* list, size_t k) //找倒数第K个结点
{
assert(list);
SListNode* pfast = list;
SListNode* pslow = list;
for (size_t i = 0; i < k - 1; i++)
{
pfast = pfast->_next;
}
while (pfast->_next != NULL)
{
pfast = pfast->_next;
pslow = pslow->_next;
}
return pslow;
}
SListNode* SListIsCycle(SListNode* list) //判断是否带环并找相遇结点
{
assert(list);
SListNode* pfast = list;
SListNode* pslow = list;
while (pfast->_next != NULL && pfast != NULL)
{
pfast = pfast->_next->_next;
pslow = pslow->_next;
if (pfast == pslow)
{
return pslow;
}
}
return NULL;
}
int SListCycleLen(SListNode* meetNode) //求环的长度
{
assert(meetNode);
int i = 1;
SListNode* cur = meetNode->_next;
while (cur != meetNode)
{
cur = cur->_next;
i++;
}
return i;
}
//2l+2x=l+nq+x
//l = nq - x
SListNode* SListEntryNode(SListNode* list, SListNode* meetNode) //求入口点
{
assert(list);
assert(meetNode);
while (list != meetNode)
{
list = list->_next;
meetNode = meetNode->_next;
}
return list;
}
SListNode* SListIsCrossNode(SListNode* list1, SListNode* list2) //假设链表不带环
{
assert(list1);
assert(list2);
SListNode* tail1 = list1;
SListNode* tail2 = list2;
SListNode* meetNode = NULL;
if (list1 == list2)
{
return NULL;
}
while (tail1->_next != NULL)
{
tail1 = tail1->_next;
}
tail1->_next = list1;
meetNode = SListIsCycle(list2);
tail2 = SListEntryNode(list2, meetNode);
return tail2;
}
SListNode* SListCrossNode(SListNode* list1, SListNode* list2) //假设链表带环,则都带环
{
assert(list1);
assert(list2);
SListNode* tail1 = list1;
SListNode* tail2 = list2;
SListNode* start = list2;
int temp = 0;
tail1 = SListEntryNode(list1, SListIsCycle(list1));
tail2 = SListEntryNode(list2, SListIsCycle(list2));
while (tail1 != start)
{
start = start->_next;
if (start == tail2)
{
temp++;
}
if (temp == 2)
{
return NULL;
}
}
if (tail1 != tail2)
{
return tail1;
}
tail1->_next = list1;
tail2 = SListEntryNode(list2, SListIsCycle(list2));
return tail2;
}
ComplexListNode* CopyComplexNode(ComplexListNode* list) //复制结点
{
assert(list);
ComplexListNode* tail = (ComplexListNode*)malloc(sizeof(ComplexListNode));
tail->_data = list->_data;
tail->_next = list->_next;
tail->_random = list->_random;
return tail;
}
void ChangeComplexList(ComplexListNode* list) //把每个复制的结点放在相同结点后面组成新的链表
{
assert(list);
ComplexListNode* temp = NULL;
ComplexListNode* tail1 = list;
ComplexListNode* tail2 = tail1->_next;
while (tail1 != NULL)
{
temp = CopyComplexNode(tail1);
tail1->_next = temp;
temp->_next = tail2;
tail1 = tail2;
if (tail2 != NULL)
{
tail2 = tail2->_next;
}
}
}
ComplexListNode* CopyComplexList(ComplexListNode* list)
{
assert(list);
ComplexListNode* tail = NULL;
ComplexListNode* list1 = list;
ComplexListNode* list2 = NULL;
ComplexListNode* temp = NULL;
ChangeComplexList(list1);
list2 = list1->_next;
temp = list2;
while (list2 != NULL) //让复制的结点随机指针指向对应复制的结点
{
if (list2->_random != NULL)
{
list2->_random = list2->_random->_next;
}
list2 = list2->_next;
}
list2 = temp;
while (list2->_next != NULL) //分开两个链表
{
tail = list2->_next;
list1->_next = tail;
list2->_next = tail->_next;
list1 = tail;
list2 = tail->_next;
}
list1->_next = NULL; //最后只要断开最后两个结点就可以了
return temp;
}
void UnionSet(SListNode* list1, SListNode* list2)
{
assert(list1);
assert(list2);
while (list1 != NULL && list2 != NULL)
{
if (list1->_a == list2->_a)
{
printf("%d ", list1->_a);
list1 = list1->_next;
list2 = list2->_next;
}
else if (list1->_a > list2->_a)
{
list2 = list2->_next;
}
else
{
list1 = list1->_next;
}
}
}
测试用例
#include <stdio.h>
#include "code.h"
SListNode* pHead = NULL;
SListNode* pHead2 = NULL;
ComplexListNode* pNode = NULL;
void test(void)
{
pHead = (SListNode*)malloc(sizeof(SListNode));
pHead->_a = 0;
pHead->_next = NULL;
SListPushBack(pHead, 1);
SListPushBack(pHead, 2);
SListPushBack(pHead, 3);
SListPushBack(pHead, 4);
SListPushBack(pHead, 5);
SListPushBack(pHead, 6);
}
void test1(void)
{
SListNode* pos = pHead->_next->_next;
SListPrint(pHead);
SLitsPrintTailToHead(pHead);
printf("\n");
SListDelNonTailNode(pos);
SListPrint(pHead);
SListInsertFrontNode(pos, 0);
SListPrint(pHead);
}
void test2(void)
{
SListNode* start = pHead;
while (start->_next != NULL)
{
start = start->_next;
}
start->_next = pHead;
start=SListJosephCircle(pHead, 3);
printf("%d\n", start->_a);
}
void test3(void)
{
pHead=SListReverse(pHead);
SListPrint(pHead);
}
void test5(void)
{
SListNode* start = SListFindMidNode(pHead);
printf("%d\n", start->_a);
start=SListFindTailKNode(pHead, 3);
printf("%d\n", start->_a);
}
void test6(void)
{
int size = 0;
SListNode* tail = pHead;
SListNode* meetNode = NULL;
SListPushBack(pHead, 7);
SListPushBack(pHead, 8);
SListPushBack(pHead, 9);
SListPushBack(pHead, 10);
meetNode = SListIsCycle(pHead);
if (meetNode == NULL)
printf("不带环\n");
while (tail->_next != NULL)
{
tail = tail->_next;
}
tail->_next = pHead->_next->_next->_next;
meetNode = SListIsCycle(pHead);
size = SListCycleLen(meetNode);
tail = SListEntryNode(pHead, meetNode);
printf("%d %d\n", size, tail->_a);
}
void test7(void)
{
SListNode* tail = pHead;
SListNode* temp = NULL;
pHead2 = (SListNode*)malloc(sizeof(SListNode));
pHead2->_a = 10;
pHead2->_next = NULL;
SListPushBack(pHead, 7);
SListPushBack(pHead, 8);
SListPushBack(pHead, 9);
SListPushBack(pHead, 10);
SListPushBack(pHead2, 11);
SListPushBack(pHead2, 12);
SListPushBack(pHead2, 13);
pHead2->_next->_next->_next->_next = pHead->_next->_next;
while (tail->_next != NULL)
{
tail = tail->_next;
}
tail->_next = pHead->_next->_next->_next;
temp = SListCrossNode(pHead, pHead2);
if (temp != NULL)
{
printf("%d\n", temp->_a);
}
}
void test8(void)
{
pNode = (ComplexListNode*)malloc(sizeof(ComplexListNode));
pNode->_data = 0;
ComplexListNode* pNode1 = (ComplexListNode*)malloc(sizeof(ComplexListNode));
pNode1->_data = 1;
ComplexListNode* pNode2 = (ComplexListNode*)malloc(sizeof(ComplexListNode));
pNode2->_data = 2;
ComplexListNode* pNode3 = (ComplexListNode*)malloc(sizeof(ComplexListNode));
pNode3->_data = 3;
ComplexListNode* pNode4 = (ComplexListNode*)malloc(sizeof(ComplexListNode));
pNode4->_data = 4;
ComplexListNode* pNewNode = NULL;
pNode->_next = pNode1;
pNode->_random = pNode2;
pNode1->_next = pNode2;
pNode1->_random = pNode4;
pNode2->_next = pNode3;
pNode2->_random = NULL;
pNode3->_next = pNode4;
pNode3->_random = pNode1;
pNode4->_next = NULL;
pNode4->_random = pNode2;
pNewNode = CopyComplexList(pNode);
while (pNode != NULL)
{
if (pNode->_random != NULL)
{
printf("%d ", pNode->_random->_data);
}
printf("%d\n", pNode->_data);
pNode = pNode->_next;
}
while (pNewNode != NULL)
{
if (pNewNode->_random != NULL)
{
printf("%d ", pNewNode->_random->_data);
}
printf("%d\n", pNewNode->_data);
pNewNode = pNewNode->_next;
}
}
void test9(void)
{
pHead2 = (SListNode*)malloc(sizeof(SListNode));
pHead2->_a = 1;
pHead2->_next = NULL;
SListPushBack(pHead2, 3);
SListPushBack(pHead2, 5);
SListPushBack(pHead2, 7);
UnionSet(pHead, pHead2);
}
int main()
{
//test();
//test1();
//test2();
//test3();
//test5();
//test6();
//test7();
//test8();
//test9();
return 0;
}