List.h
#ifndef List_h
#define List_h
struct ListNode
{
int data;
struct ListNode* pNext;
};
void InitList(struct ListNode** pHead); //初始化
struct ListNode* CreateNode(int data);//创建结点
void PushBack(struct ListNode** pHead, int data);//尾插
void PopBack(struct ListNode** pHead);//尾删
void PushFront(struct ListNode** pHead, int data);//头插
void PopFront(struct ListNode** pHead);//头删
struct ListNode* Find(struct ListNode* pHead, int data);//查找数据data
void Erase(struct ListNode** pHead, struct ListNode* pos);//删除pos位置节点
void Insert(struct ListNode** pHead, struct ListNode* pos, int data);//在pos位置插入节点data
void DestroyList(struct ListNode** pHead);//删除链表
void PrintList(struct ListNode* pHead);//打印链表
void PrintListTailToHead(struct ListNode* pHead);//从尾到头打印单链表
void InsertNotHead(struct ListNode* pos, int data);//在非头节点插入数据data
void DelNotTailNode(struct ListNode* pos);//删除不是尾节点的节点
struct ListNode* FindMidNode(struct ListNode* pHead);//查找中间节点
struct ListNode* JosephCircle(struct ListNode* pHead, int M);//约瑟夫环
void ReverseList(struct ListNode** pHead);//反转单链表
void SortList(struct ListNode* pHead);//排序单链表
struct ListNode* FindLastKNode(struct ListNode* pHead, int K);//查找倒数第K个节点
int GetCyleLen(struct ListNode* pMeetNode);//获得环长度
struct ListNode* HasCycle(struct ListNode* pHead);//判断链表是否有环
struct ListNode* MergeList(struct ListNode* pL1, struct ListNode* pL2);//合并两个单链表
struct ListNode* FindEnterNode(struct ListNode* pHead, struct ListNode* pMeetNode);//
int IsListCrose(struct ListNode* pL1, struct ListNode* pL2);//判断两个链表是否相交
int IsListCroseWithCycle(struct ListNode* pL1, struct ListNode* pL2);//判断两个链表是否环内相交
#endif /* List_h */
List.c
#include "List.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
void InitList(struct ListNode** pHead)//初始化
{
*pHead = NULL;
}
struct ListNode* CreateNode(int data)//创建结点
{
struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
if (node == NULL) {
return NULL;
}
node->data = data;
node->pNext = NULL;
return node;
}
void PushBack(struct ListNode** pHead, int data)//尾插
{
assert(pHead != NULL);
if (*pHead == NULL) {
*pHead = CreateNode(data);
return;
}
struct ListNode* node = *pHead;
while (node->pNext) {
node = node->pNext;
}
node->pNext = CreateNode(data);
}
void PopBack(struct ListNode** pHead)//尾删
{
assert(pHead != NULL);
if (*pHead == NULL) {
return;
} else if ((*pHead)->pNext == NULL) {
free(*pHead);
*pHead = NULL;
} else {
struct ListNode* pNode = *pHead;
struct ListNode* pPreNode = NULL;
while (pNode->pNext) {
pPreNode = pNode;
pNode = pNode->pNext;
}
pPreNode->pNext = pNode->pNext;
free(pNode);
pNode = NULL;
}
}
void PushFront(struct ListNode** pHead, int data)//头插
{
assert(pHead != NULL);
struct ListNode* node = CreateNode(data);
if (node != NULL) {
node->pNext = *pHead;
*pHead = node;
}
}
void PopFront(struct ListNode** pHead)//头删
{
assert(pHead != NULL);
if (*pHead == NULL) {
return;
}
struct ListNode* node = *pHead;
*pHead = (*pHead)->pNext;
free(node);
node = NULL;
}
struct ListNode* Find(struct ListNode* pHead, int data)//查找数据data
{
assert(pHead != NULL);
struct ListNode* node = pHead;
while (node) {
if (node->data == data) {
return node;
}
node = node->pNext;
}
return NULL;
}
void Erase(struct ListNode** pHead, struct ListNode* pos)//删除pos位置节点
{
assert(pHead != NULL);
assert(pos != NULL);
if (*pHead == pos) {
*pHead = pos->pNext;
free(pos);
pos = NULL;
return;
}
struct ListNode* node = *pHead;
while (node) {
if (node->pNext == pos) {
node->pNext = pos->pNext;
free(pos);
pos = NULL;
return;
}
node = node->pNext;
}
}
void Insert(struct ListNode** pHead, struct ListNode* pos, int data)//在pos位置插入节点data
{
assert(pHead != NULL);
assert(pos != NULL);
struct ListNode* newNode = CreateNode(pos->data);
if (newNode != NULL) {
newNode->pNext = pos->pNext;
pos->pNext = newNode;
pos->data = data;
}
}
void DestroyList(struct ListNode** pHead)//删除链表
{
assert(pHead != NULL);
struct ListNode* delNode = NULL;
while (*pHead) {
delNode = *pHead;
*pHead = (*pHead)->pNext;
free(delNode);
delNode = NULL;
}
}
void PrintList(struct ListNode* pHead)//打印链表
{
struct ListNode* node = pHead;
while (node != NULL) {
printf("%d->",node->data);
node = node->pNext;
}
printf("NULL\n");
}
void PrintListTailToHead(struct ListNode* pHead)//从尾到头打印单链表
{
if (pHead != NULL) {
PrintListTailToHead(pHead->pNext);
printf("%d ",pHead->data);
}
}
void InsertNotHead(struct ListNode* pos, int data)//在非头节点插入数据data
{
assert(pos != NULL);
struct ListNode* pNewNode = CreateNode(pos->data);
if (pNewNode != NULL) {
pNewNode->pNext = pos->pNext;
pos->pNext = pNewNode;
pos->data = data;
}
}
void DelNotTailNode(struct ListNode* pos)//删除不是尾节点的节点
{
assert(pos != NULL);
assert(pos->pNext != NULL);
struct ListNode* pDelNode = pos->pNext;
pos->data = pos->pNext->data;
pos->pNext = pos->pNext->pNext;
free(pDelNode);
pDelNode = NULL;
}
struct ListNode* FindMidNode(struct ListNode* pHead)//查找中间节点
{
assert(pHead != NULL);
struct ListNode* pfast = pHead;
struct ListNode* pslow = pHead;
while (pfast != NULL && pfast->pNext != NULL) {
pfast = pfast->pNext->pNext;
pslow = pslow->pNext;
}
return pslow;
}
/*
*约瑟夫环:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,
*数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依次规律重复下去,直到圆桌周围的人全部出列
*/
struct ListNode* JosephCircle(struct ListNode* pHead, int M)//约瑟夫环
{
struct ListNode* pNode = pHead;
struct ListNode* pDelNode;
int K = M;
if (pHead == NULL || M <= 0) {
return NULL;
}
while (pNode->pNext != pNode) {
K = M;
while (--K) {
pNode = pNode->pNext;
}
pDelNode = pNode->pNext;
pNode->data = pDelNode->data;
pNode->pNext = pDelNode->pNext;
free(pDelNode);
}
return NULL;
}
void ReverseList(struct ListNode** pHead) //反转单链表
{
struct ListNode* pNewNode = NULL;
struct ListNode* pPreNode = NULL;
struct ListNode* pNode = *pHead;
if (*pHead == NULL || (*pHead)->pNext == NULL)
return;
while (pNode) {
pPreNode = pNode;
pNode = pNode->pNext;
pPreNode->pNext = pNewNode;
pNewNode = pPreNode;
}
*pHead = pNewNode;
}
void SortList(struct ListNode* pHead) //排序单链表
{
struct ListNode* pTailNode = NULL;
struct ListNode* pNode = NULL;
struct ListNode* pPreNode = NULL;
if (pHead == NULL)
return;
while(pHead != pTailNode) {
pNode = pHead;
while(pNode->pNext != pTailNode) {
pPreNode = pNode;
pNode = pNode->pNext;
if (pPreNode->data > pNode->data) {
int data = pPreNode->data;
pPreNode->data = pNode->data;
pNode->data = data;
}
}
pTailNode = pNode;
}
}
struct ListNode* FindLastKNode(struct ListNode* pHead, int K) //查找倒数第K个节点
{
if (pHead == NULL || K <= 0)
return NULL;
struct ListNode* pFast = pHead;
struct ListNode* pSlow = pHead;
while (K--) {
if(pFast == NULL)
return NULL;
pFast = pFast->pNext;
}
while (pFast) {
pFast = pFast->pNext;
pSlow = pSlow->pNext;
}
return pSlow;
}
int GetCyleLen(struct ListNode* pMeetNode) //获得环长度
{
int iLen = 1;
struct ListNode* pNode = pMeetNode;
if (NULL == pMeetNode) {
return 0;
}
while (pNode->pNext != pMeetNode) {
iLen++;
pNode = pNode->pNext;
}
return iLen;
}
struct ListNode* HasCycle(struct ListNode* pHead) //判断链表是否有环
{
struct ListNode* pSlow = pHead;
struct ListNode* pFast = pHead;
if (pHead == NULL) {
return NULL;
}
while (pFast && pFast->pNext) {
pSlow = pSlow->pNext;
pFast = pFast->pNext->pNext;
if (pSlow == pFast) {
return pSlow;
}
}
return NULL;
}
struct ListNode* MergeList(struct ListNode* pL1, struct ListNode* pL2) //合并两个单链表
{
struct ListNode* pNewHead = NULL;
struct ListNode* pL1Node = pL1;
struct ListNode* pL2Node = pL2;
struct ListNode* pNode = NULL;
struct ListNode* pTailNode = NULL;
if (pL1 == NULL) {
return pL2;
}
if (pL2 == NULL) {
return pL1;
}
if (pL1Node->data > pL2Node->data) {
pNode = pL2Node;
pL2Node = pL2Node->pNext;
} else {
pNode = pL1Node;
pL1Node = pL1Node->pNext;
}
pNewHead = pNode;
pTailNode = pNode;
while (pL1Node && pL2Node) {
if (pL1Node->data > pL2Node->data) {
pNode = pL2Node;
pL2Node = pL2Node->pNext;
} else {
pNode = pL1Node;
pL1Node = pL1Node->pNext;
}
pTailNode->pNext = pNode;
pTailNode = pTailNode->pNext;
}
if (pL1Node == NULL) {
pTailNode->pNext = pL2Node;
} else {
pTailNode->pNext = pL1Node;
}
return pNewHead;
}
struct ListNode* FindEnterNode(struct ListNode* pHead, struct ListNode* pMeetNode)
{
struct ListNode* pNode1 = pHead;
struct ListNode* pNodeM = pMeetNode;
if (pHead == NULL || pMeetNode == NULL) {
return NULL;
}
while (pNode1 != pNodeM) {
pNode1 = pNode1->pNext;
pNodeM = pNodeM->pNext;
}
return pNode1;
}
int IsListCrose(struct ListNode* pL1, struct ListNode* pL2) //判断两个链表是否相交
{
struct ListNode* pL1Node = pL1;
struct ListNode* pL2Node = pL2;
if (pL1 == NULL || pL2 == NULL) {
return 0;
}
while (pL1Node->pNext != NULL) {
pL1Node = pL1Node->pNext;
}
while (pL2Node->pNext != NULL) {
pL2Node = pL2Node->pNext;
}
if (pL1Node == pL2Node) {
return 1;
}
return 0;
}
int IsListCroseWithCycle(struct ListNode* pL1, struct ListNode* pL2) //判断两个带环链表是否相交
{
struct ListNode* pL1MeetNode = NULL;
struct ListNode* pL2MeetNode = NULL;
struct ListNode* pL1Node = pL1;
struct ListNode* pL2Node = pL2;
if (pL1 == NULL || pL2 == NULL) {
return 0;
}
pL1MeetNode = HasCycle(pL1);
pL2MeetNode = HasCycle(pL2);
// 两个都不带环
if (pL1MeetNode == NULL && pL2MeetNode == NULL) {
while (pL1Node->pNext != NULL) {
pL1Node = pL1Node->pNext;
}
while (pL2Node->pNext != NULL) {
pL2Node = pL2Node->pNext;
}
if (pL2Node == pL1Node) {
return 1;
}
return 0;
}
// 两个都带环
if (pL1MeetNode != NULL && pL2MeetNode != NULL) {
struct ListNode* pNode = pL1MeetNode;
while (pNode->pNext != pL1MeetNode) {
if (pL2MeetNode == pNode) {
return 1;
}
pNode = pNode->pNext;
}
// 假如 M1 和 M2 相连,M2 在 M1 前面时,在循环内 M2 无法检测到
if (pNode == pL2MeetNode) {
return 1;
}
return 0;
}
return 0;
}
main.c
#include "List.h"
#include <stdio.h>
#include <stdlib.h>
void TestPushBack()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PushBack(&pHead, 6);
PushBack(&pHead, 7);
PrintList(pHead);
}
void TestPopBack()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PushBack(&pHead, 6);
PushBack(&pHead, 7);
PrintList(pHead);
PopBack(&pHead);
PopBack(&pHead);
PrintList(pHead);
}
void TestPushFront()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PrintList(pHead);
PushFront(&pHead,6);
PushFront(&pHead,7);
PushFront(&pHead,8);
PushFront(&pHead,9);
PrintList(pHead);
}
void TestPopFront()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PrintList(pHead);
PopFront(&pHead);
PopFront(&pHead);
PrintList(pHead);
}
void TestFind()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PrintList(pHead);
struct ListNode* findNode = Find(pHead, 6);
if (findNode != NULL) {
printf("findNode address %p,data %d\n",findNode,findNode->data);
} else {
printf("not find!\n");
}
}
void TestErase()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PrintList(pHead);
struct ListNode* findNode = Find(pHead, 1);
Erase(&pHead, findNode);
PrintList(pHead);
}
void TestInsert()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PrintList(pHead);
struct ListNode* findNode = Find(pHead, 2);
Insert(&pHead, findNode, 6);
PrintList(pHead);
}
void TestDestroyList()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PrintList(pHead);
DestroyList(&pHead);
PrintList(pHead);
}
void TestPrintListTailToHead()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PrintList(pHead);
PrintListTailToHead(pHead);
}
void TestInsertNotHead()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PrintList(pHead);
struct ListNode* findNode = Find(pHead, 2);
InsertNotHead(findNode,6);
PrintList(pHead);
}
void TestDelNotTailNode()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PrintList(pHead);
struct ListNode* findNode = Find(pHead, 2);
DelNotTailNode(findNode);
PrintList(pHead);
}
void TestFindMidNode()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
struct ListNode* mid = FindMidNode(pHead);
printf("mid data %d\n",mid->data);
PushBack(&pHead, 6);
mid = FindMidNode(pHead);
printf("mid data %d\n",mid->data);
}
void TestJosephCircle()
{
struct ListNode* pHead;
struct ListNode* pTailNode = NULL;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PushBack(&pHead, 6);
PushBack(&pHead, 7);
PrintList(pHead);
pTailNode = Find(pHead, 7);
pTailNode->pNext = pHead;
pTailNode = JosephCircle(pHead, 2);
free(pTailNode);
}
void TestReverseList()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PrintList(pHead);
ReverseList(&pHead);
PrintList(pHead);
}
void TestSortList()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 6);
PushBack(&pHead, 4);
PushBack(&pHead, 1);
PushBack(&pHead, 9);
PushBack(&pHead, 2);
PushBack(&pHead, 7);
PushBack(&pHead, 0);
PushBack(&pHead, 3);
PushBack(&pHead, 5);
PushBack(&pHead, 8);
PrintList(pHead);
SortList(pHead);
PrintList(pHead);
}
void TestFindLastKNode()
{
struct ListNode* pHead;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PushBack(&pHead, 6);
PrintList(pHead);
struct ListNode* lastK = FindLastKNode(pHead,2);
printf("last K = %d\n",lastK->data);
}
void TestGetCyleLen()
{
struct ListNode* pHead;
struct ListNode* pos1;
struct ListNode* pos2;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PushBack(&pHead, 7);
PushBack(&pHead, 9);
PrintList(pHead);
/*---------构环---------*/
pos1 = Find(pHead, 9);
pos2 = Find(pHead, 5);
pos1->pNext = pos2;
/*---------------------*/
int len = GetCyleLen(pos2);
printf("cycle len = %d\n",len);
}
void TestHasCycle()
{
struct ListNode* pHead;
struct ListNode* pos1;
struct ListNode* pos2;
InitList(&pHead);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 4);
PushBack(&pHead, 5);
PushBack(&pHead, 6);
PushBack(&pHead, 7);
PushBack(&pHead, 9);
PrintList(pHead);
/*---------构环---------*/
pos1 = Find(pHead, 9);
pos2 = Find(pHead, 5);
pos1->pNext = pos2;
/*---------------------*/
struct ListNode* pNode = HasCycle(pHead);
if (pNode == NULL) {
printf("list not cycle\n");
} else {
printf("list has cycle,pNode->data = %d\n",pNode->data);
}
}
void TestMergeList()
{
struct ListNode* pList1;
struct ListNode* pList2;
InitList(&pList1);
PushBack(&pList1, 1);
PushBack(&pList1, 3);
PushBack(&pList1, 5);
PushBack(&pList1, 7);
PushBack(&pList1, 9);
PrintList(pList1);
InitList(&pList2);
PushBack(&pList2, 2);
PushBack(&pList2, 4);
PushBack(&pList2, 6);
PushBack(&pList2, 8);
PrintList(pList2);
struct ListNode* pList3 = MergeList(pList1, pList2);
PrintList(pList3);
}
int main(int argc, const char * argv[])
{
//TestPushBack();
//TestPopBack();
//TestPushFront();
//TestPopFront();
//TestFind();
//TestErase();
//TestInsert();
//TestDestroyList();
//TestPrintListTailToHead();
//TestInsertNotHead();
//TestDelNotTailNode();
//TestFindMidNode();
//TestJosephCircle();
//TestReverseList();
//TestSortList();
//TestFindLastKNode();
//TestGetCyleLen();
//TestHasCycle();
//TestMergeList();
return 0;
}