冒泡排序
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int e = arr.length - 1; e > 0; e--) {
for (int i = 0; i < e; i++) {
if (arr[i] > arr[i + 1]) {
swap(arr, i, i + 1);
}
}
}
}
改写后的cpp代码
void bubbleSort(int arr[], int n) {
if ( !arr || n < 2)
return;
for (int e = arr.length - 1; e > 0; e--) {
for (int i = 0; i < e; i++) {
if (arr[i] > arr[i + 1]) {
swap(arr[i], arr[i + 1]); } } } }
选择排序
public static void selectionSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
minIndex = arr[j] < arr[minIndex] ? j : minIndex;
}
swap(arr, i, minIndex);
}
}
改写后的cpp代码
void selectSort(int arr[], int n) {
if ( !arr || n < 2)
return;
for (int i = 0; i < n-1; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++)
minIndex = arr[j]<arr[minIndex]? j : minIndex;
swap(arr[minIndex], arr[i]); } }
插入排序
public static void insertionSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 1; i < arr.length; i++) {
for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
swap(arr, j, j + 1);
}
}
}
改写后的cpp代码
void selectionSort(int arr[], int n)
{
if ( !arr || n < 2)
return;
for(int i = 1; i < n-1; i++) {
for (int j = i - 1; j >= 0 && arr[j] > arr[j-1]; j--)
swap(arr[j], arr[j+1]); } }
异或交换写法
void swap(int[] arr, int i, int j) {
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
对数器
随机样本产生器
例如生成长度随机元素随机的数组
#include <ctime>
std::vector generateRandomArray(int maxSize, int maxValue) {
srand(time(NULL));
int size = (int)(rand() % (maxSize - 1 + 1) + 1);
std::vector v;
v.resize(size);
for(int i=0; i<size; i++) {
v[i] = (int)(rand() % (maxSize - 1 + 1) + 1) - (int)(rand() % (maxSize - 1 - 1 + 1) + 1); }
return v; }
绝对正确的方法
例如在测试排序算法中,系统库自带的排序函数sort()
就可以视作为绝对正确的方法
进行数据量较大的测试,比较两种算法的结果
递归时间复杂度的计算
master公式
T(N) = aT(N/b) + O(N^d)
a是一次递归过程包括子过程的个数
N/b是子过程的数据量
O(N^d)是递归以外的时间复杂度
计算结果为
当 log(b, a) > d 时,时间复杂度为 O(N^log(b, a))
当 log(b, a) = d 时,时间复杂度为 O(N^d · logN)
当 log(b, a) < d 时,时间复杂度为 O(N^d)
例:在递归实现的归并排序中,参数a = 2,b = 2,d = 1,满足第二个条件,因此时间复杂度为 O(NlogN)
归并排序
public static void mergeSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
mergeSort(arr, 0, arr.length - 1);
}
public static void mergeSort(int[] arr, int l, int r) {
if (l == r) {
return;
}
int mid = l + ((r - l) >> 1);
mergeSort(arr, l, mid);
mergeSort(arr, mid + 1, r);
merge(arr, l, mid, r);
}
public static void merge(int[] arr, int l, int m, int r) {
int[] help = new int[r - l + 1];
int i = 0;
int p1 = l;
int p2 = m + 1;
while (p1 <= m && p2 <= r) {
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= m) {
help[i++] = arr[p1++];
}
while (p2 <= r) {
help[i++] = arr[p2++];
}
for (i = 0; i < help.length; i++) {
arr[l + i] = help[i];
}
}
修改使用cpp实现
void mergeSort(int arr[], int n) {
if (arr == NULL || arr.length < 2) {
return;
}
mergeSort(arr, 0, n-1);
}
void mergeSort(int arr[], int l, int r) {
if (l == r) {
return;
}
int mid = l + ((r - l) / 2);
mergeSort(arr, l, mid);
mergeSort(arr, mid + 1, r);
merge(arr, l, mid, r);
}
void merge(int arr[], int l, int m, int r) {
int* help = new int[r - l + 1];
int i = 0;
int p1 = l;
int p2 = m + 1;
while (p1 <= m && p2 <= r) {
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= m) {
help[i++] = arr[p1++];
}
while (p2 <= r) {
help[i++] = arr[p2++];
}
for (i = 0; i < r - l + 1; i++) {
arr[l + i] = help[i];
}
delete []help;
}
归并排序思想应用
小和问题
在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。
求一个数组的小和。
例子:
[1 3 4 2 5]
1左边比1小的数,没有;
3左边比3小的数, 1;
4左边比4小的数, 1、.3;
2左边比2小的数, 1;
5左边比5小的数, 1,3.4.2;
所以小和为1+1+3+1+1+3+4+2=16
public static int smallSum(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
return mergeSort(arr, 0, arr.length - 1);
}
public static int mergeSort(int[] arr, int l, int r) {
if (l == r) {
return 0;
}
int mid = l + ((r - l) >> 1);
return mergeSort(arr, l, mid) + mergeSort(arr, mid + 1, r) + merge(arr, l, mid, r);
}
public static int merge(int[] arr, int l, int m, int r) {
int[] help = new int[r - l + 1];
int i = 0;
int p1 = l;
int p2 = m + 1;
int res = 0;
while (p1 <= m && p2 <= r) {
res += arr[p1] < arr[p2] ? (r - p2 + 1) * arr[p1] : 0;
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= m) {
help[i++] = arr[p1++];
}
while (p2 <= r) {
help[i++] = arr[p2++];
}
for (i = 0; i < help.length; i++) {
arr[l + i] = help[i];
}
return res;
}
逆序对问题