单链表常见面试题

//LinkList.h
#ifndef _LINKLIST_H__
#define _LINKLIST_H__

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
typedef int DataType;
typedef struct Node
{
    DataType data;
    struct Node* next;
}Node,*pNode,*pList;
void InitList(pList* pplist);
//尾插法
void PushBack(pList* pplist);
//排序
void BubbleSort(pList* pplist);
//打印单向链表 
void ReversePrint(pList plist);
//删除无头单链表的非尾结点 
void EraseNotTail(pNode pos);
//在无头单链表的非头结点前插入一个元素 
void InsertFrontNode(pNode pos, DataType x);
//约瑟夫环问题 
void JosephCycle(pList* pplist, int k);
//逆序单向链表 
void ReverseList(pList* pplist);
//合并两个有序列表 
pList Merge(const pList* p1, const pList* p2);
//查找单链表的中间节点,要求只能遍历一次链表 
pNode FindMidNode(pList plist);
//查找单链表的倒数第k个节点,要求只能遍历一次链表 
pNode FindKNode(pList plist, int k);
//判断链表时候带环 
pNode CheckCircle(pList plist);
//求环的长度 
int GetCircleLength(pNode meet);
//求环的入口点 
pNode GetCycleEntryNode(pList plist, pNode meet);
//判断两条单项链表时候相交 
int CheckCross(pList list1, pList list2);
//求交点 
pNode GetCrossNode(pList list1, pList list2);
#endif


