算法-排序

101 阅读3分钟

快速排序:

思路.

1.确认分割点,可以选择q[l] 中中点或者 最右的端点。

2.使得分割点的左边小于等于分割点,右边大于等于分割点

3.递归处理左右两端

  1. #include
  2. #define LEN 12 // 宏定义数组的大小
  3. static int tmp[LEN] = {0};// 设置临时数组
  4. // 打印数组
  5. void print_array(int *array)
  6. {
  7. int index = 0;
<div>printf("\narray:\n");</div>
</div>

11.

<div>for (; index < LEN; index++){</div>

</div>

12.

<div>printf(" %d, ", *(array + index));</div>

</div>

13.

<div>}</div>

</div>

14.

<div>printf("\n");</div>

</div>

15.

<div>}</div>

</div>

17.

<div>// 把两个有序的数组排序成一个数组</div>

</div>

18.

<div>void _mergeSort(int *array, int start, int middle, int end)</div>

</div>

19.

<div>{</div>

</div>

20.

<div>int first = start;</div>

</div>

21.

<div>int second = middle + 1;</div>

</div>

22.

<div>int index = start;</div>

</div>

23.

<div>while ((first <= middle) && (second <= end)){</div>

</div>

24.

<div>if (array[first] >= array[second])</div>

</div>

25.

<div>tmp[index++] = array[second++];</div>

</div>

26.

<div>else</div>

</div>

27.

<div>tmp[index++] = array[first++];</div>

</div>

28.

<div>}</div>

</div>

29.

<div>while(first <= middle) tmp[index++] = array[first++];</div>

</div>

30.

<div>while(second <= end) tmp[index++] = array[second++];</div>

</div>

32.

<div>for (first = start; first <= end; first++)</div>

</div>

33.

<div>array[first] = tmp[first];</div>

</div>

34.

<div>}</div>

</div>

36.

<div>// 递归划分数组</div>

</div>

37.

<div>void mergeSort(int *array, int start, int end)</div>

</div>

38.

<div>{</div>

</div>

39.

<div>if (start >= end)</div>

</div>

40.

<div>return;</div>

</div>

41.

<div>int middle = ((end + start) >> 1);</div>

</div>

42.

<div>mergeSort(array, start, middle);// 递归划分左边的数组</div>

</div>

43.

<div>mergeSort(array, middle+1, end);// 递归划分右边的数组</div>

</div>

44.

<div>_mergeSort(array, start, middle, end);// 对有序的两个数组进行合并成一个有序的数组</div>

</div>

45.

<div>}</div>

</div>

47.

<div>int main(void)</div>

</div>

48.

<div>{</div>

</div>

49.

<div>int array[LEN] = {2, 1, 4, 0, 12, 520, 2, 9, 5, 3, 13, 14};</div>

</div>

50.

<div>print_array(array);</div>

</div>

51.

<div>mergeSort(array, 0, LEN-1);</div>

</div>

52.

<div>print_array(array);</div>

</div>

53.

<div>return 0;</div>

</div>

54.

<div>}</div>

</div>

算法2 :歸并排序:

思路:

1.找到分界點(終點(l+r)>>1)

2.遞歸排序左邊和右邊

3.合并兩個區間

时间复杂度的分析 

n.Log2N (因为总共有Log2N层(每次从1-》n,每次变成原来的2被,因此可以用对数表示需要的次数,乘法银子的话,说明的是每层需要的时间))

整数二分:

单调性不是必要的

              vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

大部分满足单调性;百分之95的情况满足二段性质;

两个模板;

区别:

1. 不同性质部分的端点的区间不一样(更具mid的值来更新);

2.mid的更新也不一样,在模板二的时候需要上取整,要不然会死循环

1.确定边界

2.编写框架

3.设计一个check函数(),一段满足这个性质,另一段不满足这个性质。因此是红色那段的模板

4.判断如何更新

5.如果l=mid,r=mid-1, 算mid的时候+1

public int mySqrt(int x) 

 { 

 int l = 0;

 int r = x; 

 while (l < r) 

 { int mid = l + r + 1 >> 1; 

 if (mid*mid > x)//因爲滿足的條件在左邊,所以不需要等於,如果這個條件成立,表示在的是綠顏色的部分,所以需要更新r的值 。表示紅色的部分,表示模板2,因此mid需要向上除;

 r = mid-1;//否則需要更新l的值 

 else 

 { l=mid; } 

 } 

 return l;

 }

//https://www.acwing.com/blog/content/31/ 二分模板

Leetcode 35:

正確題解:

das

class Solution

 {

 public int searchInsert(int[] nums, int target) 

 {

 if (nums.length == 0) return 0;

 if (nums[nums.length - 1] < target) 

 return nums.length ; int l = 0; int r = nums.length - 1; 

 while (l < r) 

 { int mid = l + r >> 1; 

 if (nums[mid] >= target) 

 { 

 r = mid; 

 }

 else 

 { 

 l = mid + 1; 

 } 

 } 

 return l; 

 } 

}

疑問點:到底什麽時候用模板一,什麽時候用模板2呀(應該是 兩個都可以做出來)

因爲num[mid]<=target的話,找到這個剛好等於的邊界也可以呀