找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2879|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

C++語言判斷單鏈表是否有環(huán)鏈表 程序源碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
1.問題:如果給定一個(gè)單鏈表,如何判斷其是否為有環(huán)鏈表
2.方法:
(1)從給定鏈表的第一個(gè)節(jié)點(diǎn)開始遍歷,每遍歷至一個(gè)節(jié)點(diǎn),都將其和所有的前驅(qū)節(jié)點(diǎn)進(jìn)行比對(duì),如果為同一個(gè)節(jié)點(diǎn),則表明當(dāng)前鏈表中有環(huán);反之,如果遍歷至鏈表最后一個(gè)節(jié)點(diǎn),仍未找到相同的節(jié)點(diǎn),則證明該鏈表中無環(huán)。


如上所示,當(dāng)函數(shù)的返回值為 True,表示該鏈表有環(huán);反之若函數(shù)返回值為 False,表明鏈表中無環(huán)。顯然,此實(shí)現(xiàn)方案的時(shí)間復(fù)雜度為O(n2)。
(2)在一個(gè)鏈表中,如果 2 個(gè)指針(假設(shè)為 H1 和 H2)都從表頭開始遍歷鏈表,其中 H1 每次移動(dòng) 2 個(gè)節(jié)點(diǎn)的長度(H1 = H1->next->next),而 H2 每次移動(dòng) 1 個(gè)節(jié)點(diǎn)的長度(H2 = H2->next),如果該鏈表為有環(huán)鏈表,則 H1、H2 最終必定會(huì)相等;反之,如果該鏈表中無環(huán),則 H1、H2 永遠(yuǎn)不會(huì)相遇。


本算法的時(shí)間復(fù)雜度為 O(n)。

  1. #include<stdio.h>
  2. #include<stdlib.h>

  3. //自定義 bool 類型
  4. typedef enum Bool
  5. {
  6.     False=0,
  7.     True=1
  8. }Bool;

  9. typedef struct link{
  10.     int data;
  11.     struct link* next;
  12. }link;

  13. link *linkIint(int n)
  14. {
  15.     link *head=(link*)malloc(sizeof(link));
  16.     head->data=1;
  17.     head->next=NULL;
  18.     link *phead=head;
  19.     int i;
  20.     for(i=2;i<=n;i++)
  21.     {
  22.         link *temp=(link*)malloc(sizeof(link));
  23.         temp->data=i;
  24.         temp->next=NULL;

  25.         head->next=temp;
  26.         head=head->next;
  27.     }
  28.         head->next=phead;
  29.     return phead;
  30. }

  31. #if 1
  32. Bool HaveRing(link *temp)
  33. {
  34.     link *H2=temp;
  35.     link *H1=temp->next;
  36.         if(H2==NULL||H2==NULL)
  37.         {
  38.                 return False;
  39.         }
  40.     while(H1)
  41.     {
  42.         if(H1==H2)
  43.         {
  44.             printf("this links have a ring\n");
  45.             return True;
  46.         }
  47.         else
  48.         {
  49.             H1=H1->next;
  50.             if (!H1)
  51.             {
  52.                 printf("this links no ring\n");
  53.                 return False;
  54.             }
  55.             else
  56.             {
  57.                 H1=H1->next;
  58.                 H2=H2->next;
  59.             }
  60.         }
  61.     }
  62.     //鏈表中無環(huán)
  63.     printf("this links no ring\n");
  64.     return False;
  65. }
  66. #else

  67. Bool HaveRing(link *H)
  68. {
  69.     link * Htemp = H;
  70.     //存儲(chǔ)所遍歷節(jié)點(diǎn)所有前驅(qū)節(jié)點(diǎn)的存儲(chǔ)地址,64位環(huán)境下地址占 8 個(gè)字節(jié),所以這里用 long long 類型
  71.     long long addr[20] = { 0 };
  72.     int length = 0, i = 0;
  73.         if(Htemp==NULL||Htemp->next==NULL)
  74.         {
  75.                 return False;
  76.         }
  77.     //逐個(gè)遍歷鏈表中各個(gè)節(jié)點(diǎn)
  78.     while (Htemp) {
  79.         //依次將 Htemp 和 addr 數(shù)組中記錄的已遍歷的地址進(jìn)行比對(duì)
  80.         for (i = 0; i < length; i++) {
  81.             //如果比對(duì)成功,則證明有環(huán)
  82.             if (Htemp == (link*)addr[i]) {
  83.                 return True;
  84.             }
  85.         }
  86.         //比對(duì)不成功,則記錄 Htemp 節(jié)點(diǎn)的存儲(chǔ)地址
  87.         addr[length] = (long long)Htemp;
  88.         length++;
  89.         Htemp = Htemp->next;
  90.     }
  91.     return False;
  92. }

  93. #endif

  94. void linkPrint(link *temp)
  95. {
  96.         link *phead=temp;
  97.     if(!temp)
  98.         printf("the link is empty\n");
  99.     else
  100.     {
  101.         while(temp)
  102.         {
  103.             printf("%d\t",temp->data);
  104.             temp=temp->next;
  105.             if(temp==phead)
  106.             {
  107.                                 printf("\r\n");
  108.                 break;
  109.             }
  110.         }
  111.     }
  112. }

  113. int main()
  114. {
  115.     link *head=linkIint(6);
  116.     linkPrint(head);
  117.     if(HaveRing(head)==True)
  118.         {
  119.                 printf("the link has a ring\r\n");
  120.         }
  121.         else
  122.         {
  123.                 printf("the link no rave\r\n");
  124.         }
  125.     return 0;
  126. }
復(fù)制代碼




3.以上源碼: 有環(huán)鏈表判定.7z (1.09 KB, 下載次數(shù): 5)

評(píng)分

參與人數(shù) 1黑幣 +30 收起 理由
admin + 30 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表