常見的鏈表題目

 

常見的鏈表題目

分類: 算法&數據結構 3943人閱讀 評論(11) 收藏 舉報

一些常見的單鏈表題目,總結思路和實現代碼。

1.單鏈表的反序

2.給單鏈表建環

3.檢測單鏈表是否有環

4.給單鏈表解環

5.檢測兩條鏈表是否相交

6.不輸入頭節點,刪除單鏈表的指定節點(只給定待刪除節點指針)

 

1.單鏈表的反序

  1. //逆轉鏈表,並返回逆轉後的頭節點  
  2. node* reverse(node *head)  
  3. {  
  4.     if(head == NULL || head->next == NULL)  
  5.     {  
  6.         return head;  
  7.     }  
  8.     node *cur = head;  
  9.     node *pre = NULL;  
  10.     node *tmp;  
  11.     while(cur->next)  
  12.     {  
  13.         tmp = pre;  
  14.         pre = cur;  
  15.         cur = cur->next;  
  16.         pre->next = tmp;                  //操作pre的next逆轉  
  17.     }  
  18.     cur->next = pre;                     //結束時,操作cur的next逆轉  
  19.     return cur;  
  20. }  

 

2.給單鏈表建環

 

  1. //給單鏈表建環,讓尾指針,指向第num個節點,若沒有,返回false  
  2. bool bulid_looplink(node *head, int num)  
  3. {  
  4.     node *cur = head;  
  5.     node *tail = NULL;  
  6.     int i = 0;  
  7.     if(num <= 0 || head == NULL)  
  8.     {  
  9.         return false;  
  10.     }  
  11.     for(i = 1; i < num; ++i)  
  12.     {  
  13.         if(cur == NULL)  
  14.         {  
  15.             return false;  
  16.         }  
  17.         cur = cur->next;  
  18.     }  
  19.     tail = cur;  
  20.     while(tail->next)  
  21.     {  
  22.         tail = tail->next;  
  23.     }  
  24.     tail->next = cur;  
  25.     return true;  
  26. }  

 

3.檢測單鏈表是否有環

  1. //檢測單鏈表是否有環,快慢指針  
  2. bool detect_looplink(node *head)  
  3. {  
  4.     node *quick_node = head->next, *slow_node = head;  
  5.     if(head == NULL || head->next == NULL)  
  6.     {  
  7.         return false;  
  8.     }  
  9.     while(quick_node != slow_node)  
  10.     {  
  11.         if(quick_node == NULL || slow_node == NULL)  
  12.             break;  
  13.         quick_node = quick_node->next->next;  
  14.         slow_node = slow_node->next;  
  15.     }  
  16.     if(quick_node != NULL && slow_node != NULL)    //非尾節點相遇  
  17.         return true;  
  18.     return false;  
  19. }  

 

4.給單鏈表解環

ps:爲了增加節點位圖的效率,本應使用hash或則紅黑樹,這裏不造車了,直接用 set容器

  1. //找到有環節點,並解環,找到並解環,返回true,無環,返回false  
  2. //思路:先找到環節點:被2個節點指向的節點(一定有環的條件)ps:不考慮中間環,因爲只有一個next節點,只可能是尾環  
  3. bool unloop_link(node *head)  
  4. {  
  5.     set<node *> node_bitmap;        //node的地址位圖  
  6.     unsigned int num = 0;  
  7.     node *cur = head, *pre = NULL;  
  8.     while(cur != NULL)  
  9.     {  
  10.         if(!node_bitmap.count(cur) )              //該節點未被遍歷過  
  11.         {  
  12.             node_bitmap.insert(cur);  
  13.             ++num;  
  14.         }  
  15.         else                               //指向已被遍歷過的節點,此時pre節點爲尾節點  
  16.         {  
  17.             pre->next = NULL;  
  18.             return true;  
  19.         }  
  20.         pre = cur;  
  21.         cur = cur->next;  
  22.     }  
  23.     return false;  
  24. }  

 

5.檢測兩條鏈表是否相交

  1. //檢測兩條鏈表是否相交,是則返回第一個交點,否則返回NULL  
  2. //思路:把2個鏈表各遍歷一遍,記下長度length1和length2,若2者的尾節點指針相等,則相交。  
  3. //       之後再把長的鏈表從abs(len1-len2)的位置開始遍歷,第一個相等的指針爲目標節點  
  4. node* detect_intersect_links(node *first_link, node *second_link)  
  5. {  
  6.     int legnth1 = 1, length2 = 1, pos = 0;  
  7.     node *cur = NULL, *longer_link = first_link, *shorter_link = second_link;  
  8.     if(first_link == NULL || second_link == NULL)  
  9.     {  
  10.         return NULL;  
  11.     }  
  12.     while(first_link->next || second_link->next)     //遍歷2個鏈表  
  13.     {  
  14.         if(first_link->next)  
  15.         {  
  16.             first_link = first_link->next;  
  17.             ++legnth1;  
  18.         }  
  19.         if(second_link->next)  
  20.         {  
  21.             second_link = second_link->next;  
  22.             ++length2;  
  23.         }  
  24.     }  
  25.     if(first_link != second_link)                 //比較尾節點  
  26.     {  
  27.         return NULL;  
  28.     }  
  29.     pos = legnth1 - length2;  
  30.     if(legnth1 < length2)                  //保證 longer_link爲長鏈表  
  31.     {  
  32.         pos = length2 - legnth1;  
  33.         cur = longer_link;  
  34.         longer_link = shorter_link;  
  35.         shorter_link = cur;  
  36.     }  
  37.     while(pos-- > 0)  
  38.         longer_link = longer_link->next;  
  39.     while(longer_link || shorter_link)  
  40.     {  
  41.         if(longer_link == shorter_link)                  //找到第一個交點  
  42.         {  
  43.             return longer_link;  
  44.         }  
  45.         longer_link = longer_link->next;  
  46.         shorter_link = shorter_link->next;  
  47.     }  
  48.     return NULL;  
  49. }  

6.不輸入頭節點,刪除單鏈表的指定節點(只給定待刪除節點指針)

  1. //無頭節點,隨機給出單鏈表中一個非頭節點,刪除該節點,當傳入空節點,或者尾節點時,返回false  
  2. //思路:由於沒有頭節點,非循環單鏈表,無法獲取目標節點的前節點,所以只能把它的next節點數據前移,並刪除next節點  
  3. //ps:當傳入節點爲尾節點,無法用此方法刪除  
  4. bool withouthead_delete_node(node *target_node)  
  5. {  
  6.     node *cur = NULL;  
  7.     if(target_node == NULL || target_node->next == NULL)   //空節點或者尾節點,失敗  
  8.     {  
  9.         return false;  
  10.     }  
  11.     cur = target_node->next;  
  12.     target_node->name = cur->name;  
  13.     target_node->next = cur->next;  
  14.     delete cur;  
  15.     return true;  
  16. }  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章