C语言单链表——之常见面试题目2

接上篇还是无头节点的:

实现的函数声明:

// 从头至尾打印单链表
void PrintListTailToHead(PSlist pHead);

// 链表的非头结点前插入元素data
void InsertNotHead(PSlist pHead, PSlist pos, Datatype data);

// 删除链表的非尾结点
void DelNotTailNode(PSlist pos);

// 查找链表的中间结点,要求只遍历一次链表
PSlist FindMidNode(PSlist pHead); //返回1return 2参数 3结构体打包返回
PSlist FindMidNode2(PSlist pHead);//偶数返回后一个


// 约瑟夫环问题
PSlist JosephCircle(PSlist pHead, int M);

// 单链表逆置:两种方法都实现:一、三个指针  二、尾插发
PSlist ReverseList(PSlist* pHead);

// 单链表排序:冒泡(优化版本)
void SortList(PSlist pHead);

// 查找链表的倒数第K个结点
PSlist FindLastKNode(PSlist pHead, int K,int size);

// 判断链表是否带环
PSlist HasCycle(PSlist pHead);

// 求环的长度
int GetCyleLen(PSlist pMeetNode);

// 合并两个已序单链表
PSlist MergeList(PSlist pL1, PSlist pL2);

//查找环的入口
PSlist FindEnterNode(PSlist pHead, PSlist pMeetMode);
//判断两个链表是否相交 判断尾节点
//y 前面不相同的个数相同
//v 
// y 前面节点个数不相同
//方法2:让他构成环求交点

// 两个链表是否相交(不带环)
int IsMeet(PSlist pos1, PSlist pos2);
//1都不带环 == Ismeet
//2有且只有一个带环  不相交 相当于3
//3两个都带环 M1 M2 相遇会出现M1 = M2 

// 两个链表是否相交,带环
int IsMeetwithcycle(PSlist pos1, PSlist pos2);

实现:

void PrintListTailToHead(PSlist pHead)
{
    if (pHead == NULL)
    {
        return;
    }
    else
    {
        PrintListTailToHead(pHead->next);
        printf("%d->", pHead->data);
    }
}

void InsertNotHead(PSlist pHead,PSlist pos, Datatype data)
{
    assert(pHead);
    assert(pos);
    PSlist pNew = BuyNode(pos->data);

    if (pos == pHead || pos == pHead->next)
    {
        return;
    }

    pos->data = data;
    pNew->next = pos->next;
    pos->next = pNew;

}

void DelNotTailNode(PSlist pos)
{
    PSlist pCur = pos->next;
    if (pos == NULL)
    {
        return;
    }
    if (pos->next == NULL)
    {
        return;
    }
    pos->data = pCur->data;
    pos->next = pCur->next;
    free(pCur);
    pCur->next = NULL;
}

PSlist FindMidNode(PSlist pHead)//偶数返回前一个
{
    if (pHead == NULL || pHead->next == NULL)
    {
        return NULL;
    }

    PSlist pSlow = pHead;
    PSlist pFast = pSlow->next;

    while (pFast && pFast->next)
    {
        pSlow = pSlow->next;

        pFast = pFast->next;
        pFast = pFast->next;
    }
    return pSlow;
}

PSlist FindMidNode2(PSlist pHead)//偶数返回后一个
{
    if (pHead == NULL || pHead->next == NULL)
    {
        return NULL;
    }
    PSlist pSlow = pHead;
    PSlist pFast = pSlow->next;
    while(pFast &&pFast->next)
    { 
        pSlow = pSlow->next;

        pFast = pFast->next;
        pFast = pFast->next;
    }
    pSlow = pSlow->next;
    return pSlow;
}


PSlist JosephCircle(PSlist pHead, int M)
{
    if (pHead == NULL || pHead->next == NULL || M <= 0)
    {
        return NULL;
    }
    PSlist pNode = NULL;
    int k = 0;
    while (pHead->next != pHead)//最后一个不进去
    {
        k = M;
        pNode = pHead->next;
        while (--k)
        {
            pHead = pHead->next;
            pNode = pNode->next;
        }
        pHead->data = pNode->data;
        pHead->next = pNode->next;
        free(pNode);
        pNode->next  = NULL;
    }

    return pHead;
}

void DestroyList(PSlist* pHead)
{
    assert(pHead);
    PSlist pCur = *pHead;
    PSlist pDel = NULL;
    if (pCur == NULL)
    {
        return;
    }
    while (pCur)
    {
        pDel = pCur;
        pCur = pCur->next;
        free(pDel);
        pDel->next = NULL;
    }

}

