#include"LinkList.h"
PNode BuyNewNode(DateType date)
{
PNode NewNode=(PNode)malloc(sizeof(Node));
if(NewNode==NULL)
{
return NULL;
}
NewNode->date=date;
NewNode->next=NULL;
return NewNode;
}
void LinkListInit(PNode *ppHead)
{
assert(ppHead);
*ppHead=NULL;
}
void LinkListPushBack(PNode *ppHead,DateType date)
{
PNode cur=*ppHead;
PNode newNode=BuyNewNode(date);
assert(ppHead);
if(cur==NULL)
{
*ppHead=newNode;
return ;
}
while(cur->next)
{
cur=cur->next;
}
cur->next=newNode;
}
void PrintLinkList(PNode pHead)
{
//链表为空
if(pHead==NULL)
{
return;
}
while( pHead)
{
printf("%d---->",pHead->date);
pHead=pHead->next;
}
printf("\n");
}
void LinkListPopBack(PNode *ppHead)
{
PNode cur=*ppHead;
assert(ppHead);
//链表为空
if(cur==NULL)
{
return;
}
//链表为一个节点
if(cur->next==NULL)
{
free(cur);
cur=NULL;
return ;
}
//链表为多个节点
while(cur->next->next)
{
cur=cur->next;
}
free(cur->next);
cur->next=NULL;
}
void LinkListPushFront(PNode *ppHead, DateType date)
{
PNode newNode=BuyNewNode(date);
assert(ppHead);
//链表无节点
if(*ppHead==NULL)
{
return;
}
//链表不为空
newNode->next=*ppHead;
*ppHead=newNode;
}
void LinkListPopFront(PNode *ppHead)
{
PNode cur=*ppHead;
assert(ppHead);
//空链表
if(*ppHead=NULL)
{
return;
}
//非空链表
*ppHead=cur->next;
free(cur);
cur=NULL;
}
void LinkListPrintReverse(PNode pHead)
{
if(pHead==NULL)
{
return;
}
LinkListPrintReverse(pHead->next);
printf("%d-->",pHead->date);
return ;
}
PNode SListFind(PNode pHead, DateType date)
{
PNode cur=pHead;
//链表为空
if(NULL==pHead)
{
return NULL;
}
//链表不为空
while(cur)
{
if(cur->date==date)
{
return cur;
}
cur=cur->next;
}
return NULL;
}
void SListInsert(PNode* ppHead, PNode pos, DateType date)
{
PNode cur;
assert(ppHead);
cur= BuyNewNode(date);
if(cur==NULL)
{
return ;
}
cur->next=pos->next;
pos->next=cur;
}
void SListErase(PNode* ppHead, PNode pos)
{
PNode cur=*ppHead;
assert(ppHead);
//链表为空
if(NULL==cur)
{
return;
}
//链表有一个节点
if((NULL==cur->next)&&(pos==cur))
{
free(cur);
cur=NULL;
*ppHead=NULL;
return;
}
//链表有多个节点
while((cur->next!=pos)&&(cur->next!=NULL))
{
cur=cur->next;
}
//找到了
if(cur->next==pos)
{
cur->next=pos->next;
free(pos);
pos=NULL;
}
if(cur->next==NULL)
{
printf("找不到!\n");
}
}
void SListDestroy(PNode* ppHead)
{
PNode cur=*ppHead;
PNode cur1=NULL;
assert(ppHead);
while(cur)
{
cur1=cur;
cur=cur->next;
free(cur1);
}
free(cur);
free(*ppHead);
}
int SListSize(PNode pHead)
{
int count =0;
PNode cur=pHead;
while(cur)
{
cur=cur->next;
count++;
}
return count;
}
void SListClear(PNode* ppHead)
{
PNode cur=*ppHead;
PNode cur1=NULL;
assert(ppHead);
while(cur)
{
cur1=cur;
cur=cur->next;
free(cur1);
}
}
PNode SListBack(PNode pHead)
{
PNode cur=pHead;
if(pHead=NULL)
{
return NULL;
}
while(cur->next)
{
cur=cur->next;
}
return cur;
}
// 从尾到头打印单链表
void PrintListFromTail2Head(PNode pHead)
{
if(NULL==pHead)
{
return ;
}
else
{
PrintListFromTail2Head(pHead->next);
printf("%d--->",pHead->date);
}
}
// 在无头单链表pos位置前插入值为结点data的结点
void InsertPosFront(PNode* ppHead,PNode pos, DateType date)
{
int tmp=0;
PNode tmp1=NULL;
assert(ppHead);
//2,将新节点插入POS的后面
SListInsert( ppHead, pos, date);
//3,将pos与新节点进行交换
tmp=pos->date;
pos->date=pos->next->date;
pos->next->date=tmp;
}
void JosephCircle(PNode* ppHead, const int M)
{
PNode cur2=NULL;
int count=0;
PNode cur1=NULL;
PNode cur=*ppHead;
assert(ppHead);
//约瑟夫环
cur1=SListBack(*ppHead);//找到最后一个节点的地址
cur1->next=cur;
//报数 删除节点
while(cur!=cur->next)
{
count=M;
while(--count)
{
cur=cur->next;
}
cur2=cur->next;
cur->date=cur2->date;
cur->next=cur2->next;
free(cur2);
}
*ppHead=cur;
//解环
/* cur->next=NULL;*/
cur->next=NULL;
}
// 删除无头单链表的非尾结点,要求:不能遍历链表
void DeleteNotTailNode(PNode pos)
{
PNode cur=pos->next;
if(NULL==pos)
{
return ;
}
assert(pos->next);
pos->date=cur->date;
pos->next=cur->next;
free(cur);
cur=NULL;
}
void BubbleSort(PNode pHead)
{
PNode pPerCur=NULL;
PNode pCur=NULL;
PNode pTail=NULL;
int tmp=0;
pPerCur=pHead;
pCur=pHead->next;
if(pHead==NULL||pHead->next==NULL)
{
printf("节点不够,无法排序!\n");
return ;
}
while(pHead->next!=pTail)
{
int Ischange=0;
pPerCur=pHead;
pCur=pHead->next;
while(pCur!=pTail)
{
if(pPerCur->date>pCur->date)
{
tmp=pCur->date;
pCur->date=pPerCur->date;
pPerCur->date=tmp;
}
pPerCur= pCur;
pCur= pCur->next;
Ischange=1;
}
if(!Ischange)
{
return ;
}
pTail=pPerCur;
}
}
// 单链表的逆序---三个指针
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL || pHead->next==NULL)
{
return pHead;
}
ListNode* pPer=NULL;
ListNode* pCur=pHead;
ListNode* pAft=NULL;
while(pCur)
{
pAft=pCur->next;
pCur->next=pPer;
pPer=pCur;
pCur=pAft;
}
return pPer;
}
// 单链表的逆序---使用递归法
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL || pHead->next==NULL) //条件一仅处理头节点为空情况,
{
return pHead;
}
ListNode* newHead=ReverseList(pHead->next);//这个返回值仅用来返回头结点
pHead->next->next=pHead;
pHead->next=NULL;
return newHead;
}
// 判断两个单链表是否相交---链表不带环
int IsCrossWithoutCircle(PNode pHead1, PNode pHead2)
{
PNode pCur1;
PNode pCur2;
if(pHead1==NULL||pHead2==NULL)
{
return -1;//无交点
}
pCur1=SListBack(pHead1);
pCur2=SListBack(pHead2);
if(pCur1==pCur2)
{
return 0;//表示有交点
}
return -1;//无交点
}
// 如果相交 获取交点
PNode GetCrossNode(PNode pHead1, PNode pHead2)
{
int ret1=0;
int ret2=0;
int retsub=0;
int ret=0;
// 判断两个单链表是否相交---链表不带环
ret=IsCrossWithoutCircle( pHead1, pHead2);
if(ret!=0)
{
printf("不相交 !\n");
return NULL;
}
// 求链表中结点的个数
ret1=SListSize(pHead1);
ret2=SListSize(pHead2);
retsub=ret1-ret2;
if(retsub>0)//链表1长
{
while(retsub)
{
pHead1=pHead1->next;
retsub--;
}
}
if(retsub<0)//链表2长
{
while(retsub++)
{
pHead2=pHead2->next;
}
}
while(pHead1!=pHead2)//寻找交点
{
pHead1=pHead1->next;
pHead2=pHead2->next;
}
return pHead1;
}
//判断一个链表是否带环,若带环,求入环点
PNode IsLoopAndEnterNode(PNode pHead)
{
PNode pFast=pHead;
PNode pSlow=pHead;
PNode pCross=NULL;
while(pFast&&pFast->next)//快慢指针,快的走两步,慢的走一步
//如果无环呢 所以必须判断pFast是否为空
{
pFast=pFast->next->next;
pSlow=pSlow->next;
if(pFast==pSlow)
{
break;
}
}
if(pFast!=pSlow)//不知道是有环退出还是无环退出,所以进行判断
{
return NULL;
}
//因为交点到入点的距离和起点到入点的距离相同
pCross=pFast;//将将交点赋给pCross
pSlow=pHead;//将起点赋给pSlow
while(pCross!=pSlow)//相同速度跑
{
pCross=pCross->next;
pSlow=pSlow->next;
}
return pSlow;
}
// 合并两个有序链表,合并起来依然要有序
PNode MergeSList(PNode pHead1, PNode pHead2)
{
PNode pCur1=pHead1;
PNode pCur2=pHead2;
PNode TailNode=NULL;//标记指针
PNode NewNode=NULL;//新链表
if(pCur2==NULL||pCur1==NULL)
{
return NULL==pCur1?pCur2:pCur1;//1为空返回2的指针,2为空返回1的指针
}
if(pCur1->date>pCur2->date)
{
TailNode=pCur2;
pCur2=pCur2->next;
}
else
{
TailNode=pCur1;
pCur1=pCur1->next;
}
NewNode=TailNode;
//因为最后需要返回头指针,所以需要在循环外标记好
while(pCur2!=NULL&&pCur1!=NULL)//1或2 移动到空了 就退出
{
if(pCur1->date>pCur2->date)
{
TailNode->next=pCur2;
pCur2=pCur2->next;
}
else
{
TailNode->next=pCur1;
pCur1=pCur1->next;
}
TailNode=TailNode->next;
}
if((pCur2==NULL)&&(pCur1!=NULL))//退出之后 让没有到空的链表直接连接到新链表上
{
TailNode->next=pCur1;
}
else
{
TailNode->next=pCur2;
}
//排序完成,下面进行返回,不知道第一个节点的地址,要判断
return NewNode;
}
// 查找链表的中间结点,要求只能遍历一次链表
PNode FindMiddleNode(PNode pHead)
{
PNode pFast=pHead;
PNode pSlow=pHead;
PNode pPer=NULL;
while(pFast&&pFast->next)
{
pFast=pFast->next->next;
pPer=pSlow;
pSlow=pSlow->next;
}
//如果节点有偶数个,要求得到前面的节点
if(!pFast)
{
return pPer;
}
return pSlow;
}
// 查找链表的倒数第K个结点
PNode FindLastKNode(PNode pHead, int K)
{
PNode pFast=pHead;
PNode pSlow=pHead;
PNode pPer=NULL;
//假设倒数第k个节点 存在
//若需判断,有查看节点个数的函数,大于k即可
while(--K)
{
pFast=pFast->next;
}
while(pFast->next)
{
pFast=pFast->next;
pSlow=pSlow->next;
}
return pSlow;
}
// 判断链表是否相交,链表可能带环
int IsListCrossWithCircle(PNode pHead1, PNode pHead2)
{
PNode PMNode1;
PNode PMNode2;
PNode PBNode1;
PNode PBNode2;
if((pHead1==NULL)&&(pHead2==NULL))
{
return 0;
}
//1, 判断链表的带环情况
PMNode1=IsLoopAndEnterNode(pHead1);
PMNode2=IsLoopAndEnterNode(pHead2);
// 两个都不带环
if(PMNode1==NULL&&PMNode2==NULL)
{
PBNode1=SListBack(pHead1);
PBNode2=SListBack(pHead2);
if(PBNode1==PBNode2)//相交
{
return 1;
}
}
//两个都带环
if(PMNode1!=NULL&&PMNode2!=NULL)
{
//要防止找到自己而相等退出的情况
//处理一开始两个指针相等的情况
if(PMNode1==PMNode2)
{
return 2;
}
//直接从第二个节点开始
do{
PMNode1=PMNode1->next;
if(PMNode1==PMNode2)
{
return 2;
}
}while(PMNode1->next!=PMNode2);//如果下一个是本身就退出
}
//一个带环,,不会相交
return 0;
}