LinkList.h
#pragma once
#include<stdio.h>
#include<stddef.h>
typedef char LinkType;
typedef struct LinkNode{
LinkType data;
struct LinkNode* next;
}LinkNode;
//初始化
void LinkListInit(LinkNode** head);
//创建一个新结点
LinkNode* CreatNewNode(LinkType value);
//尾插
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);
//在pos之前插入元素
void LinkListInsert(LinkNode** head, LinkNode* pos, LinkType value);
//在pos之后插入元素
void LinkListInsertAfter(LinkNode** head, LinkNode* pos, LinkType value);
//删除指定位置的元素
void LinkListErase(LinkNode** head, LinkNode* pos);
//删除指定值的元素
void LinkListRemove(LinkNode** head, LinkType to_delete);
//删除指定值的所有元素
void LinkListRemoveAll(LinkNode** head, LinkType to_delete);
//判断链表为空
int LinkListEmpty(LinkNode* head);
//求链表元素个数
size_t LinkListSize(LinkNode* head);
//逆序打印单链表
void LinkListReversePrint(LinkNode** head);
//不允许遍历链表,在pos位置之前插入一个元素
void LinkListInsertBefore(LinkNode* head, LinkNode* pos, LinkType value);
//单链表逆置
void LinkListReverse(LinkNode** head);
////单链表逆置(就地逆置)
//void LinkListReverse2(LinkNode** head);
//单链表的冒泡排序
void LinkListBubbleSort(LinkNode* head);
//将两个链表合成为一个链表并排序
LinkNode* LinkListMerge(LinkNode* head1, LinkNode* head2);
//将两个有序链表合并成为一个有序链表
LinkNode* LinkListMerge2(LinkNode* head1, LinkNode* head2);
//寻找链表的中间结点
LinkNode* FindMidNode(LinkNode* head);
//寻找第倒数第k个结点
LinkNode* FindLastKNode(LinkNode* head, size_t k);
//删除第K个结点
void EraseLastKNode(LinkNode* head, size_t k);
//判断链表是否带环,如果带环,则返回环的长度,如果不带环,返回-1
size_t CheckCycle(LinkNode* head);
//如果链表带环,求出环的入口
//两种方法
//1.已知入口点,假设从入口点断开,则问题变为两个单链表求交点问题
//通过设置快慢指针,快的先走两个链表长度的差值,然后第一次相遇的结点为环的入口
LinkNode* GetCycleEntryNode2(LinkNode* head, LinkNode* MetNode);
//2.两个指针,一个从头开始走,一个从相遇点开始走,两个指针相遇时,则相遇点为入口点
LinkNode* GetCycleEntryNode1(LinkNode* head);
//判断两个链表是否有交点,并求出交点
LinkNode* HasCrossNode(LinkNode* head1, LinkNode* head2);
LinkList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"LinkList.h"
#include<stdlib.h>
LinkNode* CreatNewNode(LinkType value) {
LinkNode* NewNode = (LinkNode*)malloc(sizeof(LinkNode));
NewNode->data = value;
NewNode->next = NULL;
return NewNode;
}
void DestoryNode(LinkNode** Delete) {
if (Delete == NULL) {
return;
}
if (*Delete == NULL) {
return;
}
free(*Delete);
}
void LinkListInit(LinkNode** head) {
if (head == NULL) {
//非法输入
return;
}
if ((*head) == NULL) {
//空链表
return;
}
(*head) = NULL;
}
LinkNode* LinkListPushBack(LinkNode** head, LinkType value) {
if (head == NULL) {
//非法输入
return;
}
if ((*head) == NULL) {
//空链表
(*head) = CreatNewNode(value);
}
//链表不为空链表,直接遍历一遍
else {
LinkNode* begin = *head;
while (begin->next) {
begin = begin->next;
}
begin->next = CreatNewNode(value);
}
}
void LinkListPopBack(LinkNode** head) {
if (head == NULL) {
return;
}
if (*head == NULL) {
//空链表
return;
}
LinkNode* pop = *head;
while (pop->next->next){
pop = pop->next;
}
LinkNode* Delete = pop->next;
DestoryNode(&Delete);
pop->next = NULL;
}
void LinkListPushFront(LinkNode** head, LinkType value) {
if (head == NULL) {
return;
}
if (*head == NULL) {
//空链表
LinkNode* NewNode = CreatNewNode(value);
*(head) = NewNode;
}
else{
LinkNode* NewNode = CreatNewNode(value);
LinkNode* NextNode = (*head);
(*head) = NewNode;
NewNode->next = NextNode;
}
}
void LinkListPopFront(LinkNode** head) {
if (head == NULL) {
return;
}
if (*head == NULL) {
return;
}
LinkNode* Delete = (*head);
(*head) = (*head)->next;
DestoryNode(&Delete);
}
LinkNode* LinkListFind(LinkNode* head, LinkType to_find) {
if (head == NULL) {
//空链表
return;
}
LinkNode* cur = head;
while (cur) {
if (cur->data == to_find) {
return cur;
}
cur = cur->next;
}
return 0;
}
void LinkListInsert(LinkNode** head, LinkNode* pos, LinkType value){
if (head == NULL) {
return;
}
if (*head == NULL) {
//空链表
return;
}
if (pos == NULL) {
return;
}
LinkNode* cur = (*head);
while (cur) {
if (pos == (*head)) {
LinkNode* NewNode = CreatNewNode(value);
LinkNode* AfterInsert = (*head);
(*head) = NewNode;
NewNode->next = AfterInsert;
}
if (cur->next == pos) {
LinkNode* NewNode = CreatNewNode(value);
LinkNode* AfterInsert = cur->next;
cur->next = NewNode;
NewNode->next = AfterInsert;
break;
}
cur = cur->next;
}
}
void LinkListInsertAfter(LinkNode** head, LinkNode* pos, LinkType value) {
if (head == NULL) {
//非法输入
return;
}
if (*head == NULL) {
//空链表
return;
}
if (pos == NULL) {
return;
}
LinkNode* cur = *head;
while (cur) {
if (pos == cur) {
LinkNode* NewNode = CreatNewNode(value);
LinkNode* After = cur->next;
cur->next = NewNode;
NewNode->next = After;
break;
}
cur = cur->next;
}
}
void LinkListErase(LinkNode** head, LinkNode* pos){
if (head == NULL) {
return;
}
if (*head == NULL) {
//空链表
return;
}
if (pos == NULL) {
return;
}
LinkNode* cur = (*head);
while (cur) {
if (pos == (*head)) {
(*head) = (*head)->next;
DestoryNode(&cur);
break;
}
if (cur->next == pos) {
LinkNode* Delete = cur->next;
cur->next = cur->next->next;
DestoryNode(&Delete);
break;
}
cur = cur->next;
}
}
void LinkListRemove(LinkNode** head, LinkType to_delete) {
if (head == NULL) {
return;
}
if (*head == NULL) {
return;
}
LinkNode* begin = *head;
LinkNode* prev = NULL;
while (begin) {
if ((*head)->data == to_delete) {
LinkNode* Delete = begin;
(*head) = (*head)->next;
DestoryNode(&Delete);
break;
}
if (begin->data == to_delete) {
LinkNode* Delete = begin;
prev->next = begin->next;
DestoryNode(&Delete);
break;
}
prev = begin;
begin = begin->next;
}
}
size_t LinkListSize(LinkNode* head) {
if (head == NULL) {
return 0;
}
size_t count = 0;
LinkNode* cur = head;
while (cur) {
count++;
cur = cur->next;
}
return count;
}
void LinkListRemoveAll(LinkNode** head, LinkType to_delete) {
if (head == NULL) {
return;
}
if (*head == NULL) {
return;
}
size_t size = LinkListSize(*head);
while (size) {
LinkListRemove(&(*head), to_delete);
size--;
}
}
int LinkListEmpty(LinkNode* head) {
if (head == NULL) {
//空链表
return 1;
}
else {
return 0;
}
}
void LinkListReversePrint(LinkNode** head) {
if (head == NULL) {
//空链表
return;
}
LinkNode* NewHead = NULL;
LinkNode* cur = (*head);
while (cur) {
//拆结点
LinkNode* Node = cur;
cur = cur->next;
//装结点
Node->next = NewHead;
NewHead = Node;
}
LinkNode* cur2 = NewHead;
while (cur2) {
printf("[%c]->", cur2->data);
cur2 = cur2->next;
}
printf("NULL\n");
}
void LinkListInsertBefore(LinkNode* head, LinkNode* pos, LinkType value) {
if (head == NULL) {
//空链表
return;
}
if (pos == NULL) {
//非法
return;
}
LinkNode* NewNode = CreatNewNode(pos->data);
LinkNode* cur = pos->next;
pos->next = NewNode;
NewNode->next = cur;
pos->data = value;
}
void LinkListReverse(LinkNode** head) {
if (head == NULL) {
return;
}
if (*head == NULL) {
return;
}
LinkNode* NewHead = NULL;
LinkNode* begin = (*head);
while (begin != NULL) {
//拆结点
LinkNode* Node = begin;
begin = begin->next;
//把新结点装给新的头节点
Node->next = NewHead;
NewHead = Node;
}
(*head) = NewHead;
}
//void LinkListReverse2(LinkNode** head) {
// if (head == NULL) {
// return;
// }
// if (*head == NULL) {
// return;
// }
// LinkNode* pre = NULL;
// LinkNode* cur = *head;
//
// while (cur) {
//
//
// }
// (*head) = pre;
//}
void LinkListBubbleSort(LinkNode* head) {
if (head == NULL) {
//空链表
return;
}
//prev 和 next 指针 一前一后向后遍历链表
LinkNode* prev = NULL;
LinkNode* next = NULL;
//tail是冒泡排序时的尾标记
LinkNode* tail = NULL;
while (tail != head) {
//优化标记
int exchange = 0;
//将数据向后冒
prev = head;
next = head->next;
while (next != tail) {
//交换
if (prev->data > next->data) {
LinkType tmp = prev->data;
prev->data = next->data;
next->data = tmp;
exchange = 1;
}
//指针分别向后移动一个结点
prev = next;
next = next->next;
}
if (exchange == 0) {
return;
}
//更新尾标记
tail = prev;
}
}
LinkNode* LinkListMerge(LinkNode* head1, LinkNode* head2) {
if (head1 == NULL) {
return head2;
}
if (head2 == NULL) {
return head1;
}
if (head1 == NULL || head2 == NULL) {
return;
}
LinkNode* cur = head1;
while (cur) {
LinkNode* node = cur;
cur = cur->next;
node->next = head2;
head2 = node;
}
return head2;
}
LinkNode* FindMidNode(LinkNode* head) {
if (head == NULL) {
return;
}
LinkNode* fast = head;
LinkNode* slow = head;
while (fast) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
LinkNode* FindLastKNode(LinkNode* head, size_t k) {
if (head == NULL) {
return;
}
LinkNode* fast = head;
LinkNode* slow = head;
while (k) {
fast = fast->next;
k--;
}
while (fast) {
slow = slow->next;
fast = fast->next;
}
return slow;
}
void EraseLastKNode(LinkNode* head, size_t k) {
if (head == NULL) {
//空链表
return;
}
LinkNode* fast = head;
LinkNode* slow = head;
while (k) {
fast = fast->next;
k--;
}
while (fast) {
slow = slow->next;
fast = fast->next;
}
slow->data = slow->next->data;
LinkNode* delete = slow->next;
slow->next = delete->next;
DestoryNode(&delete);
}
LinkNode* LinkListMerge2(LinkNode* head1, LinkNode* head2) {
//如果有任意一个链表是空,则返回另一个
if (head1 == NULL) {
return head2;
}
if (head2 == NULL) {
return head1;
}
//newhead保存最终链表的头指针,tail是尾节点
LinkNode* newhead;
LinkNode* tail;
if (head1->data < head2->data) {
newhead = head1;
head1 = head1->next;
}
else {
newhead = head2;
head2 = head2->next;
}
tail = newhead;
while (head1 && head2) {
if (head1->data < head2->data) {
//将数据小的结点存入newhead中
tail->next = head1;
head1 = head1->next;
//tail指针向后走一个
tail = tail->next;
}
else{
tail->next = head2;
head2 = head2->next;
tail = tail->next;
}
}
//循环退出,某一个链表到了末尾,head1或者head2为空指针
if (head1) {
tail->next = head1;
}
if (head2) {
tail->next = head2;
}
return newhead;
}
size_t CheckCycle(LinkNode* head) {
if (head == NULL) {
return -1;
}
LinkNode* slow = head;
LinkNode* fast = head;
//fast->next不能为NULL
while (fast && fast->next) {
//快慢指针
slow = slow->next;
fast = fast->next->next;
//如果快慢指针相遇,则一定有环
if (slow == fast) {
size_t size = 0;
//此循环必须先执行一次,所以用do while语句
do {
slow = slow->next;
++size;
} while (slow != fast);
return size;
}
}
return (size_t)-1;
}
LinkNode* GetCycleEntryNode1(LinkNode* head) {
if (head == NULL) {
return;
}
LinkNode* slow = head;
LinkNode* fast = head;
LinkNode* MetNode = NULL;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (fast == slow) {
MetNode = fast;//保存相遇点
break;
}
}
LinkNode* cur = head;
while (1) {
cur = cur->next;
MetNode = MetNode->next;
if (cur == MetNode) {
return cur;
}
}
}
LinkNode* GetCycleEntryNode2(LinkNode* head, LinkNode* MetNode) {
if (head == NULL) {
return;
}
if (MetNode == NULL) {
return;
}
int sz1 = 0;
int sz2 = 0;
LinkNode* begin1 = head;
LinkNode* begin2 = MetNode->next;
//假设链表从相遇点断开,求出两个单链表的长度
while (begin1 != MetNode) {
begin1 = begin1->next;
++sz1;
}
while (begin2 != MetNode) {
begin2 = begin2->next;
++sz2;
}
begin1 = head;
begin2 = MetNode->next;
int sz = 0;
if (sz1 > sz2) {
sz = sz1 - sz2;
while (sz) {
begin1 = begin1->next;
sz--;
}
}
else if (sz2 > sz1) {
sz = sz2 - sz1;
while (sz) {
begin2 = begin2->next;
sz--;
}
}
//begin1和begin2第一次相遇的点就是入口点
while (begin1 != begin2) {
begin1 = begin1->next;
begin2 = begin2->next;
}
return begin1;
}
//判断链表相交
/*1.两个链表都是单链表,可能相交
方法①:单链表相交,他们的尾结点一定是相同的
方法②:直接让某一个单链表的尾结点指向另一个单链表,这样就转化位链表是否带环问题
求交点方法,求出两个单链表的长度,然后让短的先走两个链表长度的差值,然后再一起走,相遇点即位交点
2.两个链表中有一个带环,另一个不带环
不可能相交
3.两个链表都带环
方法:求出某一个链表的环的入口点,然后断开,再遍历第二个链表,
如果链表不带环了,就代表两个链表相交,转化为两个单链表求交点*/
LinkNode* HasCrossNode(LinkNode* head1, LinkNode* head2) {
if (head1 == NULL) {
return;
}
if (head2 == NULL) {
return;
}
//先判断两个链表是否带环
size_t flag1 = CheckCycle(head1);
size_t flag2 = CheckCycle(head2);
//两个链表都不带环
if (flag1 == (size_t)-1 && flag2 == (size_t)-1) {
//遍历两个链表并顺表求出长度
LinkNode* cur1 = head1;
size_t length1 = 1;
LinkNode* cur2 = head2;
size_t length2 = 1;
while (cur1->next) {
cur1 = cur1->next;
++length1;
}
while (cur2->next) {
cur2 = cur2->next;
++length2;
}
if (cur1 == cur2) {
//尾结点相等
//两个链表确实相交了
//对cur1和cur2初始化
cur1 = head1;
cur2 = head2;
//判断两个链表谁长
if (length1 >= length2) {
size_t length = length1 - length2;
//让长的先走两个链表的差值,然后再一起走
while (length--) {
cur1 = cur1->next;
}
while (cur1 != cur2) {
cur1 = cur1->next;
cur2 = cur2->next;
}
//通过while循环让cur1和cur2相遇,相遇点为交点
return cur1;
}
else if (length2 > length1) {
size_t length = length2 - length1;
while (length--) {
cur2 = cur2->next;
}
while (cur1 != cur2) {
cur1 = cur1->next;
cur2 = cur2->next;
}
return cur2;
}
}
else if (cur1 != cur2) {
//尾结点不相等,肯定不想交
printf("两个链表都位单链表且不相交!\n");
return (LinkNode*)-1;
}
}
//两个链表都带环
else if (flag1 != (size_t)-1 && flag2 != (size_t)-1) {
/*①相交,交点在环外
②相交,交点是环的入口点
方法:求出某个链表的环的入口点,然后断开,然后遍历另一个链表,看是否还有环,
如果没有了,就代表相交,交点在环的入口点之前
转化为两个单链表求交点*/
//得到链表1的入口点
LinkNode* entry1 = GetCycleEntryNode1(head1);
//得到链表2的入口点
LinkNode* entry2 = GetCycleEntryNode1(head2);
LinkNode* cur1 = head1;
LinkNode* cur2 = head2;
size_t length1 = 1;
//通过遍历找到环的入口点之前的点,计算之前的长度
while (cur1->next != entry1) {
cur1 = cur1->next;
++length1;
}
//断开环的入口点
cur1->next = NULL;
//判断链表2是否带环
size_t flag = CheckCycle(head2);
if (flag == (size_t)-1) {
//链表不带环了,求出链表的长度
size_t length2 = 0;
while (cur2) {
cur2 = cur2->next;
++length2;
}
cur2 = head2;
cur1 = head1;
//链表2不带环了,表明他们的交点在环外
if (length1 >= length2) {
size_t length = length1 - length2;
while (length--) {
cur1 = cur1->next;
}
while (cur1 != cur2) {
cur1 = cur1->next;
cur2 = cur2->next;
}
return cur1;
}
else if (length2 > length1) {
size_t length = length2 - length1;
while (length--) {
cur2 = cur2->next;
}
while (cur1 != cur2) {
cur1 = cur1->next;
cur2 = cur2->next;
}
return cur1;
}
}
else {
//链表2依旧带环
//判断链表2的入口点是否在链表1的环上
LinkNode* cur3 = entry1;
LinkNode* cur4 = entry2;
//flag是链表2的环的长度,如果两个链表是相交的,那么他们的环是同一个
while (cur3 != cur4 ) {
cur3 = cur3->next;
flag--;
if (flag == -1) {
//表示遍历了一遍链表1的环但是并未找到与链表2环相等的点,代表两个链表带环且没有交点
printf("\n\n两个链表带环且没有交点\n");
return (LinkNode*)-1;
}
}
if (cur3 != entry1){
printf("\n\n两个链表带环且有两个交点,分别是两个链表环的入口点\n");
return (LinkNode*)-1;
}
else {
printf("\n\n两个链表带环有且只有一个交点,交点是环的入口点\n");
return entry1;
}
}
}
else {
printf("链表不相交\n");
return (LinkNode*)-1;
}
}
test.c#define _CRT_SECURE_NO_WARNINGS 1
#include"LinkList.h"
#include<stdlib.h>
#include<stddef.h>
#define FUNCTION printf("-----------------------%s-----------------------\n",__FUNCTION__);
void PrintChar(LinkNode* head, char* msg) {
if (head == NULL) {
return;
}
printf("%s\n\n", msg);
while (head) {
printf("[%c] ", head->data);
head = head->next;
}
printf("\n\n");
}
void TestPushBack() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
}
void TestPopBack() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
LinkListPopBack(&pnode);
LinkListPopBack(&pnode);
PrintChar(pnode, "尾删两个元素");
}
void TestPushFront() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
LinkListPushFront(&pnode, 'a');
LinkListPushFront(&pnode, 'b');
LinkListPushFront(&pnode, 'c');
LinkListPushFront(&pnode, 'd');
PrintChar(pnode, "头插四个元素");
}
void TestPopFront() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushFront(&pnode, 'a');
LinkListPushFront(&pnode, 'b');
LinkListPushFront(&pnode, 'c');
LinkListPushFront(&pnode, 'd');
PrintChar(pnode, "头插四个元素");
LinkListPopFront(&pnode);
LinkListPopFront(&pnode);
PrintChar(pnode, "头删两个元素");
}
void TestFind() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushFront(&pnode, 'a');
LinkListPushFront(&pnode, 'b');
LinkListPushFront(&pnode, 'c');
LinkListPushFront(&pnode, 'd');
PrintChar(pnode, "头插四个元素");
if (LinkListFind(pnode, 'b')) {
printf("find sucess!!!\n");
}
if (LinkListFind(pnode, 'f') == 0) {
printf("lose!!!\n");
}
}
void TestInsert() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkNode* pos_a = LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkNode* pos_d = LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
LinkListInsert(&pnode, pos_d, 'e');
PrintChar(pnode, "在d之前插入一个元素e:");
LinkListInsert(&pnode, pos_a, 'f');
PrintChar(pnode, "在a之前插入一个元素f:");
}
void TestAfterInsert() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkNode* pos_a = LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkNode* pos_d = LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
LinkListInsertAfter(&pnode, pos_a, 'f');
PrintChar(pnode, "在a之后插入一个元素f:");
LinkListInsertAfter(&pnode, pos_d, 'e');
PrintChar(pnode, "在d之后插入一个元素e:");
}
void TestErase() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkNode* pos_a = LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkNode* pos_d = LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
LinkListErase(&pnode, pos_a);
PrintChar(pnode, "删除元素'a'");
LinkListErase(&pnode, pos_d);
PrintChar(pnode, "删除元素'd'");
}
void TestRemove() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
LinkListRemove(&pnode, 'a');
PrintChar(pnode, "删除元素a");
LinkListRemove(&pnode, 'd');
PrintChar(pnode, "删除元素d");
}
void TestRemoveAll() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
LinkListRemoveAll(&pnode, 'a');
PrintChar(pnode, "删除元素'a'");
LinkListRemoveAll(&pnode, 'd');
PrintChar(pnode, "删除元素'd'");
}
void TestEmpty() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
int ret;
ret = LinkListEmpty(pnode);
printf("expect 1,actual %d: \n", ret);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
ret = LinkListEmpty(pnode);
printf("expect 0, actual %d\n: ", ret);
}
void TestListSize() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
size_t size = LinkListSize(pnode);
printf("except 4,actual : %d\n", size);
}
void TestReversePrint() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
LinkListReversePrint(&pnode);
}
void TestInsertBefore() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkNode* pos_a = LinkListPushBack(&pnode, 'a');
LinkNode* pos_b = LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkNode* pos_d = LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
LinkListInsertBefore(pnode, pos_b, 'e');
PrintChar(pnode, "在b之前插入e");
LinkListInsertBefore(pnode, pos_d, 'f');
PrintChar(pnode, "在d之前插入f");
LinkListInsertBefore(pnode, pos_a, 'g');
PrintChar(pnode, "在a之前插入g");
}
void TestReverse() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插四个元素");
LinkListReverse(&pnode);
PrintChar(pnode, "链表逆置");
}
//void TestReverse2() {
// LinkNode* pnode;
// FUNCTION;
// LinkListInit(&pnode);
// LinkListPushBack(&pnode, 'a');
// LinkListPushBack(&pnode, 'b');
// LinkListPushBack(&pnode, 'c');
// LinkListPushBack(&pnode, 'd');
// PrintChar(pnode, "尾插四个元素");
// LinkListReverse2(&pnode);
// PrintChar(pnode, "链表逆置");
//}
void TestBubbleSort() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插八个元素");
LinkListBubbleSort(pnode);
PrintChar(pnode, "冒泡排序:");
}
void TestListMerge() {
LinkNode* pnode;
LinkNode* pnode2;
FUNCTION;
LinkListInit(&pnode);
LinkListInit(&pnode2);
printf("Head1:\n");
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
LinkListPushBack(&pnode, 'f');
PrintChar(pnode, "尾插四个元素");
printf("Head2:\n");
LinkListPushBack(&pnode2, 'b');
LinkListPushBack(&pnode2, 'e');
LinkListPushBack(&pnode2, 'g');
LinkListPushBack(&pnode2, 'h');
PrintChar(pnode, "尾插八个元素");
LinkNode* head = LinkListMerge(pnode, pnode2);
LinkListBubbleSort(head);
PrintChar(head, "合并head1和head2:");
}
void TestFindMid() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插八个元素");
LinkNode* Mid = FindMidNode(pnode);
printf("中间结点为:%c\n", Mid->data);
}
void TestFindLastKNode() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插八个元素");
LinkNode* LastKNode = FindLastKNode(pnode, 6);
printf("the Last k node data: %c\n", LastKNode->data);
LinkNode* LastKNode2 = FindLastKNode(pnode, 5);
printf("the Last k node data: %c\n", LastKNode2->data);
}
void TestEraseLastKNode() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'd');
PrintChar(pnode, "尾插八个元素");
EraseLastKNode(pnode, 8);
PrintChar(pnode, "删除倒数第八个元素");
EraseLastKNode(pnode, 4);
PrintChar(pnode, "删除倒数第四个元素");
}
void TestLinkListMerge2() {
LinkNode* pnode1;
LinkNode* pnode2;
FUNCTION;
LinkListInit(&pnode1);
LinkListInit(&pnode2);
LinkListPushBack(&pnode1, 'a');
LinkListPushBack(&pnode1, 'c');
LinkListPushBack(&pnode1, 'e');
LinkListPushBack(&pnode1, 'g');
LinkListPushBack(&pnode1, 'h');
LinkListPushBack(&pnode2, 'b');
LinkListPushBack(&pnode2, 'd');
LinkListPushBack(&pnode2, 'f');
LinkListPushBack(&pnode2, 'g');
LinkListPushBack(&pnode2, 'i');
LinkListPushBack(&pnode2, 'j');
LinkNode* newpnode = LinkListMerge2(pnode1, pnode2);
PrintChar(newpnode, "合并后的链表为:");
}
void TestCheckCycle() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'e');
LinkListPushBack(&pnode, 'f');
LinkListPushBack(&pnode, 'g');
LinkListPushBack(&pnode, 'h');
LinkNode* cur = pnode;
while (cur->next) {
cur = cur->next;
}
cur->next = pnode->next->next;
size_t sz = CheckCycle(pnode);
printf("expect 5, actual : %d\n\n\n", sz);
}
void TestGetCycleNode1() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'e');
LinkListPushBack(&pnode, 'f');
LinkListPushBack(&pnode, 'g');
LinkListPushBack(&pnode, 'h');
LinkNode* cur = pnode;
while (cur->next) {
cur = cur->next;
}
cur->next = pnode->next->next->next;
LinkNode* entrynode = GetCycleEntryNode1(pnode);
printf("expect entrynode is: e, actual: %c\n\n", entrynode->data);
}
void TestGetCycleNode2() {
LinkNode* pnode;
FUNCTION;
LinkListInit(&pnode);
LinkListPushBack(&pnode, 'a');
LinkListPushBack(&pnode, 'b');
LinkListPushBack(&pnode, 'c');
LinkListPushBack(&pnode, 'e');
LinkListPushBack(&pnode, 'f');
LinkListPushBack(&pnode, 'g');
LinkListPushBack(&pnode, 'h');
LinkNode* cur = pnode;
while (cur->next) {
cur = cur->next;
}
cur->next = pnode->next->next->next;
LinkNode* MetNode = pnode->next->next->next->next;
LinkNode* EntryNode = GetCycleEntryNode2(pnode, MetNode);
printf("expect entry: e,actual: %c\n\n", EntryNode->data);
}
void TestHasCrossNode() {
//测试
//①两个单
LinkNode* pnode1;
LinkNode* pnode2;
FUNCTION;
LinkListInit(&pnode1);
LinkListInit(&pnode2);
LinkListPushBack(&pnode1, 'a');
LinkListPushBack(&pnode1, 'b');
LinkListPushBack(&pnode1, 'c');
LinkNode* pos_e = LinkListPushBack(&pnode1, 'e');
LinkListPushBack(&pnode1, 'f');
LinkListPushBack(&pnode1, 'g');
LinkListPushBack(&pnode1, 'h');
LinkNode* cur = pnode1;
while (cur->next) {
cur = cur->next;
}
//pnode1的环的入口点为e
cur->next = pnode1->next->next->next;
LinkListPushBack(&pnode2, 'a');
LinkListPushBack(&pnode2, 'b');
LinkListPushBack(&pnode2, 'c');
//pnode2->next->next->next = pos_e->next;
//pnode2->next->next->next->next = pos_e;
//两个单链表相交,交点为e
LinkNode* test = HasCrossNode(pnode1, pnode2);
//printf("expect e, actual:%c", test->data);
//②两个带环单链表,相交/不相交
//交点在入口点外
//printf("expect c,actual: %c", test->data);
//交点在环内
//printf("expect e, actual:%c",test->data);
//③一个带环一个不带环
}
int main() {
TestPushBack();
TestPopBack();
TestPushFront();
TestPopFront();
TestFind();
TestInsert();
TestAfterInsert();
TestErase();
TestRemove();
TestRemoveAll();
TestEmpty();
TestListSize();
TestReversePrint();
TestInsertBefore();
TestReverse();
//TestReverse2();
TestBubbleSort();
TestListMerge();
TestFindMid();
TestFindLastKNode();
TestEraseLastKNode();
TestLinkListMerge2();
TestCheckCycle();
TestGetCycleNode1();
TestGetCycleNode2();
TestHasCrossNode();
system("pause");
return 0;
}
有这个代码肯定有许多bug,毕竟 是第一次写,以后还会多写几遍的