PSlist ReverseList(PSlist* pHead)
{
    assert(pHead);
    PSlist pCur = *pHead;
    PSlist pNewHead = pCur->next;
    pCur->next = NULL;
    PSlist pNode = NULL;


    while (pNewHead)
    {
        pNode = pNewHead;
        pNewHead = pNewHead->next;
        pNode->next = pCur;
        pCur = pNode;
    }
    pNewHead = NULL;
    return pCur;
}


void SortList(PSlist pHead)
{
    if (pHead == NULL && pHead->next == NULL)
    {
        return;
    }
    PSlist pCur =NULL;
    PSlist pTail =NULL;
    while (pHead != pTail)
    {
        pCur = pHead;
        pTail = pHead->next;
        while (pCur->next)//哎!跳不出去嘞
        {
            if (pCur->data > pTail->data)
                pCur->data ^= pTail->data ^= pCur->data ^= pTail->data;
            pCur = pTail;
            pTail = pTail->next;        

        }
        pTail = NULL;
    }
}

判断单链表有无环
///
int  HasCycle(PSlist pHead)
{
    PSlist pFast = pHead;
    PSlist pSlow = pHead;
    if (pHead == NULL)
    {
        return -1;
    }
    while (pFast && pFast->next)
    {
        pSlow = pSlow->next;
        pFast = pFast->next->next;
        if (pSlow == pFast)
        {
            return 1;
        }
    }
}


PSlist FindLastKNode(PSlist pHead, int K,int size)
{
    int i = 0;
    int M = K;
    if (K <= 0 && K > size)
    {
        return NULL;
    }
    PSlist pFast = pHead;
    PSlist pSlow = NULL;

    while (M-- && pFast->next != NULL)
    {
        pFast = pFast->next;
    }
    pSlow = pHead;
    while (pFast->next != NULL)
    {
        pFast = pFast->next;
        pSlow = pSlow->next;
    }

    return pSlow;
}

PSlist MergeList(PSlist pL1, PSlist pL2)
{
    if (pL1 == NULL || pL2 == NULL)
        return pL1 == NULL ? pL2 : pL1;

    PSlist cur = pL1;
    if (pL1->data > pL2->data)
    {
        cur = pL2;
        pL2 = pL2->next;
    }
    else
    {
        pL1 = pL1->next;
    }

    PSlist NewHead = cur;
    while (pL1 != NULL && pL2 != NULL)
    {
        if (pL1->data < pL2->data)
        {
            cur->next = pL1;
            pL1 = pL1->next;
        }
        else
        {
            cur->next = pL2;
            pL2 = pL2->next;
        }
        cur = cur->next;
    }
    if (pL1 != NULL)
        cur->next = pL1;
    else
        cur->next = pL2;

    return NewHead;
}
//
PSlist FindLastKNode(PSlist pHead, int K)
{
    if (K == 0 || pHead == NULL)
        return NULL;

    PSlist fast = BuyNode(-1);
    PSlist slow = fast;

    for (size_t i = 0; i < K - 1; ++i)
    {
        if (fast->next)
            fast = fast->next;
        else
        {
            return 0;
        }
    }

    while (fast->next)
    {
        slow = slow->next;
        fast = fast->next;
    }
    return slow;
}

int IsMeet(PSlist pos1, PSlist pos2)
{
    PSlist pNode1 = pos1;
    PSlist pNode2 = pos2;
    if (pos1 == NULL || pos2 == NULL)
    {
        return 0;
    }

    //y字型
    while (pNode1->next != NULL)
    {
        pNode1 = pNode1->next;
    }
    while (pNode2->next != NULL)
    {
        pNode2 = pNode1->next;
    }

    if (pNode1 == pNode2)
    {
        return 1;//相交
    }
    return 0;
}

