1. 从尾到头打印单链表
//时间复杂度O(N*N),空间复杂度O(1)
//非递归
void SListPrintTailToHead(SListNode* pHead)
{
SListNode* tail = NULL;
while (tail != pHead)//非空
{
SListNode* cur = pHead;
while (cur->_next != tail)
{
cur = cur->_next;
}
printf("%d ", cur->_data);
tail = cur;
}
printf("\n");
}
//时间复杂度O(N),空间复杂度O(1)
//递归
void SListPrintTailToHeadR(SListNode* pHead)//递归
{
if (pHead == NULL)
return;
SListPrintTailToHeadR(pHead->_next);
printf("%d ", pHead->_data);
}
void TestSListPrintTailToHead()
{
SListNode* list = NULL;
SListPushFront(&list, 4);
SListPushFront(&list, 3);
SListPushFront(&list, 2);
SListPushFront(&list, 1);
SListPrint(list);
//SListPrintTailToHead(list);
SListPrintTailToHeadR(list);
printf("\n");
}
2. 删除一个无头单链表的非尾节点(不能遍历链表)
void DelNonTailNode(SListNode* pHead, SListNode* pos)
{
//替换法
SListNode* next = NULL;
assert(pos&&pos->_next);
next = pos->_next;
pos->_data = next->_data;
pos->_next = next->_next;
free(next);
}
void TestDelNonTailNode()
{
SListNode* list = NULL;
SListNode* pos = NULL;
SListPushFront(&list, 4);
SListPushFront(&list, 3);
SListPushFront(&list, 2);
SListPushFront(&list, 1);
SListPrint(list);
pos = SListFind(list,3);
DelNonTailNode(list, pos);
SListPrint(list);
}
3. 在无头单链表的一个节点前插入一个节点(不能遍历链表)
void InsertFrontNode(SListNode* pos,DataType x)
{
//替换法插入
SListNode* next = NULL;
SListNode* newNode = NULL;
assert(pos);
next = pos->_next;
newNode = BuySListNode(pos->_data);
pos->_next = newNode;
newNode->_next = next;
pos->_data = x;
}
void TestInsertFrontNode()
{
SListNode* list = NULL;
SListNode* pos = NULL;
SListPushFront(&list, 4);
SListPushFront(&list, 3);
SListPushFront(&list, 2);
SListPushFront(&list, 1);
SListPrint(list);
pos = SListFind(list, 3);
InsertFrontNode(pos,6);
SListPrint(list);
}
4.单链表实现约瑟夫环(JosephCircle)
SListNode* JosephCircle(SListNode* pHead, int k)
{
SListNode* cur = pHead;
SListNode* next = NULL;
while (cur->_next != cur)//循环继续条件
{
int count = k;
while (--count)
{
cur = cur->_next;
}
//替换法
next = cur->_next;
cur->_data = next->_data;
cur->_next = next->_next;
free(next);
}
return cur;
}
void TestJosephCircle()
{
SListNode* list = NULL;
SListNode* tail = NULL;
SListPushBack(&list, 1);
SListPushBack(&list, 2);
SListPushBack(&list, 3);
SListPushBack(&list, 4);
SListPrint(list);
tail = SListFind(list, 4);
tail->_next = list;
printf("最后的幸存者是:%d\n",JosephCircle(list,3)->_data);
}
5.逆置/反转单链表
void Reverselist(SListNode** ppList)
{
SListNode* n1 = NULL;
SListNode* n2 = NULL;
SListNode* n3 = NULL;
if (*ppList==NULL || (*ppList)->_next == NULL)
return;
n1 = *ppList;
n2 = n1->_next;
n3 = n2->_next;
//逆置
n1->_next = NULL;
while (n2)
{
n2->_next = n1;
n1 = n2;
n2 = n3;
if (n3!=NULL)
n3 = n3->_next;
}
*ppList = n1;
}
//创建新节点
SListNode* Reverselist1(SListNode* list)
{
SListNode* cur = list;
SListNode* newList = NULL;
while (cur)
{
SListNode* next = cur->_next;
cur->_next = newList;
newList = cur;
cur = next ;
}
return newList;
}
void TestReverselist()
{
SListNode* list = NULL;
SListNode* newList = NULL;
SListPushBack(&list, 1);
SListPushBack(&list, 2);
SListPushBack(&list, 3);
SListPushBack(&list, 4);
SListPrint(list);
//Reverselist(&list);
newList = Reverselist1(list);
SListPrint(newList);
}
6.单链表排序(冒泡排序&快速排序)
//冒泡排序
void SListBubbleSort(SListNode* list)
{
SListNode* tail = NULL;
while (tail!=list)
{
SListNode* cur = list;
SListNode* next = cur->_next;
int exchange = 0;//判断是否进行交换,如果已经有序,直接退出
while (next != tail)
{
if (cur->_data > next->_data)
{
DataType tmp = cur->_data;
cur->_data = next->_data;
next->_data = tmp;
exchange = 1;
}
cur = cur->_next;
next = next->_next;
}
if (exchange = 0)
{
break;
}
tail = cur;//打印结点
}
}
void TestSListBubbleSort()
{
SListNode* list = NULL;
SListPushBack(&list, 10);
SListPushBack(&list, 22);
SListPushBack(&list, 3);
SListPushBack(&list, 40);
SListPushBack(&list, 5);
SListBubbleSort(list);
SListPrint(list);
}
7.合并两个有序链表,合并后依然有序
//升序
SListNode* SListMerge(SListNode* list1, SListNode* list2)
{
//尾插
SListNode* list = NULL;
SListNode* tail = NULL;
//去较小的一个节点做开头
if (list1->_data < list2->_data)
{
tail = list = list1;
list1 = list1->_next;
}
else
{
tail = list = list2;
list1 = list2->_next;
}
//尾插
while (list1&&list2)
{
if (list1->_data < list2->_data)
{
tail->_next = list1;
list1 = list1->_next;
}
else
{
tail->_next = list2;
list2 = list2->_next;
}
tail = tail->_next;
}
if (list1)
tail->_next = list1;
if (list2)
tail->_next = list2;
return list;
}
void TestSListMerge()
{
SListNode* list1 = NULL;
SListNode* list2 = NULL;
SListNode* list = NULL;
SListPushBack(&list1, 1);
SListPushBack(&list1, 3);
SListPushBack(&list1, 3);
SListPushBack(&list1, 5);
SListPushBack(&list1, 9);
SListPrint(list1);
SListPushBack(&list2, 2);
SListPushBack(&list2, 3);
SListPushBack(&list2, 4);
SListPushBack(&list2, 6);
SListPushBack(&list2, 8);
SListPrint(list2);
list = SListMerge(list1, list2);
SListPrint(list);
}
8.查找单链表的中间节点,要求只能遍历一次链表
//定义两个指针,slow,fastslow一次走一格,fast一次走两格当fast走到尾时,slow位于中间节点
SListNode* FindMidNode(SListNode* list)
{
SListNode* fast = NULL;
SListNode* slow = NULL;
fast = slow = list;
while (fast&&fast->_next)
{
slow = slow->_next;
fast = fast->_next->_next;
}
return slow;
}
void TestFindMidNode()
{
SListNode* list = NULL;
SListNode* mid = NULL;
SListPushBack(&list, 1);
SListPushBack(&list, 2);
SListPushBack(&list, 3);
SListPushBack(&list, 4);
SListPushBack(&list, 5);
SListPrint(list);
mid = FindMidNode(list);
printf("中间节点是:%d\n", mid->_data);
}
9.查找单链表的倒数第k个节点,要求只能遍历一次链表
SListNode* FindTailKNode(SListNode* list, size_t k)
{
SListNode* fast = NULL;
SListNode* slow = NULL;
fast = list;
slow = list;
while (k--)
{
if (fast==NULL)//判空
return NULL;
fast = fast->_next;
}
while (fast)
{
slow = slow->_next;
fast = fast->_next;
}
return slow;
}
10.删除链表的倒数第K个结点
void DelTailKNode(SListNode* list)
{
SListNode* Del = NULL;
SListNode* prev = NULL;
SListNode* next = NULL;
Del = FindTailKNode(list, 2);
prev = list;
while (prev->_next != Del)
{
prev = prev->_next;
}
next = prev->_next;
prev->_next = Del->_next;
Del->_data = next->_data;
free(Del);
}
void TestFindTailKNode()
{
SListNode* list = NULL;
SListNode* kNode = NULL;
SListNode* Del = NULL;
SListPushBack(&list, 1);
SListPushBack(&list, 2);
SListPushBack(&list, 3);
SListPushBack(&list, 4);
SListPushBack(&list, 5);
SListPrint(list);
DelTailKNode(list);
SListPrint(list);
//kNode = FindTailKNode(list, 2);
//printf("倒数第k个节点: %d\n", kNode->_data);
}
11.判断单链表是否带环?
若带环,求环的长度?求环的入口点?并计算每个算法的时间复杂度&空间复杂度
SListNode* IsCycle(SListNode* list)
{
SListNode* fast = NULL;
SListNode* slow = NULL;
fast = list;
slow = list;
while (fast&&fast->_next)
{
slow = slow->_next;
fast = fast->_next->_next;
if (slow == fast)
return slow;
}
return NULL;
}
int GetCycleLen(SListNode* meet)
{
int n = 1;
SListNode* cur = meet;
while (cur->_next != meet)
{
n++;
cur = cur->_next;
}
return n;
}
SListNode* GetEntryNode(SListNode* list, SListNode* meet)
{
while (list != meet)
{
list = list->_next;
meet = meet->_next;
}
return list;
}
void TestIsCycle()
{
SListNode* list = NULL;
SListNode* meet = NULL;
SListNode* tail = NULL;
SListNode* entry = NULL;
SListPushBack(&list, 1);
SListPushBack(&list, 2);
SListPushBack(&list, 3);
SListPushBack(&list, 4);
SListPushBack(&list, 5);
SListPushBack(&list, 6);
printf("IsCycle? %d\n",IsCycle(list));
//构造环
tail = SListFind(list, 6);
entry = SListFind(list, 3);
tail->_next = entry;
meet = IsCycle(list);
printf("IsCycle?:%d\n", meet->_data);
printf("Cycle Len?:%d\n", GetCycleLen(meet));
printf("Cycle Entry?:%d\n", GetEntryNode(list, meet)->_data);
}
12.判断两个链表是否相交
,若相交,求交点。(假设链表不带环)
//判断两个链表是否相交,若相交,求交点。(假设链表可能带环)
int IsCross(SListNode* list1, SListNode* list2)
{
while (list1&&list1->_next)
{
list1 = list1->_next;
}
while (list2&&list2->_next)
{
list2 = list2->_next;
}
if (list1 == list2&&list1 != NULL)
{
return 1;
}
else
return 0;
}
SListNode* GetCrossNode(SListNode* list1, SListNode* list2)
{
SListNode* longlist = NULL;
SListNode* shortlist = NULL;
SListNode* cur1 = list1;
SListNode* cur2 = list2;
int n1 = 0;
int n2 = 0;
int gap = 0;
while (cur1)
{
cur1 = cur1->_next;
n1++;
}
while (cur2)
{
cur2 = cur2->_next;
n2++;
}
longlist = list1;
shortlist = list2;
if (n1 < n2)
{
longlist = list2;
shortlist = list1;
}
gap = abs(n1 - n2);//绝对值
while (gap--)
{
longlist = longlist->_next;
}
while (shortlist != longlist)
{
shortlist = shortlist->_next;
longlist = longlist->_next;
}
return shortlist;
}
void TestCrossNode()
{
SListNode* node11, *node22;
SListNode* node1 = BuySListNode(1);
SListNode* node2 = BuySListNode(2);
SListNode* node3 = BuySListNode(3);
SListNode* node4 = BuySListNode(4);
SListNode* node5 = BuySListNode(5);
node1->_next = node2;
node2->_next = node3;
node3->_next = node4;
node4->_next = node5;
node11 = BuySListNode(11);
node22 = BuySListNode(22);
node11->_next = node22;
node22->_next = node4;
printf("Is Cross?%d\n", IsCross(node1, node11));
printf("Cross Node?%d\n", GetCrossNode(node1, node11)->_data);
}
13.求两个已排序单链表中相同的数据。
void UnionSet(SListNode* list1, SListNode* list2)
{
while (list1&&list2)
{
if (list1->_data > list2->_data)
{
list2 = list2->_next;
}
else if (list1->_data < list2->_data)
{
list1 = list1->_next;
}
else
{
printf("相同的数据:%d\n", list1->_data);
list1 = list1->_next;
list2 = list2->_next;
}
}
printf("\n");
}
void TestUnionSet()
{
SListNode* list1 = NULL;
SListNode* list2 = NULL;
SListPushBack(&list1, 1);
SListPushBack(&list1, 3);
SListPushBack(&list1, 4);
SListPushBack(&list1, 5);
SListPushBack(&list1, 6);
SListPushBack(&list2, 2);
SListPushBack(&list2, 3);
SListPushBack(&list2, 5);
SListPushBack(&list2, 7);
SListPushBack(&list2, 9);
UnionSet(list1, list2);
}
14.复杂链表的复制。
一个链表的每个节点,有一个指向next指针指向
//下一个节点,还有一个random指针指向这个链表中的一个随机节点
//或者NULL,现在要求实现复制这个链表,返回复制后的新链表。
typedef struct ComplexNode
{
int _data;
struct ComplexNode* _next;
struct ComplexNode* _random;
}ComplexNode;
ComplexNode* BuyComplexNode(int x)
{
ComplexNode* node = (ComplexNode*)malloc(sizeof(ComplexNode));
assert(node);
node->_data = x;
node->_next = NULL;
node->_random = NULL;
return node;
}
//理解难度较高**
ComplexNode* CopyComplexList(ComplexNode* list)
{
//拷贝复杂链表,连接在原链表的后面
ComplexNode* cur = list;
ComplexNode* copylist = NULL;
ComplexNode* tail = NULL;
while (cur)
{
ComplexNode* next = cur->_next;
ComplexNode*newNode = BuyComplexNode(cur->_data);
cur->_next = newNode;
newNode->_next = next;
cur = next;
}
//置random
cur = list;
while (cur)
{
ComplexNode* next = cur->_next;
if (cur->_random)
next->_random = cur->_random->_next;
cur = cur->_next->_next;
}
//拆解链表
cur = list;
while (cur)
{
ComplexNode* next = cur->_next;
ComplexNode* nextNext = next->_next;
cur->_next = nextNext;
if (copylist == NULL)
{
copylist = tail = next;
}
else
{
tail->_next = next;
tail = next;
}
cur = nextNext;
}
return copylist;
}
void PrintComplex(ComplexNode* list)
{
while (list)
{
ComplexNode* random = list->_random;
int data = random ? random->_data : 0;
printf("%d:%d->", list->_data, data);
list = list->_next;
}
printf("\n");
}
void TestCopyComplexList()
{
ComplexNode*copylist = NULL;
ComplexNode* n1 = BuyComplexNode(1);
ComplexNode* n2 = BuyComplexNode(2);
ComplexNode* n3 = BuyComplexNode(3);
ComplexNode* n4 = BuyComplexNode(4);
n1->_next = n2;
n2->_next = n3;
n3->_next = n4;
n4->_next = NULL;
n1->_random = n4;
n2->_random = n1;
n3->_random = NULL;
n4->_random = n4;
copylist = CopyComplexList(n1);
PrintComplex(n1);
PrintComplex(copylist);
}