//LinkList.c
#define _CRT_SECURE_NO_WARNINGS
#include"LinkList.h"
pNode buynode(DataType x)
{
    pNode tmp = NULL;
    tmp = (pNode)malloc(sizeof(Node));
    if (tmp == NULL)
    {
        perror("malloc");
        exit(1);
    }
    tmp->data = x;
    tmp->next = NULL;
    return tmp;
}
void InitList(pList* pplist)
{
    assert(pplist);
    *pplist = NULL;
}
//尾插法
void PushBack(pList* pplist,DataType x)
{

    pNode cur = NULL;
    assert(pplist);
    cur = *pplist;
    pNode newnode = buynode(x);
    if (*pplist == NULL)
    {
        *pplist = newnode;
    }
    else
    {
        while (cur->next)
        {
            cur = cur->next;
        }
        cur->next = newnode;
    }
}
//排序
void BubbleSort(pList* pplist)
{
    pNode cur = NULL;
    pNode tail = NULL;
    assert(pplist);
    cur = *pplist;
    if (*pplist == NULL)
    {
        return;
    }
    while (cur != tail)
    {
        while (cur->next!=tail)
        {
            if (cur->data < cur->next->data)
            {
                DataType tmp = cur->data;
                cur->data = cur->next->data;
                cur->next->data = tmp;
            }
            cur = cur->next;
        }
        tail = cur;
        cur = *pplist;
    }
}
//打印单向链表 
void Display(pList plist)
{
    pNode tmp = plist;
    while (tmp)
    {
        printf("%d->", tmp->data);
        tmp = tmp->next;
    }
    printf("end\n");
}
//查找x所在的节点
pNode Find(pList pplist,DataType x)
{
    pNode cur = pplist;
    if (pplist == NULL)
    {
        return NULL;
    }
    else
    {
        while (cur)
        {
            if (cur->data == x)
            {
                return cur;
            }
            cur = cur->next;
        }
        return NULL;
    }

}
//删除无头单链表的非尾结点 
void EraseNotTail(pNode pos)
{
    pNode cur = NULL;
    assert(pos);
    cur = pos->next;
    pos->data = cur->data;
    pos->next = cur->next;
    free(cur);
    cur = NULL;
}
//在无头单链表的非头结点前插入一个元素 
void InsertFrontNode(pNode pos, DataType x)
{
    pNode NewNode = NULL;
    assert(pos);
    NewNode = buynode(x);
    NewNode->next = pos->next;
    pos->next = NewNode;
    DataType tmp = pos->data;
    pos->data = NewNode->data;
    NewNode->data = tmp;
}
//约瑟夫环问题 
void JosephCycle(pList* pplist, int k)
{

}
//逆序单向链表 
void ReverseList(pList* pplist)
{
    pNode cur = *pplist;
    pNode p = NULL;
    pNode r = NULL;
    assert(pplist);
    while (cur)
    {
        r = p;
        p = cur;
        cur = cur->next;
        p->next = r;
    }
    *pplist = p;
}
//合并两个有序列表    非递归
pList Merge(const pList* p1, const pList* p2)
{
    pList newnode = NULL;
    pNode cur = NULL;
    pNode cur1 = *p1;
    pNode cur2 = *p2;
    assert(p1);
    assert(p2);
    //p1和p1相等(包括两个都为NULL)
    if (*p1 == *p2)
    {
        return *p1;
    }
    //一个为空,一个非空
    if ((*p1 == NULL) && (*p2 != NULL))
    {
        return *p2;
    }
    if ((*p2 == NULL) && (*p1 != NULL))
    {
        return *p1;
    }
    //2个都不为空
    if (cur1->data < cur2->data)
    {
        newnode = cur1;
        cur1 = cur1->next;
        newnode->next = NULL;
    }
    else
    {
        newnode = cur2;
        cur2 = cur2->next;
        newnode->next = NULL;
    }
    cur = newnode;
    while (cur1&&cur2)
    {
        if (cur1->data > cur2->data)
        {
            cur->next = cur2;   
            cur2 = cur2->next;
            cur = cur->next;
        }
        else
        {
            cur->next = cur1;
            cur1 = cur1->next;
            cur = cur->next;
        }
    }
    if (cur1 == NULL)
    {
        cur->next = cur2;
    }
    else
    {
        cur->next = cur1;
    }
    return newnode;
}
//查找单链表的中间节点,要求只能遍历一次链表 
pNode FindMidNode(pList plist)
{
    pNode slow = plist;
    pNode fast = plist;
    if ((fast == NULL) || (fast->next == NULL))
    {
        return fast;
    }
    else
    {
        while (fast&&fast->next)
        {
            fast = fast->next->next;
            slow = slow->next;
        }
        return slow;
    }

}
//查找单链表的倒数第k个节点,要求只能遍历一次链表 
pNode FindKNode(pList plist, int k)
{
    pNode fast = plist;
    pNode slow = plist;
    if (plist == NULL)
    {
        return NULL;
    }
    int i = 0;
    for (i; i < k-1; i++)
    {
        fast = fast->next;
        if (fast == NULL)
        {
            return NULL;
        }
    }
    fast = fast->next;
    while (fast)
    {
        fast = fast->next;
        slow = slow->next;
    }
    return slow;
}
//判断链表是否带环 
pNode CheckCircle(pList plist)
{
    pNode slow = plist;
    pNode fast = plist;
    if (plist == NULL)
    {
        return NULL;
    }
    else
    {
        while (fast&&fast->next)
        {
            fast = fast->next->next;
            slow = slow->next;
            if (fast == slow)
            {
                return slow;
                break;
            }
        }
        return NULL;
    }
}
//求环的长度 
int GetCircleLength(pNode meet)
{
    int count = 0;
    pNode cur = meet;
    do 
    {
        count++;
        cur = cur->next;
    } while (cur!=meet);
    return count;
}
//求环的入口点 
pNode GetCycleEntryNode(pList plist, pNode meet)
{

}
//判断两条单项链表时候相交 
int CheckCross(pList list1, pList list2)
{
    pNode cur1 = list1;
    pNode cur2 = list2;
    if (cur1 == NULL || cur2 == NULL)
    {
        return 0;                //0表示不相交,1表示相交
    }
    while (cur1->next)
    {
        cur1 = cur1->next;
    }
    while (cur2->next)
    {
        cur2 = cur2->next;
    }
    if (cur1 == cur2)
    {
        return 1;
    }
    return 0;

}
//求交点 
pNode GetCrossNode(pList list1, pList list2)
{
    int len1 = 0, len2 = 0;
    pNode cur1 = NULL;
    pNode cur2 = NULL;
    cur1 = list1;
    cur2 = list2;
    while (cur1->next)
    {
        len1++;
        cur1 = cur1->next;
    }
    while (cur2->next)
    {
        len2++;
        cur2 = cur2->next;
    }
    int diff = abs(len2 - len1);
    if (len1 > len2)
    {
        cur1 = list1;
        cur2 = list2;
    }
    else
    {
        cur1 = list2;
        cur2 = list1;
    }
    for (int i = 0; i < diff; i++)
    {
        cur1 = cur1->next;
    }
    while (cur1 != cur2)
    {
        cur1 = cur1->next;
        cur2 = cur2->next;
    }
    return cur1;
}

