链表面试题大全

#include"list.h"
//买一个结点
pNode BuyNode(DataType d)
{
    pNode tmp=(pNode)malloc(sizeof(Node));
    if (tmp == NULL)
        exit(0);
    tmp->data = d;
    tmp->next = NULL;
    return tmp;
}

//销毁链表
void DestroyList(pList* pplist)
{
    pList cur=*pplist;
    pList del;
    assert(pplist);
    while (cur != NULL)
    {
        del = cur;
        cur = cur->next;
        free(del);
    }
    del = NULL;
    *pplist = NULL;
}

//尾加 用cur指针找到最后一个结点 然后将新结点添加到cur后
void PushBack(pList* pplist, DataType d)
{
    pList cur = *pplist;
    pList tmp;
    assert(pplist);
    tmp = BuyNode(d);
    if (*pplist == NULL)
    {
        *pplist = tmp;
    }
    else
    {
        while (cur->next)
        {
            cur = cur->next;
        }
        cur->next = tmp;
    }
}


//尾删
void PopBack(pList* pplist)
{
    assert(pplist);
    if (*pplist == NULL)
    {
        return;
    }
    else if((*pplist)->next== NULL)
    {
        free(*pplist);
        *pplist = NULL;
    }
    else 
    {
        pList del = *pplist;
        while (del->next->next)
        {
            del = del->next;
        }
        free(del->next);
        del->next= NULL;
    }
}



//头加
void PushFront(pList* pplist, DataType d)
{
    pList tmp;
    assert(pplist);
    tmp = BuyNode(d);
    if (*pplist == NULL)
    {
        *pplist = tmp;
    }
    else
    {
        tmp->next = (*pplist);
        (*pplist) = tmp;
    }
}


//头删
void PopFront(pList* pplist)
{
    pList del = *pplist;
    assert(pplist);
    if (*pplist == NULL)
        return;
    else
    {
        del = *pplist;
        (*pplist) = (*pplist)->next;
        free(del);
        del = NULL;
    }
}
//打印
void PrintList(pList plist)
{
    pList tmp=plist;
    if (plist == NULL)
        return;
    else
    {
        while (tmp->next)
        {
            printf("%d->", tmp->data);
            tmp = tmp->next;
        }
        printf("%d\n", tmp->data);
    }
}


//得到链表长度
int GetListLength(pList plist)
{
    pList cur = plist;
    int ret=0;
    if (plist != NULL)
    {
        while (cur)
        {
            ret++;
            cur = cur->next;
        }
    }
        return ret;
}

//按值查询,返回结点地址
pNode Find(pList plist, DataType d)
{

    if (plist == NULL)
        return NULL;
    else
    {
        pList tmp = plist;
        while (tmp&&tmp->data != d)
        {
            tmp = tmp->next;
        }
        return tmp;
    }
}

//按地址插入
void Insert(pList* pplist, pNode pos, DataType d)
{
    pList cur = *pplist;
    assert(pplist);
    if (pos == NULL)
    {
        return;
    }
    else
    {
        while (cur&&cur!= pos)
        {
            cur = cur->next;
        }
        if (cur == pos)
        {
            pList tmp = BuyNode(d);
            tmp->next = pos->next;
            pos->next=tmp;
        }
    }
}

//按地址删除
void Erase(pList *pplist, pNode pos)
{
    pList cur = *pplist;
    assert(pplist);
    if (pos == NULL)
    {
        return;
    }
    else
    {
        if (*pplist == NULL)
            return;
        else
        {
            //删除第一个
            if (*pplist == pos)
            {
                (*pplist) = (*pplist)->next;
                free(pos);
                pos = NULL;
            }
            else
            {
                while (cur->next&&cur->next != pos)
                {
                    cur = cur->next;
                }
                if (cur->next == pos)
                {
                    cur->next = cur->next->next;
                    free(pos);
                    pos = NULL;
                }
            }
        }
    }
}

//按值移除
void Remove(pList* pplist, DataType d)
{
    pList cur=*pplist;
    pList del;
    assert(pplist);
    if (*pplist == NULL)
        return;
    else
    {
        //删除第一个
        if ((*pplist)->data == d)
        {
            del = *pplist;
            (*pplist) = (*pplist)->next;
            free(del);
            del = NULL;
        }
        else
        {
            while (cur->next&&cur->next->data != d)
            {
                cur = cur->next;
            }
            if (cur->next != NULL)
            {
                del = cur->next;
                cur->next = cur->next->next;
                free(del);
                del = NULL;
            }
        }
    }
}

