【数据结构】C语言单链表的后续操作


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,毕竟 是第一次写,以后还会多写几遍的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值