//test.c
#define _CRT_SECURE_NO_WARNINGS
#include"LinkList.h"

void test1()
{
    pList pplist;
    InitList(&pplist);
    PushBack(&pplist, 1);
    PushBack(&pplist, 2);
    PushBack(&pplist, 3);
    PushBack(&pplist, 4);
    Display(pplist);
    //ReversePrint1(&pplist);
    //ReversePrint2(&pplist);
    Display(pplist);
}
void test2()
{
    pList pplist;
    pNode node = NULL;
    InitList(&pplist);
    PushBack(&pplist, 1);
    PushBack(&pplist, 2);
    PushBack(&pplist, 3);
    PushBack(&pplist, 4);
    Display(pplist);
    node = Find(pplist, 3);
    EraseNotTail(node);
    InsertFrontNode(node, 10);
    Display(pplist);
}
void test3()
{
    pList pplist;
    pNode node = NULL;
    InitList(&pplist);
    PushBack(&pplist, 11);
    PushBack(&pplist, 2);
    PushBack(&pplist, 7);
    PushBack(&pplist, 4);
    Display(pplist);
    BubbleSort(&pplist);
    Display(pplist);
}
void test4()
{
    pList s1;
    pList s2;
    pList s3 = NULL;
    pList node = NULL;
    pNode mid = NULL;
    InitList(&s1);
    InitList(&s2);
    PushBack(&s1, 1);
    PushBack(&s1, 3);
    PushBack(&s1, 5);
    Display(s1);

    PushBack(&s2, 2);
    PushBack(&s2, 4);
    PushBack(&s2, 6);
    PushBack(&s2, 8);
    PushBack(&s2, 10);
    Display(s2);

    node = Merge(&s2, &s1);
    mid=FindMidNode(node);
    Display(node);
    printf("%d\n", mid->data);
}
void test5()
{
    pList pplist;
    pNode node = NULL;
    InitList(&pplist);
    PushBack(&pplist, 11);
    PushBack(&pplist, 2);
    PushBack(&pplist, 7);
    PushBack(&pplist, 44);
    PushBack(&pplist, 5);
    PushBack(&pplist, 8);
    node= Find(pplist, 8);
    node->next = Find(pplist, 2);
    Display(pplist);
    node = FindKNode(pplist, 7);
    printf("%d\n", node->data);
}
void test6()
{
    pList pplist;
    pNode node = NULL;
    pNode newnode = NULL;
    InitList(&pplist);
    PushBack(&pplist, 11);
    PushBack(&pplist, 2);
    PushBack(&pplist, 7);
    PushBack(&pplist, 44);
    PushBack(&pplist, 5);
    PushBack(&pplist, 8);
    node = Find(pplist, 8);
    node->next = Find(pplist, 2);
    newnode = CheckCircle(pplist);
    //printf("%d\n", newnode->data);
    int ret=GetCircleLength(newnode);
    printf("%d\n", ret);
}
void test7()
{
    pList s1;
    pList s2;
    pNode node;
    pNode c;
    InitList(&s1);
    InitList(&s2);
    PushBack(&s1, 1);
    PushBack(&s1, 3);
    PushBack(&s1, 5);

    PushBack(&s2, 2);
    PushBack(&s2, 4);
    PushBack(&s2, 6);
    PushBack(&s2, 8);
    PushBack(&s2, 10);
    node = Find(s1, 5);
    node->next = Find(s2, 6);
    int ret = CheckCross(NULL, NULL);
    if (ret == 1)
    {
        printf("相交\n");
    }
    else
    {
        printf("不相交\n");
    }
    c = GetCrossNode(s1, s2);
    printf("%d\n", c->data);

}
int main()
{
    //test1();
    //test2();
    //test3();
    //test4();
    //test5();
    //test6();
    test7();

    system("pause");

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值