//单链表有环,是指单链表的最后一个结点的指针指向了链表中的某个结点(通常单链表的最后一个结点的指针域是空的)//试编写算法判断单链表是否存在环,如果带环则找出环的起点

//(1)给出算法的基本设计思想
// 1.设置快慢指针,其中快的走两个结点慢的走一个结点
// 2.如果快指针为空则就是无环链表,若快指针在某个结点上等于慢指针则为有环结点
// 3.如果是有环节点可以在表头创建节点p,移动p和慢指针当p==slow后,即为环的起点
//        具体:设表头到环的距离为L,设快指针与慢指针相遇的结点为x,从两指针相遇的结点到起点为y,设一圈的距离为R
//            则慢指针一共移动了L+x个结点,快指针则移动了2(L+x)个结点,快指针比慢指针多走了n圈
//            则他们的具体有等式  2(L + x) = L + x + nR
//                        化简得  L = nR - x
//                    提出一个R   L = (n - 1)R + (R-x)   
//      (n-1)R可以当做0,(R+x)=y    L = y                
// 所以移动y次后p和slow相遇就是起点

//(2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释
typedef struct LNode
{
    int data;
    struct LNode* next;
}LNode,*LinkList;
bool InitList(LinkList * L)//初始化
{
    (*L) = (LNode*)malloc(sizeof(LNode));
    if ((*L) == NULL)
        return false;
    (*L)->next = NULL;
    return true;
}
bool InsertList(LinkList* L)
{
    LNode* p = (*L);//尾指针
    if (p == NULL)
        return false;
    int i = 0;
    scanf("%d", &i);

    while (i != 9999)
    {
        LNode* s = (LNode*)malloc(sizeof(LNode));
        if (s == NULL)
            return true;
        s->data = i;
        s->next = p->next;
        p->next = s;
        p = s;
        scanf("%d", &i);
    }
    //p->next = NULL;//不带环链表
    LNode* q = (*L);
    for (i = 0; i < 4; i++)
        q = q->next;
    p->next = q;//假设链表带环,并且假设起始地点为q结点
    return true;
}
bool Surround(LinkList L)//判断是否带环如果带环找到环的起点
{
    LNode* fast = L;
    LNode* slow = L;


    while (fast->next != NULL && fast->next->next != NULL)
    {
        fast = fast->next->next;//快指针走两步
        slow = slow->next;//慢指针走一步
        if (fast == slow)
            break;
    }
    if (fast->next == NULL || fast->next->next == NULL)//不带环的情况
    {
        printf("不带环\n");
        return false;
    }

    //带环的情况
    LNode* p = L;
    if (p == NULL)
        return false;
    while (p != slow)
    {
        p = p->next;
        slow = slow->next;
    }
    if (p == slow)
    {
        printf("环的入口结点为\n");
        printf("%d \n", p->data);
    }
    return true;
}
bool PrintList(LinkList L)
{
    LNode* p = L->next;
    if (p == NULL)
        return false;
    while (p != NULL)
    {
        printf("%d ", p->data);
        p = p->next;
    }
    return true;
}
int main()
{
    LinkList L;//指向链表的指针
    InitList(&L);//初始化
    InsertList(&L);//插入
    Surround(L);//判断是否带环
    //PrintList(L);//测试
    return 0;
}

//(3)说明你所设计算法的时间复杂度和空间复杂度
//时间复杂度O(n)
//空间复杂度O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值