//移除所有这样的值
void RemoveAll(pList* pplist, DataType d)
{
    pList cur ;
    pList cur2 = *pplist;
    pList del;
    assert(pplist);
    if (*pplist == NULL)
        return;
    while (cur2)
    {
        if ((*pplist)->data == d)
        {
            del = *pplist;
            *pplist = (*pplist)->next;
            //把头指针移动到新的头
            cur2 = *pplist;
            free(del);
            del = NULL;
        }
        else
        {
            cur = cur2;
            while (cur->next&&cur->next->data != d)
            {
                cur = cur->next;
            }
            if (cur->next != NULL)
            {
                del = cur->next;
                cur->next = cur->next->next;
                cur2 = cur;
                free(del);
                del = NULL;
            }
            else
            {
                //执行这条语句证明再没有需要删除的东西了,所以退出循环
                cur2 = NULL;
            }
        }
    }
}

//面试题
//逆序打印单项链表====非递归方法
void PrintTailToHead(pList plist)
{
    pList tail = NULL;
    pList cur=plist;
    if (plist == NULL)
        return;
    else
    {
        while (cur != tail)
        {
            while (cur->next != tail)
            {
                cur = cur->next;
            }
            printf("%d ", cur->data);
            tail = cur;
            cur = plist;
        }
    }
}
//删除无头非尾结点
void DelNodeNotTail(pNode pos)
{
    pList del;
    if (pos == NULL)
        return;
    else
    {
        del = pos->next;
        pos->data = pos->next->data;
        pos->next = pos->next->next;
        free(del);
        del = NULL;
    }
}
//插入结点
void InsertNode(pNode pos, DataType d)
{
    pList tmp;
    if (pos == NULL)
        return;
    else
    {
        tmp = BuyNode(pos->data);
        tmp->next = pos->next;
        pos->next = tmp;
        pos->data = d;
    }
}

//环
void JosephusCycle(pList* pplist, int k)
{
    pList del;
    pList cur = *pplist;
    int count=0;
    assert(pplist);
    if (*pplist == NULL)
        return;
    else
    {
        while (cur != cur->next)
        {
            count++;
            if (count == k)
            {
                del = cur->next;
                cur->data = cur->next->data;
                cur->next = cur->next->next;
                free(del);
                del = NULL;
                count = -1;
            }
            cur = cur->next;
        }
        *pplist = cur;
    }
}

//逆置链表
void ReverseList(pList* pplist)
{
    pList tmp1;
    pList tmp2;
    pList tmp3;
    assert(pplist);
    if ((*pplist) == NULL || (*pplist)->next == NULL)
        return;
    else
    {
        tmp1 = *pplist;
        tmp2 = tmp1->next;
        tmp3 = tmp2->next;
        tmp1->next = NULL;
        while(tmp2!=NULL)
        {
            tmp2->next = tmp1;
            tmp1 = tmp2;
            tmp2 = tmp3;
            if(tmp3!=NULL)
            tmp3 = tmp3->next;
        }
        *pplist=tmp1;
    }
}

//链表冒泡排序
void BubbleSort(pList plist)
{
    pList cur;
    pList cur_next ;
    int n = GetListLength(plist);
    int flag=0;
    if (plist == NULL||plist->next==NULL)
    {
        return;
    }
    else
    {
        for (int i=0; i < n-1; i++)
        {
            for (int j = 0; j < n - 1 - i; j++)
            {
                int c = j;
                cur = plist;
                cur_next = cur->next;
                while (c--)
                {
                    cur=cur->next;
                    cur_next = cur->next;
                }
                if (cur->data < cur_next->data)
                {
                    int tmp = cur->data;
                    cur->data = cur_next->data;
                    cur_next->data=tmp;
                }
            }
        }
    }
}


