//.h
#pragma once
typedef int DataType;
typedef struct Node
{
struct Node* _pNext;
DataType _data;
}Node,*pNode;
typedef struct CListNode
{
struct CListNode* _pNext;
struct CListNode* _pRandom;
DataType data;
}CListNode, *pCListNode;
void SListInit(pNode* pHead);// 链表初始化
pNode BuySListNode(DataType data); //创建新结点
void SListPushBack(pNode* pHead, DataType data);// 尾插
void printSList(pNode pHead);//打印单链表
void SListPopBack(pNode* pHead);//尾删
void SListPushFront(pNode* pHead, DataType data);//头插
void SListPopFront(pNode* pHead);//头删
pNode SListFind(pNode pHead, DataType data); //查找值为data的结点,返回该结点在链表中的位置
void SListInsert(pNode* pHead, pNode pos, DataType data);// 在链表pos位置后插入结点data
void SListErase(pNode* pHead, pNode pos);// 删除链表pos位置上的结点
void SListDestroy(pNode* pHead);// 销毁单链表
int SListSize(pNode pHead);// 求链表中结点的个数
void SListClear(pNode* pHead);// 将链表中的结点清空
pNode SListBack(pNode pHead);// 获取链表中的最后一个结点,返回该结点的地址
//
///
void PrintListFromTailHead(pNode pHead);// 从尾到头打印单链表
void DeleteNotTailNode(pNode pos);//删除无头单链表的非尾结点,要求:不能遍历
void InsertPosFront(pNode pos, DataType data);//在无头单链表POS位置前插入值为data的结点
void JosephCircle(pNode* pHead, const int M);//用单链表模拟实现约瑟夫环
void BubbleSort(pNode pHead);// 使用冒泡排序方法对单链表进行排序
void ReverseSList(pNode* pHead);// 单链表的逆置--三个指针
void ReverseSLiseTop(pNode pHead);// 单链表的逆置--头插法
pNode MergeSList(pNode pHead1, pNode pHead2);// 合并两个有序链表,合并之后依然有序
pNode FindMiddleNode(pNode pHead);// 查找链表的中间结点,要求只能遍历一次链表
pNode FindLastKNode(pNode pHead, int k);// 查找链表的倒数第K个结点,要求只能遍历链表一次
pNode DeleteLastKNode(pNode pHead, int k);// 删除链表的倒数第K个结点,要求只能遍历链表一次
int IsCrossWithoutCircle(pNode pHead1, pNode pHead2);// 判断单链表是否相交?链表不带环
pNode GetCrossNode(pNode pHead1, pNode pHead2);// 求不带环单链表相交交点
pNode IsCircle(pNode pHead);// 判断链表是否带环
int GetCircleLen(pNode pHead);// 求环的长度
pNode GetEnterNode(pNode pHead, pNode pMeetNode);// 求环的入口点
int IsListCrossWithCircle(pNode pHead1, pNode pHead2);// 判断链表是否带环,链表可能带环
void CListNodeInit(pCListNode* pHead);// 复杂链表初始化
pCListNode BuyCListNode(DataType data);// 复杂链表获取结点
void CListNodePushBack(pCListNode *pHead, DataType data);//复杂链表的尾插
pCListNode CopyComplexList(pCListNode pHead);// 复杂链表的复制
//.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"SListNode.h"
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
//初始化
void SListInit(pNode* pHead)
{
assert(pHead);
*pHead = NULL;
}
//创建新结点
pNode BuySListNode(DataType data)
{
pNode pNewNode = (pNode)malloc(sizeof(Node));
if (NULL==pNewNode)
{
return NULL;
}
else
{
pNewNode->_data = data;
pNewNode->_pNext = NULL;
}
return pNewNode;
}
//尾插
void SListPushBack(pNode* pHead, DataType data)
{
assert(pHead);
pNode pNewNode = BuySListNode(data);
pNode pCur =*pHead;
if (NULL==pCur)
{
*pHead= pNewNode;
return;
}
while (pCur->_pNext)
{
pCur = pCur->_pNext;
}
pCur->_pNext = pNewNode;
}
void printSList(pNode pHead)//打印单链表
{
pNode pCur = pHead;
while (pCur)
{
printf("%d-->", pCur->_data);
pCur = pCur->_pNext;
}
printf("NULL\n");
}
//尾删
void SListPopBack(pNode* pHead)
{
assert(pHead);
pNode pCur = *pHead;
if (NULL==pCur)
{
return;
}
//一个节点
if (NULL==pCur->_pNext)
{
pCur = NULL;
free(pCur);
return;
}
//多个节点
while (pCur->_pNext->_pNext)
{
pCur = pCur->_pNext;
}
free(pCur->_pNext);
pCur->_pNext = NULL;
}
//头插
void SListPushFront(pNode* pHead, DataType data)
{
assert(pHead);
pNode pNewNode = BuySListNode(data);
if (NULL==pNewNode)
{
return;
}
pNewNode->_pNext = *pHead;
*pHead = pNewNode;
}
//头删
void SListPopFront(pNode* pHead)
{
assert(pHead);
pNode pCur = *pHead;
if (NULL==*pHead)
{
return;
}
else
{
*pHead = pCur->_pNext;
free(pCur);
}
}
// 查找值为data的结点,返回该结点在链表中的位置
pNode SListFind(pNode pHead, DataType data)
{
assert(pHead);
pNode pCur = pHead;
while (pCur)
{
if (pCur->_data == data)
{
return pCur;
}
pCur = pCur->_pNext;
}
return NULL;
}
// 在链表pos位置后插入结点data
void SListInsert(pNode* pHead, pNode pos, DataType data)
{
assert(pHead);
pNode pCur = *pHead;
pNode pNewNode = BuySListNode(data);
if (NULL==pHead || NULL==pos)
{
return;
}
while (pCur)
{
if (pCur == pos)
{
pNewNode->_pNext = pos->_pNext;
pos->_pNext = pNewNode;
}
pCur = pCur->_pNext;
}
}
//删除链表pos位置上的结点
void SListErase(pNode* pHead, pNode pos)
{
assert(pHead);
pNode pCur = *pHead;
if (*pHead == NULL)
{
return;
}
if (pCur == pos)//一个结点
{
*pHead = pos->_pNext;
free(pos);
pos= NULL;
}
else
{
while (pCur && pCur->_pNext != pos)
{
pCur = pCur->_pNext;
}
if (pCur != NULL)
{
pCur->_pNext = pos->_pNext;
free(pos);
pos = NULL;
}
}
}
// 销毁单链表
void SListDestroy(pNode* pHead)
{
assert(pHead);
pNode pCur = *pHead;
while (pCur)
{
pCur = pCur->_pNext;
free(pCur);
pCur = NULL;
}
*pHead = NULL;
}
// 求链表中结点的个数
int SListSize(pNode pHead)
{
assert(pHead);
int count = 0;
pNode pCur = pHead;
while (pCur)
{
count++;
pCur = pCur->_pNext;
}
return count;
}
// 将链表中的结点清空
void SListClear(pNode* pHead)
{
assert(pHead);
pNode pCur = *pHead;
while (pCur)
{
pCur->_pNext = *pHead;
free(pCur);
}
free(*pHead);
}
//void SListClear(pNode* pHead)
//{
// assert(pHead);
// SListDestoy(pHead);
//}
// 获取链表中的最后一个结点,返回该结点的地址
pNode SListBack(pNode pHead)
{
assert(pHead);
pNode pCur = pHead;
if (NULL == pHead)
{
return;
}
while (pCur->_pNext)
{
pCur = pCur->_pNext;
}
return pCur;
}
/
//面试题
void PrintFromTailHead(pNode pHead)// 从尾到头打印单链表
{
if (pHead)
{
PrintFromTailHead(pHead->_pNext);
printf("%d-->", pHead->_data);
}
}
//删除无头单链表的非尾结点,要求:不能遍历
void DeleteNotTailNode(pNode pos)
{
pNode pCur = NULL;
if (NULL == pos || NULL == pos->_pNext)
{
return;
}
pCur = pos->_pNext;
pos->_data = pCur->_data;
pos->_pNext = pCur->_pNext;
free(pCur);
}
//在无头单链表POS位置前插入值为data的结点
void InsertPosFront(pNode pos, DataType data)
{
if (NULL == pos)
{
return;
}
pNode pNewpNode = BuySListNode(pos->_data);
pNewpNode->_pNext = pos->_pNext;
pos->_data = data;
pos->_pNext = pNewpNode;
}
//用单链表模拟实现约瑟夫环
void JosephCircle(pNode* pHead, const int M)
{
assert(pHead);
pNode pCur = NULL;
int count = 0;
//构环
pCur = *pHead;
while (pCur->_pNext)
{
pCur = pCur->_pNext;
}
pCur->_pNext = *pHead;
//删结点
pCur = *pHead;
while (pCur->_pNext!= pCur)
{
count = M;//报数
while (--count)
{
pCur = pCur->_pNext;
}
pCur->_data = pCur->_pNext->_data;
pCur->_pNext = pCur->_pNext->_pNext;
}
//解环
pCur->_pNext = NULL;
*pHead = pCur;
}
// 使用冒泡排序方法对单链表进行排序
//冒泡排序算法的运作如下:
//1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
//
//2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
//
//3.针对所有的元素重复以上的步骤,除了最后一个。
//
//4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
void BobbleSort(pNode pHead)
{
int i = 0;
int j = 0;
int ret = 0;
int tmp = 0;
pNode pCur = NULL;
if (NULL == pHead)
{
return;
}
ret = SListSize(pHead);
for (i = 0; i < ret - 1; i++)
{
pCur = pHead;
for (j = 0; j < ret - 1 - i; j++)
{
if (pCur->_data > pCur->_pNext->_data)
{
tmp = pCur->_data;
pCur->_data = pCur->_pNext->_data;
pCur->_pNext->_data = tmp;
}
pCur = pCur->_pNext;
}
}
}
// 单链表的逆置--三个指针
void ReverseSList(pNode* pHead)
{
assert(pHead);
pNode pPre = NULL;
pNode pCur = NULL;
pNode pNext = NULL;
if (NULL == *pHead || NULL==(*pHead)->_pNext)//边界检测
{
return;
}
pCur = *pHead;
while (pCur)
{
pNext=pCur->_pNext;
pCur->_pNext = pPre;
pPre = pCur;
pCur = pNext;
}
*pHead=pPre;
}
// 单链表的逆置--头插法
void ReverseSListTop(pNode pHead)
{
assert(pHead);
pNode pNewNode = NULL;
if (NULL == pHead)
{
return;
}
pNode pCur = pHead;
while (pCur)
{
SListPushFront(&pNewNode, pCur->_data);
pCur = pCur->_pNext;
}
return pNewNode;
}
// 合并两个有序链表,合并之后依然有序
pNode MergeSList(pNode pHead1, pNode pHead2)
{
pNode pNewNode = NULL;
pNode pTailNode = NULL;
pNode pCur1 = pHead1;
pNode pCur2 = pHead2;
if (NULL == pHead1)//链表1为空的话返回链表2
return pHead2;
if (NULL == pHead2)//链表2为空的话返回链表1
return pHead1;
//两个链表都不为空
if (pCur1->_data <= pCur2->_data)//比较两个头结点大小
{
pNewNode = pCur1;
pCur1 = pCur1->_pNext;
}
else
{
pNewNode = pCur2;
pCur2 = pCur2->_pNext;
}
pTailNode = pNewNode;
while(pCur1 && pCur2)//合并后面结点
{
if (pCur1->_data <= pCur2->_data)
{
pTailNode->_pNext = pCur1;
pCur1 = pCur1->_pNext;
pTailNode = pTailNode->_pNext;
}
else
{
pTailNode->_pNext = pCur2;
pCur2 = pCur1->_pNext;
pTailNode = pTailNode->_pNext;
}
}
if (NULL==pCur1)
{
pTailNode->_pNext = pCur2;
}
if (NULL==pCur2)
{
pTailNode->_pNext = pCur1;
}
return pNewNode;
}
// 查找链表的中间结点,要求只能遍历一次链表
pNode FindMiddleNode(pNode pHead)
{
assert(pHead);
pNode pFast = pHead;
pNode pSlow = pHead;
if (NULL == pHead)
{
return;
}
while (pFast && pFast->_pNext)
{
pSlow = pSlow->_pNext;
pFast = pFast->_pNext->_pNext;
}
return pSlow;
}
// 查找链表的倒数第K个结点,要求只能遍历链表一次
pNode FindLastKNode(pNode pHead, int k)
{
assert(pHead);
pNode pFast = pHead;
pNode pSlow = pHead;
if (NULL == pHead || k<0)
{
return;
}
while (k--)//让pFast先走k步
{
if (NULL == pFast)//k大于链表中结点的个数
{
return;
}
pFast = pFast->_pNext;
}
//两个指针同时走
while (pFast)
{
pSlow = pSlow->_pNext;
pFast = pFast->_pNext;
}
return pSlow;
}
// 删除链表的倒数第K个结点,要求只能遍历链表一次
pNode DeleteLastKNode(pNode pHead, int k)
{
assert(pHead);
pNode pCur = NULL;
pNode pCur1 = NULL;
pCur=FindLastKNode(pHead, k);
if (NULL == pHead)
{
return;
}
//if删除头结点
if (pCur == pHead)
{
pHead = pCur->_pNext;
free(pCur);
pCur = NULL;
return NULL;
}
//删除其它结点
else
{
pCur1 = pHead;
if (pCur1->_pNext != pCur)
{
pCur1 = pCur1->_pNext;
}
pCur1->_pNext = pCur->_pNext;
free(pCur);
pCur = NULL;
return NULL;
}
}
// 判断单链表是否相交?链表不带环
int IsCrossWithoutCircle(pNode pHead1, pNode pHead2)
{
pNode pCur1 = pHead1;
pNode pCur2 = pHead2;
int size = 0;
if (NULL == pHead1 || NULL == pHead2)
{
return;
}
size = SListSize(pHead1) - SListSize(pHead2);
if (size > 0)
{
while (size--)
{
pCur1 = pCur1->_pNext;
}
while (pCur1 && pCur2)
{
if (pCur1 == pCur2)
{
return pCur1;
}
pCur1 = pCur1->_pNext;
pCur2 = pCur2->_pNext;
}
return NULL;
}
else if (size < 0)
{
while (size++)
{
pCur2 = pCur2->_pNext;
}
while (pCur1 && pCur2)
{
if (pCur1 == pCur2)
{
return pCur1;
}
pCur1 = pCur1->_pNext;
pCur2 = pCur2->_pNext;
}
return NULL;
}
else
{
while (pCur1 && pCur2)
{
{
return pCur1;
}
pCur1 = pCur1->_pNext;
pCur2 = pCur2->_pNext;
}
return NULL;
}
}
// 求不带环单链表相交交点
pNode GetCrossNode(pNode pHead1, pNode pHead2)
{
pNode pCur = NULL;
pCur = IsCrossWithoutCircle(pHead1, pHead2);
return pCur;
}
// 判断链表是否带环
pNode IsCircle(pNode pHead)
{
assert(pHead);
pNode pFast = NULL;
pNode pSlow = NULL;
if (NULL == pHead)
{
return;
}
pFast = pHead;
pSlow = pHead;
while (pFast && pFast->_pNext)
{
pFast->_pNext->_pNext;
pSlow->_pNext;
if (pFast == pSlow)
{
return pSlow;
}
}
return NULL;
}
// 求环的长度
int GetCircleLen(pNode pHead)
{
assert(pHead);
pNode pMeetNode = IsCircle(pHead);
pNode pCur = pMeetNode;
if (NULL == pHead)
{
return;
}
int count = 0;
while (pCur->_pNext != pMeetNode)
{
count++;
pCur = pCur->_pNext;
}
return count;
}
// 求环的入口点
pNode GetEnterNode(pNode pHead, pNode pMeetNode)
{
assert(pHead);
pMeetNode = IsCircle(pHead);
pNode pCur = pHead;
if (NULL == pHead)
{
return;
}
while (pCur != pMeetNode)
{
pCur = pCur->_pNext;
pMeetNode = pMeetNode->_pNext;
}
return pCur;
}
// 判断链表是否带环,链表可能带环 ,相交返回交点
int IsListCrossWithCircle(pNode pHead1, pNode pHead2)
{
pNode pCur1 = IsCircle(pHead1);
pNode pCur2 = IsCircle(pHead2);
//两个链表都不带环
if (NULL == pCur1 && NULL == pCur2)
{
pNode pMeetNode = IsCrossWithoutCircle(pHead1, pHead2);
return pMeetNode;
}
//两个链表都带环(环内,环外)
else if (pCur1 != NULL && pCur2 != NULL)
{
pNode pMeetNode = NULL;
pNode pEnterNode1 = GetEnterNode(pHead1, pMeetNode);
pNode pEnterNode2 = GetEnterNode(pHead2, pMeetNode);
int count1 = 1;
int count2 = 1;
int size = 0;
pNode pCur3 = pHead1;
pNode pCur4 = pHead2;
//环外相交
if (pEnterNode1 == pEnterNode2)
{
while (pHead1 != pEnterNode1)
{
count1++;
pCur3 = pCur3->_pNext;
}
while (pHead2 != pEnterNode2)
{
count2++;
pCur4 = pCur4->_pNext;
}
size = count1 - count2;
if (size > 0)
{
while (size--)
{
pCur3 = pCur3->_pNext;
}
while (pCur3 && pCur4)
{
pCur3 = pCur3->_pNext;
pCur4 = pCur4->_pNext;
}
if (pCur3 == pCur4)
{
return pCur3;
}
return NULL;
}
else if (size < 0)
{
while (size++)
{
pCur4 = pCur4->_pNext;
}
while (pCur3 && pCur4)
{
pCur3 = pCur3->_pNext;
pCur4 = pCur4->_pNext;
}
if (pCur3 == pCur4)
{
return pCur3;
}
return NULL;
}
//环内相交
else
{
pNode p1 = pEnterNode1;
pNode p2 = pEnterNode2;
while(p1 != pEnterNode1)
{
p1 = p1->_pNext;
p2 = p2->_pNext->_pNext;
}
if (p1 == p2)
{
return p1;
}
return NULL;
}
}
}
else
{
return NULL;
}
}
void CListNodeInit(pNode* pHead)
{
assert(pHead);
*pHead = NULL;
}
pCListNode BuyCListNode(DataType data)// 复杂链表获取结点
{
pCListNode pNewNode = (pCListNode)malloc(sizeof(CListNode));
if (NULL == pNewNode)
{
return NULL;
}
else
{
pNewNode->_pNext = NULL;
pNewNode->_pRandom = NULL;
pNewNode->data = data;
}
return pNewNode;
}
void CListNodePushBack(pCListNode *pHead, DataType data)//复杂链表的尾插
{
assert(pHead);
pCListNode pNewNode = BuyCListNode(data);
pCListNode pCur = *pHead;
if (NULL == pCur)
{
*pHead = pNewNode;
return;
}
while (pCur->_pNext)
{
pCur = pCur->_pNext;
}
pCur->_pNext = pNewNode;
}
pCListNode CopyComplexList(pCListNode pHead)// 复杂链表的复制
{
pCListNode p1 = NULL;
pCListNode p2 = NULL;
pCListNode pCur = NULL;
pCListNode pNewNode = NULL;
pCListNode pNext = NULL;
if (NULL == pHead)
return NULL;
pCur = pHead;
while (pCur)
{
pNewNode = BuyCListNode(pCur->data);
pNewNode->_pNext = pCur->_pNext;
pCur->_pNext = pNewNode;
pCur = pNewNode->_pNext;
}
while (p1)
{
p1 = pHead;
p2 = p1->_pNext;
if (p1->_pRandom != NULL)
p2->_pRandom = p1->_pRandom->_pNext;
p1 = p2->_pNext;
}
pNewNode = pHead->_pNext;
p2 = pNewNode;
p1 = pHead;
//拆除
while (p2->_pNext)
{
pNext = p2->_pNext;
p1->_pNext = pNext;
p2->_pNext = pNext->_pNext;
p1 = pNext;
p2 = pNext->_pNext;
}
p1->_pNext = NULL;
p2->_pNext = NULL;
return pNewNode;
}
//test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"SListNode.h"
#include<stdio.h>
#include<stdlib.h>
void test1()
{
pNode pHead;
SListInit(&pHead);
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
printSList(pHead);
SListPopBack(&pHead);//尾删
printSList(pHead);
SListPopBack(&pHead);
printSList(pHead);
SListPopBack(&pHead);
printSList(pHead);
SListPopBack(&pHead);
printSList(pHead);
}
void test2()
{
pNode pHead;
SListInit(&pHead);
SListPushFront(&pHead, 1);//头插
SListPushFront(&pHead, 2);
SListPushFront(&pHead, 3);
SListPushFront(&pHead, 4);
SListPushFront(&pHead, 5);
printSList(pHead);
SListPopFront(&pHead);//头删
printSList(pHead);
SListPopFront(&pHead);
printSList(pHead);
SListPopFront(&pHead);
printSList(pHead);
SListPopFront(&pHead);
printSList(pHead);
}
void test3()
{
pNode pHead;
pNode pos = NULL;
SListInit(&pHead);
SListPushFront(&pHead, 1);//头插
SListPushFront(&pHead, 2);
SListPushFront(&pHead, 3);
SListPushFront(&pHead, 4);
SListPushFront(&pHead, 5);
printSList(pHead);
pos = SListFind(pHead, 3);//找到3的位置
printf("%d\n", pos->_data);
SListInsert(&pHead,pos,6);//在3元素的位置处插入元素6
printSList(pHead);
SListErase(&pHead,pos);//删除3元素位置处的元素
printSList(pHead);
SListDestroy(&pHead);
printSList(pHead);
}
void test4()//查找值为data的结点,返回该结点在链表中的位置
{
pNode pCur=NULL;
pNode pHead;
SListInit(&pHead);
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
printSList(pHead);
pCur=SListFind(pHead, 4);
printf("%p\n", pCur);
}
void test5()// 获取链表中的最后一个结点,返回该结点的地址
{
pNode pHead;
SListInit(&pHead);
pNode pCur = NULL;
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
printSList(pHead);
pCur = SListBack(pHead);
printf("%p\n", pCur);
}
void test6()//求链表中结点的个数
{
pNode pHead;
SListInit(&pHead);
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
printSList(pHead);
int count = SListSize(pHead);
printf("链表中节点个数为%d\n", count);
}
void test7()//从尾到头打印单链表
{
pNode pHead;
SListInit(&pHead);
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
printSList(pHead);
PrintFromTailHead(pHead);
}
void test8()//删除无头单链表的非尾结点,要求:不能遍历
{
pNode pHead;
SListInit(&pHead);
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
printSList(pHead);
DeleteNotTailNode(pHead);
printSList(pHead);
DeleteNotTailNode(pHead->_pNext);
printSList(pHead);
}
void test9()//在无头单链表POS位置前插入值为data的结点
{
pNode pHead;
SListInit(&pHead);
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
printSList(pHead);
InsertPosFront(pHead->_pNext,6);
printSList(pHead);
}
void test10()//用单链表模拟实现约瑟夫环
{
pNode pHead;
SListInit(&pHead);
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
printSList(pHead);
JosephCircle(&pHead,3);
printSList(pHead);
}
void test11()// 使用冒泡排序方法对单链表进行排序
{
pNode pHead;
SListInit(&pHead);
SListPushBack(&pHead, 4);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 1);
printSList(pHead);
BobbleSort(pHead);
printSList(pHead);
}
void test12()// 单链表的逆置--三个指针
{
pNode pHead;
SListInit(&pHead);
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
printSList(pHead);
ReverseSList(&pHead);
printSList(pHead);
}
void test13()// 单链表的逆置--头插法
{
pNode pHead;
SListInit(&pHead);
pNode pCur = NULL;
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
printSList(pHead);
pCur=ReverseSListTop(pHead);
printSList(pCur);
}
void test14()// 合并两个有序链表,合并之后依然有序
{
pNode pHead1;
pNode pHead2;
pNode ret = NULL;
SListInit(&pHead1);
SListPushBack(&pHead1, 1);//尾插
SListPushBack(&pHead1, 5);
SListPushBack(&pHead1, 3);
SListPushBack(&pHead1, 8);
printSList(pHead1);
SListInit(&pHead2);
SListPushBack(&pHead2, 6);//尾插
SListPushBack(&pHead2, 7);
SListPushBack(&pHead2, 2);
SListPushBack(&pHead2, 4);
printSList(pHead2);
ret=MergeSList(pHead1,pHead2);
printSList(ret);
}
void test15()// 查找链表的中间结点,要求只能遍历一次链表
{
pNode pHead;
SListInit(&pHead);
pNode ret = NULL;
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
printSList(pHead);
ret=FindMiddleNode(pHead);
printf("%d\n",ret->_data);
}
void test16()// 查找链表的倒数第K个结点,要求只能遍历链表一次
{
pNode pHead;
SListInit(&pHead);
pNode ret = NULL;
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
printSList(pHead);
ret = FindLastKNode(pHead,2);
printf("%d\n", ret->_data);
}
void test17()// 删除链表的倒数第K个结点,要求只能遍历链表一次
{
pNode pHead;
SListInit(&pHead);
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
printSList(pHead);
DeleteLastKNode(pHead, 2);
printSList(pHead);
}
void test18()// 判断单链表是否相交?链表不带环
{
pNode pHead1;
pNode pHead2;
SListInit(&pHead1);
SListPushBack(&pHead1, 1);//尾插
SListPushBack(&pHead1, 5);
SListPushBack(&pHead1, 3);
SListPushBack(&pHead1, 2);
printSList(pHead1);
SListInit(&pHead2);
SListPushBack(&pHead2, 6);//尾插
SListPushBack(&pHead2, 7);
SListPushBack(&pHead2, 2);
SListPushBack(&pHead2, 4);
printSList(pHead2);
IsCrossWithoutCircle(pHead1, pHead2);
}
void test19()// 求不带环单链表相交交点
{
pNode pHead1;
pNode pHead2;
pNode ret = NULL;
SListInit(&pHead1);
SListPushBack(&pHead1, 1);//尾插
SListPushBack(&pHead1, 5);
SListPushBack(&pHead1, 2);
SListPushBack(&pHead1, 8);
printSList(pHead1);
SListInit(&pHead2);
SListPushBack(&pHead2, 6);//尾插
SListPushBack(&pHead2, 7);
SListPushBack(&pHead2, 2);
SListPushBack(&pHead2, 4);
printSList(pHead2);
ret = GetCrossNode(pHead1, pHead2);
printf("%d\n", ret->_data);
}
void test20()// 判断链表是否带环
{
pNode pHead;
SListInit(&pHead);
pNode ret = NULL;
SListPushBack(&pHead, 1);
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
ret = IsCircle(pHead);
}
void test21()// 求环的长度
{
pNode pHead;
SListInit(&pHead);
pNode ret = NULL;
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
printSList(pHead);
ret = GetCircleLen(pHead);
}
void test22()// 求环的入口点
{
pNode pHead;
SListInit(&pHead);
pNode ret = NULL;
pNode pMeetNode = pHead;
SListPushBack(&pHead, 1);//尾插
SListPushBack(&pHead, 2);
SListPushBack(&pHead, 3);
SListPushBack(&pHead, 4);
SListPushBack(&pHead, 5);
printSList(pHead);
ret = GetEnterNode(pHead,pMeetNode);
printf("%d\n", ret->_data);
}
void test23()// 判断链表是否带环,链表可能带环
{
pNode pHead1;
pNode pHead2;
pNode ret = NULL;
SListInit(&pHead1);
SListInit(&pHead2);
SListPushBack(&pHead1, 1);
SListPushBack(&pHead1, 2);
SListPushBack(&pHead1, 3);
SListPushBack(&pHead1, 4);
SListPushBack(&pHead1, 5);
SListPushBack(&pHead2, 6);
SListPushBack(&pHead2, 7);
SListPushBack(&pHead2, 8);
SListPushBack(&pHead2, 9);
SListPushBack(&pHead2, 10);
ret = IsListCrossWithCircle(pHead1, pHead2);
}
void test24()
{
pCListNode pHead;
CListNodeInit(&pHead);
pCListNode ret = NULL;
CListNodePushBack(&pHead, 1);
CListNodePushBack(&pHead, 2);
CListNodePushBack(&pHead, 3);
CListNodePushBack(&pHead, 4);
ret = CopyComplexList(pHead);
}
int main()
{
//test1();//尾插 尾删
//test2();//头插 头删
//test3();//在3元素的位置处插入元素6 删除3元素位置处的元素
//test4();//查找值为data的结点,返回该结点在链表中的位置
//test5();// 获取链表中的最后一个结点,返回该结点的地址
//test6();//求链表中结点的个数
//test7();//从尾到头打印单链表
//test8();//删除无头单链表的非尾结点,要求:不能遍历
// test9();//在无头单链表POS位置前插入值为data的结点
//test10();//用单链表模拟实现约瑟夫环
//test11();// 使用冒泡排序方法对单链表进行排序
//test12();// 单链表的逆置--三个指针
//test13();// 单链表的逆置--头插法
//test14();// 合并两个有序链表,合并之后依然有序
//test15();// 查找链表的中间结点,要求只能遍历一次链表
//test16();// 查找链表的倒数第K个结点,要求只能遍历链表一次
//test17();// 删除链表的倒数第K个结点,要求只能遍历链表一次
//test18();// 判断单链表是否相交?链表不带环
//test19();// 求不带环单链表相交交点
//test20();// 判断链表是否带环
//test21();// 求环的长度
//test22();// 求环的入口点
//test23();// 判断链表是否带环,链表可能带环
test24();
system("pause");
return 0;
}
链表与顺序表区别:
1.顺序表支持随机访问,单链表不支持随机访问;
2.顺序表插入/删除数据效率很低,时间复杂度为O(N)(除尾插 尾删),单链表插入/删除效率更高,时间复杂度为O(1);
3.顺序表的CPU高速缓存效率更高,单链表CPU高速缓存效率低。