【剑指offer】调整链表偶数奇数顺序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41035588/article/details/81913764

题目1

给定一个单链表,使得链表中偶数位于奇数之前。

  • Input: 17->15->8->12->10->5->4->1->7->6->NULL
  • Output: 8->12->10->4->6->17->15->5->1->7->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采用类似于“单链表的快速排序”的思路,代码简洁,但是不能保证奇数偶数内部的相对顺序。

segregate1


void segregate1(LNode **head_ref)
{
  LNode *end = *head_ref;
  
  LNode *prev = NULL;
  LNode *curr = *head_ref;
  //给一个指针指向最后节点
  while(end->next != NULL)
       end = end->next; 
  
  LNode *new_end = end;
  
  while(curr->data %2 != 0 && curr != end)
  {
    new_end->next = curr;
    curr = curr->next;
    new_end->next->next = NULL;
    new_end = new_end->next;
  }   
  
  if (curr->data%2 == 0)
  {
  
    *head_ref = curr;     
   
    while(curr != end)
    {
      if ( (curr->data)%2 == 0 )
      {
         prev = curr;
         curr = curr->next;
      }
      else
      {
         prev->next = curr->next;
         curr->next = NULL;
         new_end->next = curr;
         new_end = curr;
         curr = prev->next;
      }
    }
  }
  
  else  
    prev = curr;
  
  if((end->data)%2 != 0)
  {
      prev->next = end->next;
      end->next = NULL;
      new_end->next = end;
  }
  return;
}

segregate2


LNode* segregate2(LNode* head)
{
	if(head){
		LNode* pslow = head;
		LNode* pfast = NULL;
 
		// find the 1st odd node in the linked list,
		// and save the pointer to node in pslow.
		while(pslow && !(pslow->data & 1)){
			pslow = pslow->next;
		}
 
		if(pslow){ // now pslow points to the 1st odd node.
			pfast = pslow->next;
			while(pfast){
				if(!(pfast->data & 1)){
					swap(pfast->data, pslow->data);
					pslow = pslow->next;
				}
				pfast = pfast->next;
			}
		}
	}
	return head;
}

题目2

给定一个单链表,使得奇数位置的元素位于偶数位置元素之前。

  • 比如说:1->2->4->5->6->NULL,调整以后1->4->6->2->5->NULL。

解析

这道题和上面一道题的区别是:不是把链表中偶数元素位于奇数元素之前,而是奇数位置的元素位于偶数位置元素之前。设置三个指针,指针odd指向奇数位置的元素,指针even指向偶数位置的元素,指针evenHead指向第一个偶数位置的元素,按照奇数位置和偶数位置把链表划分为两部分,然后,奇数链表尾指针指向偶数位置首指针。时间复杂度也是o(n)。

参考代码

    ListNode* oddEvenList(ListNode* head)
    {
    	if (head == NULL || head->next == NULL)
    		return head;
    		
    	ListNode *odd = head;
    	ListNode *even = head->next;
    	ListNode *evenHead = even;
    	
    	while (even != NULL && even->next != NULL)
    	{
    		odd->next = even->next;
    		odd = odd->next;
    		even->next = odd->next;
    		even = even->next;
    	}
    	odd->next = evenHead;
    	return head;
    }

结语

编程最高境界就是,随手撸出来的代码很健壮!!!

猜你喜欢

转载自blog.csdn.net/qq_41035588/article/details/81913764