//合并有序链表
pList Merge(pList p1, pList p2)
{

    pList ret=NULL,cur=NULL;
    while (p1&&p2)
    {
        if (p1->data > p2->data)
        {
            if (ret == NULL)
            {
                ret = p2;
                cur = ret;
            }
            else
            {
                cur->next = p2;
                cur = cur->next;
            }
            p2 = p2->next;
        }
        else
        {
            if (ret == NULL)
            {
                ret = p1;
                cur = ret;
            }
            else
            {
                cur->next = p1;
                cur = cur->next;
            }
            p1 = p1->next;

        }
    }
    if (p1 != NULL)
    {
        while (p1)
        {
            cur->next = p1;
            cur = cur->next;
            p1 = p1->next;
        }
    }
    if (p2!= NULL)
    {
        while (p2)
        {
            cur->next = p2;
            cur = cur->next;
            p2 = p2->next;
        }
    }
    return ret;
}

////递归 合并有序链表(升序)
pList Merge_R(pList p1, pList p2)
{
    pList MergeHead;
    if (p1 == NULL)
        return p2;
    if (p2 == NULL)
        return p1;
    if (p1->data > p2->data)
    {
        MergeHead = p2;
        MergeHead->next = Merge_R(p1, p2->next);
    }
    else
    {
        MergeHead = p1;
        MergeHead->next = Merge_R(p1->next, p2);
    }
    return MergeHead;
}