int IsMeetwithcycle(PSlist pos1, PSlist pos2)
{
    PSlist pMeetpos1 = NULL;
    PSlist pMeetpos2 = NULL;

    PSlist pNode1 = pos1;
    PSlist pNode2 = pos2;

    if (pos1 == NULL || pos2 == NULL)
    {
        return 0;
    }

    pMeetpos1 = HasCycle(pos1);
    pMeetpos2 = HasCycle(pos2);
//都没有环
    if (pMeetpos1 == NULL || pMeetpos2 == NULL)
    {
        while (pNode1->next != NULL)
        {
            pNode1 = pNode1->next;
        }
        while (pNode2->next != pNode2)
        {
            pNode2 = pNode2->next;
        }
        if (pNode1 == pNode2)//L = nc-x 环足够大n可能等于1,环小n可能>1
        {
            return 1;
        }
        return 0;
    }
//两个都带环 M2是 M1的前一个(相遇点相同)
    if (pMeetpos1 != NULL && pMeetpos2 != NULL)
    {
        PSlist pNode = pMeetpos1;
        while(pNode->next!=pMeetpos1)
        {
            if (pMeetpos1 == pMeetpos2)
            {
                return 1;
            }

            pNode = pNode->next;
        }
        return 0;
    }
    return 0;
}
//PrintTailtoHead
void Fun4()
{
    PSlist slist;
    InitList(&slist);
    PushFront(&slist, 1);
    PushFront(&slist, 2);
    PushFront(&slist, 3);
    PushFront(&slist, 4);

    PrintListTailToHead(slist);
}
//InsertNotHead
void Fun5()
{
    PSlist slist;
    InitList(&slist);
    PushFront(&slist, 1);
    PushFront(&slist, 2);
    PushFront(&slist, 3);
    PushFront(&slist, 4);
    InsertNotHead(slist, Find(slist, 4), 7);
    PrintList(slist);
}
//DelNotTailNode
void Fun6()
{
    PSlist slist;
    InitList(&slist);
    PushBack(&slist, 1);
    PushBack(&slist, 2);
    PushBack(&slist, 3);
    PushBack(&slist, 4);

    DelNotTailNode(Find(slist,4));
    PrintList(slist);

}

void Fun7()
{
    PSlist slist;
    PSlist item = NULL;
    InitList(&slist);
    PushBack(&slist, 1);
    PushBack(&slist, 2);
    PushBack(&slist, 3);
    PushBack(&slist, 4);
    PushBack(&slist, 5);
    PushBack(&slist, 6);
    PushBack(&slist, 7);
    PushBack(&slist, 8);
    item = FindMidNode2(slist);

}
//约瑟夫环
void Fun8()
{
    PSlist slist;
    PSlist Tail= NULL;
    InitList(&slist);
    PushBack(&slist, 1);
    PushBack(&slist, 2);
    PushBack(&slist, 3);
    PushBack(&slist, 4);
    //构造环
    Tail = Find(slist, 4);
    Tail->next = slist;
    Tail = JosephCircle(slist, 3);

    //解开环
    Tail->next = NULL;
    DestroyList(&Tail);
}


void Fun9()
{
    PSlist slist;
    PSlist Tail = NULL;
    InitList(&slist);
    PushBack(&slist, 1);
    PushBack(&slist, 2);
    PushBack(&slist, 3);
    PushBack(&slist, 4);
    PrintList(slist);

    Tail = ReverseList(&slist);
    PrintList(Tail);
}

void Fun10()
{
    PSlist slist;
    PSlist Tail = NULL;
    InitList(&slist);
    PushBack(&slist, 4);
    PushBack(&slist, 3);
    PushBack(&slist, 2);
    PushBack(&slist, 1);
    PrintList(slist);                                   

    SortList(slist);
}

void Fun11()
{
    PSlist slist;
    PSlist pos1 = NULL;
    PSlist pos2 = NULL;

    InitList(&slist);
    PushBack(&slist, 1);
    PushBack(&slist, 2);
    PushBack(&slist, 3);
    PushBack(&slist, 4);
    PushBack(&slist, 5);
    PushBack(&slist, 6);
    PushBack(&slist, 7);
    PushBack(&slist, 8);
    PushBack(&slist, 9);

    //构造环
    pos1 = Find(slist, 9);
    pos2 = Find(slist, 5);
    pos1->next = pos2;
    pos1 = FindEnterNode(slist, HasCycle(slist));

}

void Fun12()
{
    PSlist slist;
    PSlist pos1 = NULL;
    PSlist pos2 = NULL;

    InitList(&slist);
    PushBack(&slist, 1);
    PushBack(&slist, 2);
    PushBack(&slist, 3);
    PushBack(&slist, 4);
    PushBack(&slist, 5);
    PushBack(&slist, 6);
    PushBack(&slist, 7);
    PushBack(&slist, 8);
    PushBack(&slist, 9);

    pos1 = Find(slist, 1);

}
int main()
{
//  int a[5] = { 5,4,3,2,1 };
//  sort(a, 5);
    //Fun1();
    //Fun2();
    //Fun3();
    //Fun4();
    //Fun5();
    //Fun6();
    //Fun7();
    //Fun8();
    //Fun9();
    Fun10();
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值