本博客继上一篇的基本操作之后的一些比较复杂的问题解决
// 逆序打印单链表
void PrintSListFromTail2Head(PNode pHead);
// 删除链表的非尾结点,要求:不能遍历链表
void DeleteListNotTailNode(PNode pos);
// 在链表pos位置前插入值到data的结点
void InesrtPosFront(PNode pos, DataType data);
// 查找链表的中间结点,要求只能遍历一次链表
PNode FindMiddleNode(PNode pHead);
// 查找链表的倒数第K个结点,要求只能遍历一次链表
PNode FindLastKNode(PNode pHead, int K);
// 删除链表的倒数第K个结点,要求只能遍历一次链表
PNode DeleteLastKNode(PNode pHead, int K);
// 用单链表实现约瑟夫环
void JosephCircle(PNode* pHead, const int M);
// 链表的逆置–三个指针
void ReverseSList(PNode* pHead);
// 链表的逆置–头插法
PNode ReverseSListOP(PNode pHead);
// 用冒泡排序思想对单链表进行排序
void BubbleSort(PNode pHead);
// 合并两个有序单链表,合并后依然有序
PNode MergeSList(PNode pHead1, PNode pHead2);
// 判断两个单链表是否相交—链表不带环
int IsSListCross(PNode pHead1, PNode pHead2);
// 求两个单链表相交的交点—链表不带环
PNode GetCorssNode(PNode pHead1, PNode pHead2);
List.h
#include<stdio.h>
#pragma once
#include<assert.h>
#include<stdlib.h>
typedef int DataType;
typedef struct Node
{
struct Node *Next;
DataType data;
}Node,*PNode;
typedef struct SCListNode //复杂链表
{
struct SCListNode* _pNext;
struct SCListNode* _random;
int _data;
}SCLNode;
// 链表的初始化
void SListInit(PNode* pHead);
// 尾插
void SListPushBack(PNode* pHead, DataType data);
// 尾删
void SListPopBack(PNode* pHead);
// 头插
void SListPushFront(PNode* pHead, DataType data);
// 头删
void SListPopFront(PNode* pHead);
// 在链表中查找值为data的元素,找到后返回值为data的结点
PNode SListFind(PNode pHead, DataType data);
// 在pos位置插入值为data的结点
void SListInsert(PNode* pHead, PNode pos, DataType data);
// 删除pos位置额结点
void SListErase(PNode* pHead, PNode pos);
// 获取链表中值data的结点
int SListSize(PNode pHead);
// 判断链表是否为空
int SListEmpty(PNode pHead);
// 销毁聊表
void SListDestroy(PNode* pHead);
//创建新的节点
PNode NewNode(DataType data);
//打印链表
void SListPrint(PNode pHead);
// 逆序打印单链表
void PrintSListFromTail2Head(PNode pHead);
// 删除链表的非尾结点,要求:不能遍历链表
void DeleteListNotTailNode(PNode pos);
// 在链表pos位置前插入值到data的结点
void InesrtPosFront(PNode pos, DataType data);
// 查找链表的中间结点,要求只能遍历一次链表
PNode FindMiddleNode(PNode pHead);
// 查找链表的倒数第K个结点,要求只能遍历一次链表
PNode FindLastKNode(PNode pHead, int K);
// 删除链表的倒数第K个结点,要求只能遍历一次链表
PNode DeleteLastKNode(PNode pHead, int K);
// 用单链表实现约瑟夫环
void JosephCircle(PNode* pHead, const int M);
// 链表的逆置--三个指针
void ReverseSList(PNode* pHead);
// 链表的逆置--头插法
PNode ReverseSListOP(PNode pHead);
// 用冒泡排序思想对单链表进行排序
void BubbleSort(PNode pHead);
// 合并两个有序单链表,合并后依然有序
PNode MergeSList(PNode pHead1, PNode pHead2);
// 判断两个单链表是否相交---链表不带环
int IsSListCross(PNode pHead1, PNode pHead2);
// 求两个单链表相交的交点---链表不带环
PNode GetCorssNode(PNode pHead1, PNode pHead2);
//复杂链表的复制
SCLNode* CopyComplexList(SCLNode* pHead);
List.c
#include"List.h"
void SListInit(PNode* pHead)
{
assert(pHead);
*pHead = NULL;
}
PNode NewNode(DataType data)
{
PNode pnewNode = (PNode)malloc(sizeof(Node));
if (NULL == pnewNode)
return NULL;
pnewNode->data = data;
pnewNode->Next = NULL;
return pnewNode;
}
void SListPushBack(PNode* pHead, DataType data)
{
assert(pHead);
PNode pnewNode = NULL;
pnewNode = NewNode(data);
if (pnewNode == NULL)
return;
if (*pHead == NULL)
*pHead = pnewNode;
else
{
PNode pCur = *pHead;
while (pCur->Next != NULL)
{
pCur = pCur->Next;
}
pCur->Next = pnewNode;
}
}
void SListPopBack(PNode* pHead)
{
assert(pHead);
if (NULL == *pHead)
return;
else if ((*pHead)->Next == NULL)
{
free(*pHead);
*pHead = NULL;
}
else
{
PNode pCur = *pHead;
while (pCur->Next != NULL)
{
pCur = pCur->Next;
}
free(pCur);
pCur = NULL;
}
}
void SListPrint(PNode pHead)
{
PNode pCur = NULL;
if (pHead == NULL)
return;
pCur = pHead;
while (pCur->Next)
{
printf("%d---->", pCur->data);
pCur=pCur->Next;
}
printf("NULL\n");
}
void SListPushFront(PNode* pHead, DataType data)
{
assert(pHead);
PNode newNode = NULL;
newNode = NewNode(data);
if (newNode == NULL)
return;
newNode->Next = *pHead;
*pHead = newNode;
}
void SListPopFront(PNode* pHead)
{
PNode pCur = NULL;
assert(pHead);
if (*pHead == NULL)
{
return;
}
else
{
pCur = (*pHead);
*pHead = (*pHead)->Next;
free(pCur);
}
}
PNode SListFind(PNode pHead, DataType data)
{
PNode pCur = NULL;
if (pHead == NULL)
return NULL;
pCur = pHead;
while (pCur)
{
if (pCur->data == data)
return pCur;
pCur = pCur->Next;
}
return NULL;
}
void SListInsert(PNode* pHead, PNode pos, DataType data)
{
PNode pnewnode = NULL;
assert(pHead);
if (*pHead == NULL || pos == NULL)
return;
pnewnode=NewNode(data);
if (NULL == pnewnode)
return;
pnewnode->Next = pos->Next;
pos->Next = pnewnode;
}
void SListErase(PNode* pHead, PNode pos)
{
PNode newnode = NULL;
assert(pHead);
if (*pHead == NULL || pos == NULL)
return;
else if ((*pHead)==pos)
SListPopFront(pHead);
else
{
newnode = *pHead;
while (newnode->Next != pos)
{
newnode = newnode->Next;
}
newnode->Next = pos->Next;
free(pos);
}
}
int SListSize(PNode pHead)
{
int count = 0;
if (pHead == NULL)
return 0;
while (pHead)
{
count++;
pHead = pHead->Next;
}
return count;
}
int SListEmpty(PNode pHead)
{
return !pHead;
}
void SListDestroy(PNode* pHead)
{
PNode pnew = NULL;
assert(pHead);
if (NULL == (*pHead))
return;
while (pnew)
{
pnew = *pHead;
*pHead = pnew->Next;
free(pnew);
}
}
void PrintSListFromTail2Head(PNode pHead)
{
if (pHead){
PrintSListFromTail2Head(pHead->Next);
printf("%d ", pHead->data);
}
}
//做法是将pos下一个节点删除,删除前将pos->Next->Data的值赋给pos->Data
void DeleteListNotTailNode(PNode pos)
{
PNode pDel;
if (pos == NULL || pos->Next == NULL)
return;
pDel = pos->Next;
pos->Next= pDel->Next;
pos->data = pDel->data;
free(pDel);
}
void InesrtPosFront(PNode pos, DataType data)
{
PNode pnew = NULL;
if (NULL == pos)
return;
pnew = NewNode(data);
if (NULL == pnew)
return;
pnew->Next = pos->Next;
pos->Next = pnew;
pnew->data = pos->data;
pos->data = data;
}
PNode FindMiddleNode(PNode pHead)
{
PNode pFast;
PNode pSlow;
if (NULL == pHead)
return NULL;
pFast = pHead;
pSlow = pHead;
while (pFast->Next&&pHead->Next->Next)
{
pFast = pFast->Next->Next;
pSlow = pSlow->Next;
}
return pSlow;
}
PNode FindLastKNode(PNode pHead, int K)
{
int count = 0;
PNode pFast;
PNode pSlow;
if (NULL == pHead)
return NULL;
pFast = pHead;
pSlow = pHead;
count = K;
while (count--)
{
pFast = pFast->Next;
}
while (pFast->Next)
{
pFast = pFast->Next;
pSlow = pSlow->Next;
}
return pSlow;
}
PNode DeleteLastKNode(PNode pHead, int K)
{
int count = 0;
PNode pFast;
PNode pSlow;
if (NULL == pHead)
return NULL;
pFast = pHead;
pSlow = pHead;
count = K;
while (count--)
{
pFast = pFast->Next;
}
while (pFast->Next)
{
pFast = pFast->Next;
pSlow = pSlow->Next;
}
pFast = pSlow->Next;
pSlow->Next = pFast->Next;
pSlow->data = pFast->data;
free(pFast);
}
void JosephCircle(PNode* pHead, const int M)
{
PNode pcur = NULL;
assert(pHead);
pcur = *pHead;
while (pcur!=pcur->Next)
{
int count = M;
pcur = pcur->Next;
PNode pDel = NULL;
while (--count)//count--,count=3,后置--,先用M的值判断一次,一共走了3次,所以必须用前置--,走2次,到三的位置的结点
{
pcur = pcur->Next;
}
//删除 (替换法删除:条件:非尾结点,因为是个环,所以没有尾结点)
pDel = pcur->Next;
pcur->Next = pDel->Next;
pcur->data = pDel->data;
free(pDel);
}
//如果把第一个结点删除了,把*ppHead的指向改一下
*pHead = pcur;
}
void ReverseSList(PNode* pHead)
{
PNode pcur = NULL;
PNode pnext = NULL;
PNode pre = NULL;
assert(pHead);
if (NULL == *pHead || NULL == (*pHead)->Next)//如果NULL == (*pHead)->Next,是一个节点的情况,不需要逆置
return;
pcur = *pHead;
while (pcur)
{
pnext = pcur->Next;//让pnext标记pcur的下一个节点
pcur->Next = pre;//pcur这个节点指向前一个节点
pre = pcur;//将前一个节点往后移
pcur = pnext;//将本节点往后移动
}
*pHead = pcur;
}
PNode ReverseSListOP(PNode pHead)
{
PNode pCur = pHead;
PNode pNext = NULL;
PNode pNewHead = NULL;
while (pCur)
{
pNext = pCur->Next;
pCur->Next = pNewHead;
pNewHead = pCur;
pCur = pNext;
}
return pNewHead;
}
void BubbleSort(PNode pHead)
{
PNode pCur = NULL;
PNode pNext = NULL;
PNode pTail = NULL;
int Flag = 0;
if (NULL == pHead || NULL == pHead->Next)
{
return;
}
while (pHead!=pTail)
{
pCur = pHead;
pNext = pCur->Next;
Flag = 0;
while (pNext!=pTail)
{
if (pCur->data > pNext->data)
{
DataType temp = pCur->data;
pCur->data = pNext->data;
pNext->data = temp;
Flag = 1;
}
pCur = pNext;
pNext = pNext->Next;
}
if (!Flag)
{
return;
}
pTail = pCur;
}
}
PNode MergeSList(PNode pHead1, PNode pHead2)
{
PNode pl1 = pHead1;
PNode pl2 = pHead2;
PNode pnew = NULL;
PNode pTail = NULL;
//判断两链表是否为空
if (NULL == pHead1 || NULL == pHead2) //等效注释部分
{
return (pHead1) ? pHead1 : pHead2;
}
//if (NULL == pHead1)
//{
// return pHead2;
//}
//if (NULL == pHead2)
//{
// return pHead1;
//}
if (pl1->data < pl2->data){
pnew = pl1;
pTail = pl1;
pl1 = pl1->Next;
}
else{
pnew = pl2;
pTail = pl2;
pl2 = pl2->Next;
}
while (pl1 && pl2)
{
if (pl1->data < pl2->data)
{
pTail->Next = pl1;
pl1 = pl1->Next;
}
else
{
pTail->Next = pl2;
pl2 = pl2->Next;
}
pTail = pTail->Next;
}
// 处理完两个链表,还剩下一个链表里有数据
if (pl1)
{
pTail->Next = pl1;
}
if (pl2)
{
pTail->Next = pl2;
}
return pnew;
}
// 判断单链表是否带环
PNode HasCircle(PNode pHead)
{
PNode pSlow = pHead;
PNode pFast = pHead;
while (pFast && pFast->Next)
{
pFast = pFast->Next->Next; //要先走,不能先判断
pSlow = pSlow->Next;
if (pFast == pSlow)
{
return pSlow; //返回相遇点
}
}
return NULL;
}
int IsSListCross(PNode pHead1, PNode pHead2)
{
PNode pTail1 = pHead1;
PNode pTail2 = pHead2;
if (NULL == pHead1 || NULL == pHead2)
{
return 0;
}
while (pTail1->Next == NULL)
{
pTail1 = pTail1->Next;
}
while (pTail2->Next == NULL)
{
pTail2 = pTail2->Next;
}
return pTail1 == pTail2;
}
PNode GetCorssNode(PNode pHead1, PNode pHead2)
{
size_t size1 = 0;
size_t size2 = 0;
PNode pCur1 = pHead1;
PNode pCur2 = pHead2;
int div = 0;
if (NULL == pHead1 || NULL == pHead2)
{
return NULL;
}
while (pCur1) //求两个链表的长度
{
size1++;
pCur1 = pCur1->Next;
}
while (pCur2) //求两个链表的长度
{
size2++;
pCur2 = pCur2->Next;
}
div = size1 - size2; //求两链表哪个长
if (div > 0) //长链表的头指针先走长的减去短的长度
{
while (div--) //后置-- 走了div步,需要走div步
{
pCur1 = pCur1->Next;
}
}
else
{
while (div++)
{
pCur2 = pCur2->Next;
}
}
while (pHead1 && pHead2) //两个头指针再一起走
{
if (pCur1 == pCur2) ////在 第一个链表 中找到 第一个 在 第二个链表 中出现的 结点
{
return pCur1;
}
pCur1 = pCur1->Next;
pCur2 = pCur2->Next;
}
return NULL;
}
SCLNode* BuySCLNode(int data)
{
SCLNode* pNewNode = (SCLNode*)malloc(sizeof(SCLNode));
pNewNode->_data = data;
pNewNode->_pNext = NULL;
pNewNode->_random = NULL;
return pNewNode;
}
SCLNode* CopyComplexList(SCLNode* pHead)
{
//1.在原链表每个结点后插入新结点
SCLNode* p1 = pHead;
SCLNode* pNewNode = NULL;
SCLNode* pNewHead = NULL;
if (pHead)
{
return NULL;
}
while (p1)
{
pNewNode = BuySCLNode(p1->_data);
pNewNode->_pNext = p1->_pNext;
p1->_pNext = pNewNode;
p1 = pNewNode->_pNext;
}
//2.给新插入结点的随机指针域赋值
p1 = pHead;
while (p1)
{
pNewNode = p1->_pNext;
if (NULL == p1->_random)
{
pNewNode->_random = NULL;
}
else if (p1->_random == p1)
{
pNewNode->_random = pNewNode;
}
else
{
pNewNode->_random = p1->_random->_pNext;
}
p1 = pNewNode->_pNext;
}
//3.将新结点从链表中拆下来
p1 = pHead;
pNewHead = p1->_pNext;
pNewNode = pNewHead;
while (pNewNode != NULL)
{
p1->_pNext = pNewNode->_pNext;
p1 = pNewNode;
pNewNode = pNewNode->_pNext;
}
return pNewHead;
}
void Test()
{
PNode list;
SListInit(&list);
SListPushBack(&list, 1);
SListPushBack(&list, 2);
SListPushBack(&list, 3);
SListPushBack(&list, 4);
SListPushBack(&list, 5);
SListPushBack(&list, 6);
SListPopFront(&list);
SListPushFront(&list, 1);
SListFind(list, 1);
//SListErase(&list, SListFind(list, 1));
SListPrint(list);
SListDestroy(&list);
}
void Test1()
{
PNode list;
SListInit(&list);
SListPushBack(&list, 1);
SListPushBack(&list, 2);
SListPushBack(&list, 3);
SListPushBack(&list, 4);
SListPushBack(&list, 5);
SListPushBack(&list, 6);
//DeleteListNotTailNode(SListFind(list, 1));
//InesrtPosFront(SListFind(list, 1), 0);
//InesrtPosFront(FindLastKNode(list,6), 0);
SListPrint(list);
}
test.c
#include"List.h"
int main()
{
Test1();
}