判斷單鏈表是否有環

寫一段代碼判斷一個單向鏈表中是否有環。

下面爲鏈表中的結構體節點
struct node
{
     int data;
     node *next;
}*linklist,*s,*t;

 

方法一:
    最簡單的思路就是,定義一個指針數組,初始化爲空指針,從鏈表的頭指針開始往後遍歷,每次遇到一個指針就跟指針數組中的指針相比較,若沒有找到相同的指針,說明這個節點是第一次訪問,還沒有形成環,將這個指針添加到指針數組中去。若在指針數組中找到了同樣的指針,說明這個節點已經被訪問過了,於是就形成了環。
方法二:
    使用map來進行映射。首先定義 map<node*,int>m; 意思就是將一個node* 指針映射成數組的下標,並賦值爲一個int類型的數值。
從鏈表的頭指針開始往後遍歷(p=p->next;),每次遇到一個指針p,就判斷if(m[p]==0)  m[p]=1;說明這個節點是第一次訪問,if(m[p]==1) 說明這個節點已經被訪問過一次了,於是就形成了環。
複製代碼
#include "iostream"
#include "map"
using namespace std;
map<node*,int>m;
bool IsLoop(node *head)
{
      if(!head)
           return false;
      node *p=head;
      while(p)
     {
           if(m[p]==0) // 默認值都是0
                m[p]=1;
           else if(m[p]==1)
                return true;
           p=p->next;
     }
}
複製代碼

 

方法三:
     思路:
    用兩個指針,pSlow,pFast,就是一個慢一個快
    慢的一次跳一步
    快的一次跳兩步
    往鏈表末端移動。如果pFast==NULL,則說明鏈表沒有環,如果pSlow==pFast,則說明鏈表存在環。
    這個方法與前面2個方法相比,不但速度很快,而且不需要額外的存儲空間,時間複雜度、空間複雜度都是最小的。
複製代碼
bool IsLoop(node *head)
{
        node *pSlow=head;
        node *pFast=head;
        while(pSlow!=NULL && pFast!=NULL)
        {
                pSlow=pSlow->next;
                pFast=pFast->next->next;
                if(pSlow==pFast)
                        return true;
        }
       return false;
}
複製代碼

 

 
 
 
完整的測試代碼如下:
複製代碼
#include "iostream"
#include "map"
using namespace std;
struct node
{
      int data;
      struct node *next;
}*linklist,*s,*head;
map<node*,int>m;
bool IsLoop(node *head)
{
      node *pSlow=head;
      node *pFast=head;
      while(pSlow!=NULL && pFast!=NULL)
      {
            pSlow=pSlow->next;
            pFast=pFast->next->next;
            if(pSlow==pFast)
                 return true;
      }
      return false;
}
node* InsertNode(node *head,int value)
{
      if(head==NULL)
      {
            head=(node *)malloc(sizeof(node));
            if(head==NULL)
                  printf("malloc failed");
            else
            {
                  head->data=value;
                  head->next=NULL;
            }
       }
       else
       {
            node *temp=(node *)malloc(sizeof(node));
            if(temp==NULL)
                  printf("malloc failed");
            else
            {
                  temp->data=value;
                  temp->next=head;
                  head=temp;
             }
       }
       return head;
}
int main(void)
{
       node *t,*q,*p=NULL;
       p=InsertNode(p,8);
       p=InsertNode(p,7);
       p=InsertNode(p,6);
       p=InsertNode(p,5);
       p=InsertNode(p,4);
       q=p;
       p=InsertNode(p,3);
       p=InsertNode(p,2);
       p=InsertNode(p,1);
       t=p;
       while(t->next)       // 找到鏈表的尾指針
              t=t->next;
       t->next=q;           // 將鏈表的尾指針指向第四個節點,這樣就構成了一個環
       bool flag=IsLoop(p);
       if(flag)
             cout<<"這個鏈表存在一個環"<<endl;
       else
             cout<<"這個鏈表不存在一個環"<<endl;
       system("pause");
       return 0;
}
複製代碼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章