//寻找中间结点
pNode FindMidNode(pList plist)
{
    pList fast=plist;
    pList slow=plist;
    while (fast&&fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}

//寻找倒数第K个结点
pNode FindLastKNode(pList plist, int k)
{
    pList fast = plist;
    pList slow = plist;
    if (plist == NULL)
    {
        return NULL;
    }
    while (k--&&fast)
    {
        fast = fast->next;
    }
    while (fast)
    {
        fast = fast->next;
        slow = slow->next;
    }
        return slow;
}

//判断是否是环
pNode IsCircle(pList plist)
{
    pNode fast=plist;
    pNode slow=plist;
    if (plist==NULL)
    {
        return NULL;
    }
    while (fast&&fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if (fast == slow)
            return fast;
    }
    return NULL;
}

//得到环的长度
int GetCircleLength(pNode meet)
{
    pNode tmp;
    int count = 1;
    if (meet == NULL)
    {
        return 0;
    }
    tmp = meet->next;
    while (tmp!=meet)
    {
        tmp = tmp->next;
        count++;
    }
    return count;
}

//得到环的开始
pNode GetCycleEntryNode(pList plist, pNode meet)
{
    pList cur1=plist;
    pList cur2=meet;
    if (meet == NULL || plist == NULL)
        return NULL;
    while (cur1 && cur2)
    {
        if (cur1 == cur2)
            return cur1;
        cur1 = cur1->next;
        cur2 = cur2->next;
    }
    return NULL;
}
//判断是否交叉 交叉返回真 不交叉返回假
int CheckCross(pList p1, pList p2)
{
    pList longlist = p1;
    pList shortlist = p2;
    int len1=0;
    int len2=0;
    int subb;
    if (p1==NULL || p2==NULL)
        return 0;
    while (longlist)
    {
        len1++;
        longlist = longlist->next;
    }
    while (shortlist)
    {
        len2++;
        shortlist = shortlist->next;
    }
    subb = len1 - len2;
    if (subb < 0)
    {
        subb = -subb;
        longlist = p2;
        shortlist = p1;
    }
    else
    {
        longlist = p1;
        shortlist = p2;
    }
    while (subb--)
    {
        longlist = longlist->next;
    }
    while (longlist!=NULL && shortlist!=NULL)
    {
        if (longlist == shortlist)
        {
            return 1;
        }
        longlist = longlist->next;
        shortlist = shortlist->next;
    }
    return 0;
}
//得到交叉点
pNode GetCrossNode(pList p1, pList p2)
{
    pList longlist = p1;
    pList shortlist = p2;
    int len1 = 0;
    int len2 = 0;
    int subb;
    if (p1 == NULL || p2 == NULL)
        return 0;
    while (longlist)
    {
        len1++;
        longlist = longlist->next;
    }
    while (shortlist)
    {
        len2++;
        shortlist = shortlist->next;
    }
    subb = len1 - len2;
    if (subb < 0)
    {
        subb = 0 - subb;
        longlist = p2;
        shortlist = p1;
    }
    else
    {
        longlist = p1;
        shortlist = p2;
    }
    while (subb--)
    {
        longlist = longlist->next;
    }
    while (longlist != NULL && shortlist != NULL)
    {
        if (longlist == shortlist)
        {
            return shortlist;
        }
        longlist = longlist->next;
        shortlist = shortlist->next;
    }
    return NULL;
}


//升级版(复杂情况)====如果交叉返回交叉点  反正返回NULL
pNode ComplexSituation(pList p1, pList p2)
{
    pList meet1 = IsCircle(p1);
    pList meet2 = IsCircle(p2);
    //有一个为空返回空
    if (p1 == NULL || p2 == NULL)
        return NULL;

    //两个都是无环单链表
    if (meet1 == NULL&&meet1 == NULL)
    {
        return GetCrossNode(p1, p2);
    }
    //两个都是环   可能相交,也可能不相交
    else if (meet1!= NULL&&meet2 != NULL)
    {
        //先确定是否是同一个环内
        pList cur = meet1->next;
        while (cur != meet1&&cur!=meet2)
        {
            cur = cur->next;
        }
        //cur回到了原点,说明meet1和meet2不是在同一个环内  所以原p1和p2没有相交点
        if (cur == meet1)
        {
            return NULL;
        }
        //反正p1和p2有相交点,且里面带有环 
        else
        {
            //在一个相遇的地方断开,然后形成了一个交叉的链表,然后得到交叉点,然后在重新连接起来
            pList tmp = meet1->next;//保存下一个结点
            meet1->next = NULL;//断开
            pList ret = GetCrossNode(p1, p2);//得到交叉点
            meet1->next = tmp;//重新连接结点
            return ret;
        }
    }
    else//一个环和一个无环单链表没有交点
    {
        return NULL;
    }
}


//15. 求两个有序单链表交集(差集)。
void UnionSet(pList p1, pList p2)
{
    if (p1 == NULL || p2 == NULL)
    {
        return;
    }
    while (p1&&p2)
    {
        if (p1->data == p2->data)
        {
            printf("%d ", p1->data);
            p1 = p1->next;
            p2 = p2->next;
        }
        else if (p1->data < p2->data)
        {
            p1 = p1->next;
        }
        else
        {
            p2 = p2->next;
        }
    }
}




//买一个复杂结点
ComplexNode* BuyComplexNode(DataType d)
{
    ComplexNode* tmp = (ComplexNode*)malloc(sizeof(ComplexNode));
    tmp->data = d;
    tmp->next = NULL;
    tmp->random = NULL;
    return tmp;
}

//打印复杂链表
void PrintComplexList(ComplexNode* plist)
{
    ComplexNode* cur = plist;
        while (cur)
        {
            printf("%d:", cur->data);
            if (cur->random==NULL)
            {
            printf("(NU)->");
            }
            else
            {
                printf("(%d)->", cur->random->data);
            }
            cur = cur->next;
        }
        printf("\n");
}

//复制复杂链表
ComplexNode* CopyComplexList(ComplexNode* plist)
{
    ComplexNode* cur=plist;
    ComplexNode* cur_R = plist;
    ComplexNode* tmp=NULL;
    ComplexNode* ret=NULL;
    if (plist == NULL)
    {
        return NULL;
    }
    else
    {
        //创建复制结点,并插入到原链表,合并新老链表
        while (cur)
        {
            tmp = (ComplexNode*)malloc(sizeof(ComplexNode));
            tmp->data = cur->data;

            tmp->next = cur->next;
            cur->next = tmp;
            cur = cur->next->next;
        }
        //根据老链表,建立新链表的随机指针的关系,随机指针的复制要在结点复制之后
        cur = plist;
        while (cur)
        {
            tmp = cur->next;
            if (cur->random != NULL)
            {
                tmp->random = cur->random->next;
            }
            else
                tmp->random = NULL;
            cur = cur->next->next;
        }
        //从合并拆出新复制的结点,并连成链表
        cur = plist;
        ret = cur->next;
        while (cur)
        {
            cur_R = cur->next;
            cur->next = cur->next->next;
            cur = cur->next;
            if (cur!= NULL)
            {
                cur_R->next = cur->next;
                cur_R = cur_R->next;
            }
            else
            {
                cur_R->next = NULL;
            }

        }
        //返回已复制的新链表
        return ret;
    }
}

猜你喜欢

转载自blog.csdn.net/QQ1910084514/article/details/81431693
今日推荐