从尾到头打印单链表
使用递归从后往前打印
在无头单链表的一个结点前插入一个结点(不能遍历链表)
单链表实现约瑟夫环(JosephCircle)
逆置单链表
方法一:
方法二:
单链表排序(冒泡排序)
类似于普通数组冒泡排序
合并两个有序链表,合并后任然有序
查找单链表的中间节点,要求只能遍历一次链表
查找单链表的倒数第K个结点,要求只能遍历一次链表
删除链表的倒数第K个结点
判断单链表是否带环?若带环求环的长度和入口
环入口:
判断两链表是否相交(假设链表不带环)
判断两链表是否相交(假设链表可能带环)
求两个已排序单链表中相同数据
复杂链表的复制。一个链表的每个结点,有一个next指针指向下一个结点,还有一个random指针指向链表的一个随机节点或者NULL,要求实现这个复杂链表的复制,返回复制后的新链表
方法一:
方法二:
具体实现代码如下:
部分代码请参照 >单链表基础操作<
①linklist.h
#pragma once
#include <stddef.h>
#include <stdio.h>
typedef char LinkType;
typedef struct LinkNode{
LinkType data;
struct LinkNode* next;
}LinkNode;
void LinkListInit(LinkNode** head); //初始化
void LinkListPrintChar(LinkNode* head, const char* msg); //打印链表
LinkNode* LinkListPushBack(LinkNode** head, LinkType value); //尾插
void LinkListPopBack(LinkNode** head); //尾删
void LinkListPushFront(LinkNode** head, LinkType value); //头插
void LinkListPopFront(LinkNode** head); //头删
LinkNode* LinkListFind(LinkNode* head, LinkType to_find); //查找元素在链表中的位置
void LinkListInsert(LinkNode** head, LinkNode* pos, LinkType value); //在pos之前插入元素
void LinkListInsertAfter(LinkNode** head, LinkNode* pos, LinkType value); //在pos之后插入元素
void LinkListErase1(LinkNode** head, LinkNode* pos); //删除指定位置的元素
void LinkListErase2(LinkNode** head, LinkNode** pos);
void LinkListRemove1(LinkNode** head, LinkType value); //删除指定值的元素
void LinkListRemove2(LinkNode** head, LinkType value);
void LinkListRemoveAll(LinkNode** head, LinkType value); //删除指定值的所有元素
int LinkListEmpty(LinkNode* head); //判断链表是否为空,为空返回1,否则返回0
size_t LinkListSize(LinkNode* head); //求链表元素个数
//经典面试题
void LinkListReversePrint(LinkNode* head); //逆序打印单链表
void LinkListInsertBefore(LinkNode** head, LinkNode* pos, LinkType value); //不允许遍历链表, 在 pos之前插入
LinkNode* JosephCycle(LinkNode* head, size_t food); //约瑟夫环
void LinkListReverse(LinkNode** head); //单链表逆置
void LinkListReverse2(LinkNode** head);
void LinkListBubbleSort(LinkNode* head); //单链表的冒泡排序
LinkNode* LinkListMerge(LinkNode* head1, LinkNode* head2); //将两个有序链表, 合并成一个有序链表
LinkNode* FindMidNode(LinkNode* head); //找到中间节点
LinkNode* FindLastKNode(LinkNode* head, size_t K); //找到倒数第 K 个节点
void EraseLastKNode(LinkNode** head, size_t K); //删除倒数第K个节点
LinkNode* HasCycle(LinkNode* head); //判定单链表是否带环. 如果带环返回1
size_t GetCycleLen(LinkNode* head); //如果链表带环, 求出环的长度
LinkNode* GetCycleEntry(LinkNode* head); //如果链表带环, 求出环的入口
LinkNode* HasCross(LinkNode* head1, LinkNode* head2); //判定两个链表是否相交, 并求出交点(假设链表不带环)
LinkNode* HasCrossWithCycle(LinkNode* head1, LinkNode* head2); //判定两个链表是否相交(假设链表可能带环)
LinkNode* UnionSet(LinkNode* head1, LinkNode* head2); //求两个已排序单链表中相同的数据
typedef struct ComplexNode{
LinkType data;
struct LinkNode* next;
struct LinkNode* random;
}ComplexNode;
ComplexNode* CreateComplexNode(LinkType value);
ComplexNode* CopyComplex(ComplexNode* head); //拷贝复杂链表
ComplexNode* CopyComplex2(ComplexNode* head); //拷贝复杂链表
②linklist.c
//经典面试题
#include "linklist.h"
#include <stdlib.h>
void LinkListReversePrint(LinkNode* head) //逆序打印单链表
{
if (head == NULL)
{
return;
}
LinkListReversePrint(head->next);
printf("[%c:%p] ", head->data, head);
}
void LinkListInsertBefore(LinkNode** head, LinkNode* pos, LinkType value) //不允许遍历链表, 在 pos之前插入
{
if (head == NULL || pos == NULL)
{
return; //非法输入
}
LinkNode* new_node = LinkListCreateNode(pos->data);
pos->data = value;
new_node->next = pos->next;
pos->next = new_node;
return;
}
LinkNode* JosephCycle(LinkNode* head, size_t food) //约瑟夫环
{
if (head == NULL)
{
return NULL;
}
if (food == 0)
{
return NULL;
}
LinkNode* cur = head;
while (cur != cur->next)
{
size_t i = 0;
for (; i < food - 1; ++i)
{
cur = cur->next;
}
printf("food:[%c]\n", cur->data);
cur->data = cur->next->data;
LinkNode* to_delete = cur->next;
cur->next = to_delete->next;
LinkListDestroyNode(to_delete);
}
return cur;
}
void LinkListReverse(LinkNode** head) //单链表逆置
{
if (head == NULL)
{
return; //非法输入
}
if (*head == NULL)
{
return; //空链表
}
if ((*head)->next == NULL)
{
return; //只有一个元素
}
LinkNode* cur = *head;
while (cur->next != NULL)
{
LinkNode* to_delete = cur->next;
//将当前结点删除
cur->next = to_delete->next;
//将这个被删除的结点插入到链表头部
to_delete->next = *head;
*head = to_delete;
}
return;
}
void LinkListReverse2(LinkNode** head)
{
if (head == NULL)
{
return; //非法输入
}
if (*head == NULL)
{
return; //空链表
}
if ((*head)->next == NULL)
{
return; //只有一个元素
}
LinkNode* pre = *head;
LinkNode* cur = (*head)->next;
pre->next = NULL;
while (cur != NULL)
{
LinkNode* next = cur->next;
cur->next = pre; //重置了当前结点的next
pre = cur;
cur = next;
}
*head = pre;
return;
}
void Swap(LinkType* a, LinkType* b)
{
LinkType tmp = *a;
*a = *b;
*b = tmp;
}
void LinkListBubbleSort(LinkNode* head) //单链表的冒泡排序(升序)
{
if (head == NULL)
{
return;
}
LinkNode* count = head;
LinkNode* tail = NULL;
for (; count != NULL; count = count->next)
{
LinkNode* cur = head;
for (; cur->next != tail; cur = cur->next)
{
if (cur->data > cur->next->data)
{
Swap(&cur->data, &cur->next->data);
}
}
tail = cur;
}
}
LinkNode* LinkListMerge(LinkNode* head1, LinkNode* head2) //将两个有序链表, 合并成一个有序链表
{
LinkNode* cur1 = head1;
LinkNode* cur2 = head2;
LinkNode* new_head = NULL;
LinkNode* new_tail = NULL;
while (cur1 != NULL && cur2 != NULL)
{
if (cur1->data < cur2->data)
{
if (new_head == NULL)
{
new_head = new_tail = cur1;
}
else
{
new_tail->next = cur1;
new_tail = new_tail->next;
}
cur1 = cur1->next;
}
else if (cur1->data >= cur2->data)
{
if (new_head == NULL)
{
new_head = new_tail = cur2;
}
else
{
new_tail->next = cur2;
new_tail = new_tail->next;
}
cur2 = cur2->next;
}
}
if (cur1 != NULL)
{
new_tail->next = cur1;
}
else
{
new_tail->next = cur2;
}
return new_head;
}
LinkNode* FindMidNode(LinkNode* head) //找到中间节点
{
LinkNode* slow = head;
LinkNode* fast = head;
while (fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
LinkNode* FindLastKNode(LinkNode* head, size_t K) //找到倒数第 K 个节点
{
LinkNode* slow = head;
LinkNode* fast = head;
size_t i = 0;
for (; i < K && fast != NULL; ++i)
{
fast = fast->next;
}
if (i < K)
{
//这种情况表示链表结点小于K,直接返回NULL
return NULL;
}
while (fast != NULL)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
void EraseLastKNode(LinkNode** head, size_t K) //删除倒数第K个节点
{
if (head == NULL)
{
return; //非法输入
}
if (*head == NULL)
{
return; //空链表
}
size_t size = LinkListSize(*head);
if (size < K)
{
//要删除的结点不存在
return;
}
if (size == K)
{
//要删除的是头结点
LinkNode* to_delete = *head;
*head = (*head)->next;
LinkListDestroyNode(to_delete);
return;
}
LinkNode* cur = *head;
size_t i = 0;
for (; i < size - (K + 1); ++i)
{
cur = cur->next;
}
LinkNode* to_delete = cur->next;
cur->next = to_delete->next;
LinkListDestroyNode(to_delete);
return;
}
LinkNode* HasCycle(LinkNode* head) //判定单链表是否带环. 如果带环返回1
{
LinkNode* slow = head;
LinkNode* fast = head;
while (fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
{
return fast;
}
}
return NULL;
}
size_t GetCycleLen(LinkNode* head) //如果链表带环, 求出环的长度
{
LinkNode* meet_node = HasCycle(head);
if (meet_node == NULL)
{
return 0; //链表无环
}
size_t count = 1;
LinkNode* cur = meet_node;
for (; cur->next != meet_node; cur = cur->next)
{
++count;
}
return count;
}
LinkNode* GetCycleEntry(LinkNode* head) //如果链表带环, 求出环的入口
{
LinkNode* meet_node = HasCycle(head);
if (meet_node == NULL)
{
return NULL; //无环,直接返回
}
LinkNode* cur1 = head;
LinkNode* cur2 = meet_node;
while (cur1 != cur2)
{
cur1 = cur1->next;
cur2 = cur2->next;
}
return cur1;
}
LinkNode* HasCross(LinkNode* head1, LinkNode* head2) //判定两个链表是否相交, 并求出交点
{
if (head1 == NULL || head2 == NULL)
{
return NULL;
}
size_t size1 = LinkListSize(head1);
size_t size2 = LinkListSize(head2);
LinkNode* cur1 = head1;
LinkNode* cur2 = head2;
if (size1 < size2)
{
size_t i = 0;
for (; i < size2 - size1; ++i)
{
cur2 = cur2->next;
}
}
else
{
size_t i = 0;
for (; i < size1 - size2; ++i)
{
cur1 = cur1->next;
}
}
while (cur1 != cur2)
{
cur1 = cur1->next;
cur2 = cur2->next;
}
return cur1;
}
LinkNode* HasCrossWithCycle(LinkNode* head1, LinkNode* head2) //判定两个链表是否相交(假设链表可能带环)
{
if (head1 == NULL || head2 == NULL)
{
return NULL;
}
LinkNode* entry1 = GetCycleEntry(head1);
LinkNode* entry2 = GetCycleEntry(head2);
if (entry1 == NULL && entry2 == NULL)
{
//1.两个链表都不带环
return HasCross(head1, head2) != NULL ? 1 : 0;
}
else if (entry1 != NULL && entry2 != NULL)
{
//2.两链表都带环
if (entry1 == entry2)
{
//相交在环外
return 1;
}
LinkNode* cur = entry1;
while (cur->next != entry1)
{
//相交在环上
if (cur == entry2)
{
return 1;
}
cur = cur->next;
}
return 0; //不相交
}
else
{
//3.一个带环,一个不带环,一定不相交
return 0;
}
return 0;
}
LinkNode* UnionSet(LinkNode* head1, LinkNode* head2) //求两个已排序单链表中相同的数据
{
if (head1 == NULL || head2 == NULL)
{
return NULL;
}
LinkNode* cur1 = head1;
LinkNode* cur2 = head2;
LinkNode* new_head = NULL;
LinkNode* new_tail = NULL;
while (cur1 != NULL && cur2 != NULL)
{
if (cur1->data < cur2->data)
{
cur1 = cur1->next;
}
else if (cur1->data > cur2->next)
{
cur2 = cur2->next;
}
else
{
//cur1的值与cur2的值相等,将这个元素放到结果中去
LinkNode* new_node = LinkListCreateNode(cur1->data);
if (new_head == NULL)
{
new_head = new_tail = new_node;
}
else
{
new_tail->next = new_node;
new_tail = new_tail->next;
}
cur1 = cur1->next;
cur2 = cur2->next;
}
}
return new_head;
}
ComplexNode* CreateComplexNode(LinkType value)
{
ComplexNode* ptr = (ComplexNode*)malloc(sizeof(ComplexNode));
ptr->data = value;
ptr->next = NULL;
ptr->random = NULL;
return ptr;
}
size_t Diff(ComplexNode* src, ComplexNode* dest)
{
if (src == NULL || dest == NULL)
{
return (size_t)-1;
}
size_t count = 0;
while (src != NULL)
{
if (src == dest)
{
return count;
}
++count;
src = src->next;
}
return (size_t)-1;
}
ComplexNode* Step(ComplexNode* pos, size_t offset)
{
size_t i = 0;
for (; i < offset; ++i)
{
if (pos == NULL)
{
return NULL;
}
pos = pos->next;
}
return pos;
}
ComplexNode* CopyComplex(ComplexNode* head) //拷贝复杂链表
{
if (head == NULL)
{
return NULL; //空链表
}
//1.先把链表进行简单复制
ComplexNode* new_head = NULL;
ComplexNode* new_tail = NULL;
ComplexNode* cur = head;
for (; cur != NULL; cur = cur->next)
{
ComplexNode* new_node = CreateComplexNode(cur->data);
if (new_head == NULL)
{
new_head = new_tail = new_node;
}
else
{
new_tail->next = new_node;
new_tail = new_tail->next;
}
}
//2.再去依次求每个random指针相对头结点的偏移量
ComplexNode* new_cur = new_head;
for (cur = head; cur != NULL && new_cur != NULL; cur = cur->next, new_cur = new_cur->next)
{
if (cur->random == NULL)
{
new_cur->random = NULL;
continue;
}
//3.根据偏移量,修改每个新链表结点的random指针
size_t offset = Diff(head, cur->random);
new_cur->random = Step(head, offset);
}
return new_head;
}
ComplexNode* CopyComplex2(ComplexNode* head) //拷贝复杂链表
{
//1.遍历旧链表,给每一个结点都创建一个对应的新结点
// 并将新结点插入到旧结点之后
ComplexNode* cur = head;
for (; cur != NULL; cur = cur->next->next)
{
ComplexNode* new_node = CreateComplexNode(cur->data);
new_node->next = cur->next;
cur->next = new_node;
}
//2.再遍历链表,更新每个新结点的random指针
for (cur = head; cur != NULL; cur = cur->next->next)
{
ComplexNode* cur_next = cur->next;
cur_next->random = cur->random->next;
}
//3.再遍历链表,把新结点依次拆下来,组成一个新的链表
ComplexNode* new_head = NULL;
ComplexNode* new_tail = NULL;
for (cur = head; cur != NULL; cur = cur->next)
{
ComplexNode* to_delete = cur->next;
//将结点拆下来
cur->next = to_delete->next;
//将这个结点安装到新链表的末尾
if (new_head == NULL)
{
new_head = new_tail = to_delete;
}
else
{
new_tail->next = to_delete;
new_tail = new_tail->next;
}
}
return new_head;
}
③test.c
//经典面试题
#include "linklist.h"
#include <windows.h>
#define TEST_HEADER printf("\n========================================%s===========================================\n",__FUNCTION__)
void TestReversePrint()
{
TEST_HEADER;
LinkNode* head = NULL;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPrintChar(head, "尾插四个元素");
printf("[逆序打印]:");
LinkListReversePrint(head);
printf("\n");
}
void TestInsertBefore()
{
TEST_HEADER;
LinkNode* head = NULL;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkNode* pos_c = LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPrintChar(head, "尾插四个元素");
LinkListInsertBefore(&head, pos_c, 'x');
LinkListPrintChar(head, "在c之前插入元素x");
}
void TestJosephCycle()
{
TEST_HEADER;
LinkNode* head = NULL;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPushBack(&head, 'e');
LinkListPushBack(&head, 'f');
LinkListPushBack(&head, 'g');
LinkNode* pos = LinkListPushBack(&head, 'h');
pos->next = head;
pos = JosephCycle(head, 5);
printf("JosephCycle: %c\n", pos->data);
}
void TestReverse()
{
TEST_HEADER;
LinkNode* head = NULL;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPushBack(&head, 'e');
LinkListPushBack(&head, 'f');
LinkListPrintChar(head, "尾插六个元素");
LinkListReverse(&head);
LinkListPrintChar(head, "逆置后的结果");
}
void TestReverse2()
{
TEST_HEADER;
LinkNode* head = NULL;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPushBack(&head, 'e');
LinkListPushBack(&head, 'f');
LinkListPrintChar(head, "尾插六个元素");
LinkListReverse2(&head);
LinkListPrintChar(head, "逆置后的结果");
}
void TestBubbleSort()
{
TEST_HEADER;
LinkNode* head = NULL;
LinkListInit(&head);
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'd');
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'f');
LinkListPushBack(&head, 'e');
LinkListPushBack(&head, 'c');
LinkListPrintChar(head, "尾插六个元素");
LinkListBubbleSort(head);
LinkListPrintChar(head, "排序后的结果");
}
void TestMerge()
{
TEST_HEADER;
LinkNode* head1 = NULL;
LinkListInit(&head1);
LinkListPushBack(&head1, 'a');
LinkListPushBack(&head1, 'd');
LinkListPushBack(&head1, 'e');
LinkListPushBack(&head1, 'h');
LinkListPrintChar(head1, "尾插四个元素");
LinkNode* head2 = NULL;
LinkListInit(&head2);
LinkListPushBack(&head2, 'b');
LinkListPushBack(&head2, 'c');
LinkListPushBack(&head2, 'f');
LinkListPrintChar(head2, "尾插三个元素");
LinkNode* new_head = LinkListMerge(head1, head2);
LinkListPrintChar(new_head, "合并后的结果");
}
void TestMidNode()
{
TEST_HEADER;
LinkNode* head = NULL;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPushBack(&head, 'e');
LinkListPrintChar(head, "尾插五个元素");
LinkNode* mid = FindMidNode(head);
printf("mid expect c, actual %c\n", mid->data);
}
void TestLastK()
{
TEST_HEADER;
LinkNode* head = NULL;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPushBack(&head, 'e');
LinkListPrintChar(head, "尾插五个元素");
LinkNode* node = FindLastKNode(head, 2);
printf("last 2 node expect d,actual %c\n", node->data);
}
void TestEraseLastK()
{
TEST_HEADER;
LinkNode* head = NULL;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPushBack(&head, 'e');
LinkListPrintChar(head, "尾插五个元素");
EraseLastKNode(&head, 2);
LinkListPrintChar(head, "删除d 后结果");
}
void TestHasCycle()
{
TEST_HEADER;
LinkNode* head = NULL;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkNode* pos = LinkListPushBack(&head, 'e');
pos->next = head;
printf("list has cycle: expect 1, actual %p\n", HasCycle(head));
}
void TestCycleLen()
{
TEST_HEADER;
LinkNode* head = NULL;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkNode* pos = LinkListPushBack(&head, 'e');
pos->next = head;
printf("cycle len expect 5, actual %lu\n", GetCycleLen(head));
}
void TestGetEntry()
{
TEST_HEADER;
LinkNode* head = NULL;
LinkListInit(&head);
LinkListPushBack(&head, 'a');
LinkListPushBack(&head, 'b');
LinkNode* pos_c = LinkListPushBack(&head, 'c');
LinkListPushBack(&head, 'd');
LinkListPushBack(&head, 'e');
LinkListPushBack(&head, 'f');
LinkNode* pos_g = LinkListPushBack(&head, 'g');
pos_g->next = pos_c;
printf("cycle entry expect c,actual %c\n", GetCycleEntry(head)->data);
}
void TestHasCross()
{
TEST_HEADER;
LinkNode* head1 = NULL;
LinkListInit(&head1);
LinkListPushBack(&head1, 'a');
LinkNode* pos_d = LinkListPushBack(&head1, 'd');
LinkListPushBack(&head1, 'e');
LinkListPushBack(&head1, 'h');
LinkNode* head2 = NULL;
LinkListInit(&head2);
LinkListPushBack(&head2, 'b');
LinkListPushBack(&head2, 'c');
LinkNode* pos_f = LinkListPushBack(&head2, 'f');
pos_f->next = pos_d;
LinkNode* cross = HasCross(head1, head2);
printf("cross expect d, actual %c\n", cross->data);
}
void TestHasCrossWithCycle()
{
TEST_HEADER;
LinkNode* head1 = NULL;
LinkListInit(&head1);
LinkNode* pos_a = LinkListPushBack(&head1, 'a');
LinkNode* pos_b = LinkListPushBack(&head1, 'b');
LinkListPushBack(&head1, 'c');
LinkNode* pos_d = LinkListPushBack(&head1, 'd');
pos_d->next = pos_b;
LinkNode* head2 = NULL;
LinkListInit(&head2);
LinkListPushBack(&head2, 'e');
LinkListPushBack(&head2, 'f');
LinkNode* pos_g = LinkListPushBack(&head2, 'g');
pos_g->next = pos_a;
int ret = HasCrossWithCycle(head1, head2);
printf("ret expect 1, actual %d\n", ret);
}
void TestUnionSet()
{
TEST_HEADER;
LinkNode* head1 = NULL;
LinkListInit(&head1);
LinkListPushBack(&head1, 'a');
LinkListPushBack(&head1, 'd');
LinkListPushBack(&head1, 'e');
LinkListPushBack(&head1, 'h');
LinkListPrintChar(head1, "创建链表一");
LinkNode* head2 = NULL;
LinkListInit(&head2);
LinkListPushBack(&head2, 'b');
LinkListPushBack(&head2, 'c');
LinkListPushBack(&head2, 'd');
LinkListPushBack(&head2, 'e');
LinkListPushBack(&head2, 'f');
LinkListPushBack(&head2, 'h');
LinkListPrintChar(head2, "创建链表二");
LinkNode* new_head = UnionSet(head1, head2);
LinkListPrintChar(new_head, "两链表交集");
}
void TestComplexCopy()
{
TEST_HEADER;
ComplexNode* a = CreateComplexNode('a');
ComplexNode* b = CreateComplexNode('b');
ComplexNode* c = CreateComplexNode('c');
ComplexNode* d = CreateComplexNode('d');
a->next = a;
b->next = c;
c->next = d;
d->next = NULL;
a->random = c;
b->random = a;
c->random = NULL;
d->random = d;
ComplexNode* new_head = CopyComplex2(a);
printf("new_head:%p\n", new_head);
}
int main()
{
//经典面试题
TestReversePrint();
TestInsertBefore();
TestJosephCycle();
TestReverse();
TestReverse2();
TestBubbleSort();
TestMerge();
TestMidNode();
TestLastK();
TestEraseLastK();
TestHasCycle();
TestCycleLen();
TestGetEntry();
TestHasCross();
TestHasCrossWithCycle();
TestUnionSet();
TestComplexCopy();
system("pause");
return 0;
}
结果:
顺序表与链表比较:
- 顺序表支持随机访问,单链表不支持随机访问
- 顺序表插入/删除数据效率很低,时间复杂度为O(N)(除尾插尾删),单链表插入/删除效率更高,时间复杂度为O(1)
- 顺序表的CPU高速缓存效率更高,单链表CPU高速缓存效率低