学习目录:
-
选择排序
-
冒泡排序
-
插入排序
-
归并排序
-
二分法
-
异或运算
详细解析后期会补上,目前先更新代码块
选择排序( 时间复杂度,O(N2) )
1 void selectSort(int array[], int len) 2 { 3 if (array == NULL || len < 2) 4 { 5 return; 6 } 7 for (int i = 0; i < len - 1; i++) 8 { 9 int minIndex = i; 10 for (int j = i + 1; j < len; j++) 11 { 12 if (array[j] < array[minIndex]) 13 { 14 Swap(array, minIndex, j); 15 } 16 } 17 } 18 }
冒泡排序( 时间复杂度,O(N2) )
1 void BubbleSort(int array[], int len) 2 { 3 if (array == NULL || len < 2) 4 { 5 return; 6 } 7 for (int i = len - 1; i > 0; i--) 8 { 9 for (int j = 0; j < i; j++) 10 { 11 if (array[j] > array[j + 1]) 12 { 13 Swap(array, i, j); 14 } 15 } 16 } 17 }
插入排序( 时间复杂度,最优O(N),最差O(N2) )
1 void insertSort(int array[], int len) 2 { 3 if (array == NULL || len < 2) 4 { 5 return; 6 } 7 for (int i = 1; i < len; i++) 8 { 9 for (int j = i - 1; j >= 0 && array[j] > array[j + 1]; j--) 10 { 11 Swap(array, j, j + 1); 12 } 13 } 14 }
归并排序(时间复杂度,O(N*logN) )
1 void merge(int array[], int L, int M, int R) 2 { 3 vector<int>help; 4 int p1 = L; 5 int p2 = M + 1; 6 while (p1 <= M && p2 <= R) 7 { 8 help.push_back(array[p1] <= array[p2] ? array[p1++] : array[p2++]); 9 } 10 while (p1 <= M) 11 { 12 help.push_back(array[p1++]); 13 } 14 while (p2 <= R) 15 { 16 help.push_back(array[p2++]); 17 } 18 for (int i = 0; i < help.size(); i++) 19 { 20 array[L + i] = help.at(i); 21 } 22 } 23 24 void mergeSort(int array[], int L, int R) 25 { 26 if (L == R) 27 { 28 return; 29 } 30 int mid = L + ((R - L) >> 1); 31 mergeSort(array, L, mid); 32 mergeSort(array, mid + 1, R); 33 merge(array, L, mid, R); 34 } 35 36 void mergeSort(int array[], int len) 37 { 38 if (array == NULL || len < 2) 39 { 40 return; 41 } 42 mergeSort(array, 0, len - 1); 43 }
二分法(时间复杂度,O(logN) )
注:不一定是有序才能二分,例如 局部最小值问题
1 bool binarySort(int array[], int len, int num) 2 { 3 if (array == NULL || len == 0) 4 { 5 return false; 6 } 7 int L = 0; 8 int R = len + 1; 9 int mid = 0; 10 while (L < R) 11 { 12 mid = L + ((R - L) >> 1); 13 if (array[mid] == num) 14 { 15 return true; 16 } 17 else if (array[mid] < num) 18 { 19 R = mid - 1; 20 } 21 else if (array[mid] > num) 22 { 23 L = mid + 1; 24 } 25 } 26 return array[L] == num; 27 }
用二分法解决问题
题目:在一个有序数组中,找>=某个数最左侧的位置
1 int binarySolve(int array[],int len,int num) 2 { 3 int L = 0; 4 int R = len - 1; 5 int mid = 0; 6 int index = -1; 7 while (L < R) 8 { 9 mid = L + ((R - L) >> 1); 10 if (array[mid] >= num) 11 { 12 index = mid; 13 R = mid - 1; 14 } 15 else 16 { 17 L = mid + 1; 18 } 19 } 20 return index; 21 }
用异或运算交换值
void Swap(int array[], int i, int j) { array[i] = array[i] ^ array[j]; array[j] = array[i] ^ array[j]; array[i] = array[i] ^ array[j]; }
用异或运算解决问题
题目:一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到这个两个数
分析:
首先,将所有的数全部异或,然后得到的结果,就是奇数A与奇数B异或的结果。
因为异或相同的要变成0,所以说,A^B异或的结果肯定有一个1。
然后去取出这个结果最右侧的1,提出来之后,再用这个1去跟所有的数去做 与 操作,
如果 与 操作的结果是1 ,那么就跟这个数进行 异或 操作。这样就得出来了A或者B中的一个值
再用这个值 去跟 A^B异或,然后得出另一个值,这两个奇数答案就出来了。
1 void findodd(int array[], int len) 2 { 3 int eor=0; 4 for (int i = 0; i < len; i++) 5 { 6 eor ^= array[i]; 7 } 8 //eor = a^b; 两个奇数 9 //现在要找出最右侧的1 10 int rightone = eor & (~eor + 1); 11 //把有1的跟其中一组奇数进行异或 12 int onlyone = 0; 13 for (int i = 0; i < len; i++) 14 { 15 if ((rightone&array[i])!=0) 16 { 17 onlyone^= array[i]; 18 } 19 } 20 int res = onlyone ^ eor; 21 cout << onlyone << " " << res; 22 }
递归解题
题目:求一个数组中的最大值
1 int process(int array[], int L, int R) 2 { 3 if (L == R) 4 { 5 return array[L]; 6 } 7 int mid = L + ((R - L) >> 1); 8 int left = process(array, L, mid); 9 int right = process(array, mid + 1, R); 10 return max(left, right); 11 } 12 13 int getMax(int array[], int len) 14 { 15 return process(array, 0, len - 1); 16 }