zoukankan      html  css  js  c++  java
  • 数据结构-判断链表是否存在环形链表

    1:这里有一个比较简单的解法。设置两个指针p1、p2。每次循环p1向前走两步。直到p2碰到NULL指针或者两个指针相等时结束循环。如果两个指针相等,则说明存在环。代码如下:

    // ConsoleApplication15.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <malloc.h>
    #include <iostream>
    using namespace std;
    
    typedef struct node//定义链表结构体
    {
        int data;//节点内容
        node *next;//指向结构体的指针,下一个节点
    }node;
    
    node *create()//创建单链表
    {
        int i = 0;//链表中数据的个数
        node *head, *p, *q;//这些的本质是节点的地址
        int x = 0;
        head = NULL;
        q = NULL;//初始化q,q代表末节点
        p = NULL;
        while (1)
        {
            printf("please input the data:");
            scanf_s("%d", &x);
            if (x == 0)
                break;//data为0时创建结束
            p = (node *)malloc(sizeof(node));//用于每次输入链表的数据
            p->data = x;
            if (++i == 1)//链表头的指针指向下一个节点
            {
                head = p;
                q = p;
            }
            else
            {
                q->next = p;//连接到链表尾端
                q = p;
            }
            q->next = NULL;/*尾结点的后继指针为NULL(空)*/
        }
        return head;
    }
    
    int length(node *head)
    {
        int len = 0;
        node *p;
        p = head->next;
        while (p != NULL)
        {
            len++;
            p = p->next;
        }
        return len;
    }
    
    void print(node *head)
    {
        node *p;
        p = head;
        while (p)/*直到结点q为NULL结束循环*/
        {
            printf("%d ", p->data);/*输出结点中的值*/
            p = p->next;/*指向下一个结点*/
        }
    }
    
    node *search_node(node *head, int pos)//查找单链表pos位置的节点,返回节点的指针。pos从0开始,0返回head节点
    {
        node *p = head->next;
        if (pos < 0)//pos位置不正确
        {
            printf("incorrect position to search node!");//pose位置不正确
            return NULL;
        }
        if (pos == 0)
        {
            return head;
        }
        if (pos == NULL)
        {
            printf("Link is empty!");//链表为空
            return NULL;
        }
        while (--pos)
        {
            if ((p = p->next) == NULL)
            {
                printf("incorrect position to search node!");//超出链表返回
                break;
            }
        }
        return p;
    }
    
    node *insert_node(node *head, int pos, int data)//单链表的插入
    {
        node *item = NULL;
        node *p;
        item = (node *)malloc(sizeof(node));
        item->data = data;
        if (pos == 0)//插在head后面
        {
            head->next = item;//head后面是item
            return head;
        }
        p = search_node(head, pos);//获得pos的节点指针
        if (p != NULL)
        {
            item->next = p->next;//item指向原pos节点的后一个节点
            p->next = item;//把item插入到pos的后面
        }
        return head;
    }
    
    node *delete_node(node *head, int pos)//删除节点
    {
        node *item = NULL;
        node *p = head->next;
        if (p = NULL)
        {
            printf("link is empty!");
            return NULL;
        }
        p = search_node(head, pos - 1);//获得位置pos节点的指针
        if (p != NULL&&p->next != NULL)
        {
            item = p->next;
            p->next = item->next;
            delete item;
        }
        return head;
    }
    
    node *reverse(node *head)//链表的逆置
    {
        node *next;
        node *prev = NULL;
        while (head != NULL)
        {
            next = head->next;
            head->next = prev;
            prev = head;
            head = next;
        }
        return prev;
    }
    
    node *search(node *head)//寻找单链表的中间元素
    {
        int i = 0;
        int j = 0;
        node *current = NULL;
        node *middle = NULL;
        current = middle = head->next;
        while (current != NULL)
        {
            if (i / 2 > j)
            {
                j++;
                middle = middle->next;
            }
            i++;
            current = current->next;
        }
        return middle;
    }
    
    node *InsertSort(void)//单链表的正向排序
    {
        int data = 0;
        struct node *head = NULL, *New, *Cur, *Pre=NULL;
        while (1)
        {
            printf("please input the data
    ");
            scanf_s("%d", &data);
            if (data == 0)
            {
                break;
            }
            New = (struct node*)malloc(sizeof(struct node));
            New->data = data;
            New->next = NULL;
            if (head == NULL)//第一次循环时对头节点赋值
            {
                head = New;
                continue;
            }
            if (New->data <= head->data)
            {//head之前插入节点
                New->next = head;
                head = New;
                continue;
            }
            Cur = head;
            while (New->data > Cur->data && Cur->next != NULL)//找到需要插入的位置
            {
                Pre = Cur;
                Cur = Cur->next;
            }
            if (Cur->data >= New->data)//位置在中间
            {
                Pre->next = New;
                New->next = Cur;
            }
            else//位置在末尾
                Cur->next = New;//把New节点插到Cur之后
        }
        return head;
    }
    
    bool IsLoop(node *head, node **start)//判断链表是否存在环形链表,start为回环开始节点的地址
    {
        node *p1 = head, *p2 = head;
        if (head == NULL || head->next == NULL)//head为NULL或者链表为空时返回false
        {
            return false;
        }
        do
        {
            p1 = p1->next;//p1走一步
            p2 = p2->next->next;//p2走两步
        } while (p2 && p2->next && p1 != p2);
        if (p1 == p2)
        {
            *start = p1;//p1为回环开始节点
            return true;
        }
        else
        {
            return false;
        }
    }
    
    int main()
    {
        bool bLoop = false;
        node *head = create();
        node *start = head->next->next->next;//使第4个节点为回环开始位置
        start->next = head->next;//回环连接到第2个节点
        node *loopStart = NULL;
        bLoop = IsLoop(head, &loopStart);
        printf("bLoop=%d
    ", bLoop);
        printf("bLoop==loopStart?%d
    ", (loopStart == start));
        return 0;
    
    
        
    
        return 0;
    }
    View Code

    运行结果:

  • 相关阅读:
    HDU 2852 KiKi's K-Number (主席树)
    HDU 2089 不要62
    Light oj 1140 How Many Zeroes?
    Bless You Autocorrect!
    HDU 6201 transaction transaction transaction
    HDU1561 The more ,The better (树形背包Dp)
    CodeForces 607B zuma
    POJ 1651 Mulitiplication Puzzle
    CSUOJ 1952 合并石子
    Uva 1599 Ideal path
  • 原文地址:https://www.cnblogs.com/lovemi93/p/7600233.html
Copyright © 2011-2022 走看看