把链表中的奇偶数分开

65 篇文章 1 订阅
46 篇文章 0 订阅


http://blog.csdn.net/jiyanfeng1/article/details/8607889

Segregate even and odd nodes in a Linked List

给你一个单链表,修改此单链表,使得前面是偶数,后面是奇数。偶数间的相对顺序不变,奇数间的相对顺序不变。返回修改后的单链表的头节点。

例如:

Input: 17->15->8->12->10->5->4->1->7->6->NULL
Output: 8->12->10->4->6->17->15->5->1->7->NULL

Input: 8->12->10->5->4->1->6->NULL
Output: 8->12->10->4->6->5->1->NULL

// If all numbers are even then do not change the list
Input: 8->12->10->NULL
Output: 8->12->10->NULL

// If all numbers are odd then do not change the list
Input: 1->3->5->7->NULL
Output: 1->3->5->7->NULL

下面给出了两个函数,第一个函数segregate1可以保有奇偶数内部的相对顺序。第二个函数segregate2采用类似于“单链表的快速排序”的思路,代码简洁,但是不能保证奇数偶数内部的相对顺序。

代码如下:

[cpp]  view plain  copy
  1. void segregate1(LNode **head_ref)  
  2. {  
  3.   LNode *end = *head_ref;  
  4.     
  5.   LNode *prev = NULL;  
  6.   LNode *curr = *head_ref;  
  7.     
  8.   /* Get pointer to the last node */  
  9.   while(end->next != NULL)  
  10.        end = end->next;   
  11.     
  12.   LNode *new_end = end;  
  13.     
  14.   /* Consider all odd nodes before the first even node 
  15.      and move then after end */  
  16.   while(curr->data %2 != 0 && curr != end)  
  17.   {  
  18.     new_end->next = curr;  
  19.     curr = curr->next;  
  20.     new_end->next->next = NULL;  
  21.     new_end = new_end->next;  
  22.   }     
  23.     
  24.   // 10->8->17->17->15  
  25.   /* Do following steps only if there is any even node */  
  26.   if (curr->data%2 == 0)  
  27.   {  
  28.     /* Change the head pointer to point to first even node */  
  29.     *head_ref = curr;       
  30.     /* now current points to the first even node */  
  31.     while(curr != end)  
  32.     {  
  33.       if ( (curr->data)%2 == 0 )  
  34.       {  
  35.          prev = curr;  
  36.          curr = curr->next;  
  37.       }  
  38.       else  
  39.       {  
  40.          /* break the link between prev and current */  
  41.          prev->next = curr->next;   
  42.           /* Make next of curr as NULL  */  
  43.          curr->next = NULL;  
  44.          /* Move curr to end */  
  45.          new_end->next = curr;  
  46.          /* make curr as new end of list */  
  47.          new_end = curr;  
  48.          /* Update current pointer to next of the moved node */  
  49.          curr = prev->next;  
  50.       }  
  51.     }  
  52.   }  
  53.     
  54.   /* We must have prev set before executing lines following this  
  55.      statement */  
  56.   else    
  57.     prev = curr;  
  58.     
  59.   /* If the end of the original list is odd then move this node to 
  60.     end to maintain same order of odd numbers in modified list */  
  61.   if((end->data)%2 != 0)  
  62.   {  
  63.       prev->next = end->next;  
  64.       end->next = NULL;  
  65.       new_end->next = end;  
  66.   }  
  67.   return;  
  68. }  
  69.   
  70. LNode* segregate2(LNode* head)  
  71. {// Note that this function cannot maintain the  
  72.  // relative order inside odd numbers and even numbers.  
  73.  // For example, 10->9->7->5->2->NULL becomes the following  
  74.  // 10->2->7->5->9->NULL.  
  75.     if(head){  
  76.         LNode* pslow = head;  
  77.         LNode* pfast = NULL;  
  78.   
  79.         // find the 1st odd node in the linked list,  
  80.         // and save the pointer to node in pslow.  
  81.         while(pslow && !(pslow->data & 1)){  
  82.             pslow = pslow->next;  
  83.         }  
  84.   
  85.         if(pslow){ // now pslow points to the 1st odd node.  
  86.             pfast = pslow->next;  
  87.             while(pfast){  
  88.                 if(!(pfast->data & 1)){  
  89.                     swap(pfast->data, pslow->data);  
  90.                     pslow = pslow->next;  
  91.                 }  
  92.                 pfast = pfast->next;  
  93.             }  
  94.         }  
  95.     }  
  96.     return head;  
  97. }  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值