指针首尾并进

  1. 快排分割数组首尾的实现方式。
  2. 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)
  3. 输入一个增序数组和一个数sum,在数组中找到两个数,使得和为sum。输入任意一对即可。

1、思路:

  先随机选base,与尾交换。然后从左往右遍历,找到比base大的数,交换;从右往左遍历,找到比base小的数,交换。

《指针首尾并进》
《指针首尾并进》
QuickSort

 1 #include <iostream>
 2 #include <exception>
 3 #include <stdlib.h>
 4 #include <string.h>
 5 
 6 using namespace std;
 7 
 8 int RandInRange(int a, int b)
 9 {
10      return rand()%(b - a + 1) + a;
11 }
12 
13 void PrintArray(int data[], int length)
14 {
15     for (int i = 0; i < length; i++)
16         printf("%d ", data[i]);
17     printf("\n");
18 }
19     
20 int Partition(int data[], int length, int start, int end)
21 {
22     if (data == NULL || length <= 0 || start < 0 || end >= length)
23         throw new exception();
24 
25     int index = RandInRange(start, end);
26     int base = data[index];
27     swap(data[start], data[index]);
28 
29     while(start < end)
30     {
31         while (start < end && data[end] > base)
32             end--;
33         data[start] = data[end];
34         while (start < end && data[start] < base)
35             start++;
36         data[end] = data[start];
37     }
38 
39     data[start] = base;
40     return start;
41 }
42 
43 void QuickSort(int data[], int length, int start, int end)
44 {
45     if (start == end)
46         return;
47     int index = Partition(data, length, start, end);
48     if (index > start)
49         QuickSort(data, length, start, index - 1);
50     if (index < end)
51         QuickSort(data, length, start + 1, end);
52 }
53 
54 int main()
55 {
56     int test[7] = {23, 13, 49, 6, 31, 19, 28};
57     PrintArray(test, 7);
58     QuickSort(test, 7, 0, 6);
59     PrintArray(test, 7);
60 }

 

2、思路:

  设置两个指针,首尾位置。首指针往后移直到遇到偶数,尾指针往前移直到遇到奇数,两者都遇到的情况下互换位置,终止条件是首尾指针碰头。

《指针首尾并进》
《指针首尾并进》
ReorderOddEven

 1 void ReorderOddEven(int *pData, unsigned int length)
 2 {
 3     if(pData == NULL || length == 0)
 4         return;
 5 
 6     int *pBegin = pData;
 7     int *pEnd = pData + length - 1;
 8 
 9     while(pBegin < pEnd)
10     {
11         // 向后移动pBegin,直到它指向偶数
12         while(pBegin < pEnd && (*pBegin & 0x1) != 0)
13             pBegin ++;
14 
15         // 向前移动pEnd,直到它指向奇数
16         while(pBegin < pEnd && (*pEnd & 0x1) == 0)
17             pEnd --;
18 
19         if(pBegin < pEnd)
20         {
21             int temp = *pBegin;
22             *pBegin = *pEnd;
23             *pEnd = temp;
24         }
25     }
26 }

 

 3、思路:

  如果原数组是无序的,则先排序,O(nlogn)开销。这里已经是增序排列了,所以不需要排序。设置两个指针,一头一尾。当和大于s,尾指针往前移;当和小于s,头指针往后移。直到两指针相遇,看是否有符合要求的数出现。

《指针首尾并进》
《指针首尾并进》
FindNumbersWithSum

 1 FindNumbersWithSum 
 2  bool FindNumbersWithSum(int data[], int length, int sum, int *num1, int *num2)
 3  {
 4      bool found = false;
 5      if (length < 1 || num1 == NULL || num2 == NULL)
 6          return found;
 7      int ahead = length - 1;
 8      int behind = 0;
 9      while (ahead > behind)
10      {
11          long long curSum = data[ahead] + data[behind];
12          if (curSum == sum)
13          {
14              *num1 = data[behind];
15              *num2 = data[ahead];
16              found = true;
17              break;
18          }
19          else if (curSum > sum)
20              ahead--;
21          else
22              behind++;
23      }
24      return found;
25  }

 

 

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/wangpengjie/archive/2013/04/16/3024990.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注