大厂笔试题
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
6.8 KiB

  1. #include <stdio.h>
  2. // 1.插入排序,时间复杂度O(n2),空间复杂度O(1)
  3. void InsertSort(int a[], int n)
  4. {
  5. for (int i = 1; i < n; i++)
  6. {
  7. // 若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入
  8. if (a[i] < a[i - 1])
  9. {
  10. int j = i - 1;
  11. // 复制为哨兵,即存储待排序元素
  12. int x = a[i];
  13. // 先后移一个元素
  14. a[i] = a[i - 1];
  15. // 查找在有序表的插入位置
  16. while (x < a[j])
  17. {
  18. a[j + 1] = a[j];
  19. // 元素后移
  20. j--;
  21. }
  22. // 插入到正确位置
  23. a[j + 1] = x;
  24. }
  25. }
  26. }
  27. // 2.希尔排序,时间复杂度O(N^1.5),空间复杂度O(1)
  28. void ShellInsertSort(int a[], int n, int dk)
  29. {
  30. for (int i = dk; i < n; ++i)
  31. {
  32. if (a[i] < a[i - dk])
  33. { // 若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入
  34. int j = i - dk;
  35. int x = a[i]; // 复制为哨兵,即存储待排序元素
  36. a[i] = a[i - dk]; // 首先后移一个元素
  37. while (j >= 0 && x < a[j])
  38. { // 查找在有序表的插入位置
  39. a[j + dk] = a[j];
  40. j -= dk; // 元素后移
  41. }
  42. a[j + dk] = x; // 插入到正确位置
  43. }
  44. }
  45. }
  46. void ShellSort(int a[], int n)
  47. {
  48. int dk = n / 2;
  49. while (dk >= 1)
  50. {
  51. ShellInsertSort(a, n, dk);
  52. dk = dk / 2;
  53. }
  54. }
  55. // 选择排序,时间复杂度:O(N^2), 空间复杂度:O(1)
  56. int SelectMinKey(int a[], int n, int i)
  57. {
  58. int k = i;
  59. for (int j = i + 1; j < n; ++j)
  60. {
  61. if (a[k] > a[j])
  62. k = j;
  63. }
  64. return k;
  65. }
  66. void SelectSort(int a[], int n)
  67. {
  68. int key, tmp;
  69. for (int i = 0; i < n - 1; ++i)
  70. {
  71. key = SelectMinKey(a, n, i); // 选择最小的元素
  72. if (key != i)
  73. {
  74. tmp = a[i];
  75. a[i] = a[key];
  76. a[key] = tmp; // 最小元素与第i位置元素互换
  77. }
  78. }
  79. }
  80. // 堆排序,时间复杂度:O(N*logN),空间复杂度:O(1)
  81. void HeapAdjust(int H[], int s, int length)
  82. {
  83. int tmp = H[s];
  84. int child = 2 * s + 1; // 左孩子结点的位置。(i+1 为当前调整结点的右孩子结点的位置)
  85. while (child < length)
  86. {
  87. if (child + 1 < length && H[child] < H[child + 1])
  88. { // 如果右孩子大于左孩子(找到比当前待调整结点大的孩子结点)
  89. ++child;
  90. }
  91. if (H[s] < H[child])
  92. { // 如果较大的子结点大于父结点
  93. H[s] = H[child]; // 那么把较大的子结点往上移动,替换它的父结点
  94. s = child; // 重新设置s ,即待调整的下一个结点的位置
  95. child = 2 * s + 1;
  96. }
  97. else
  98. { // 如果当前待调整结点大于它的左右孩子,则不需要调整,直接退出
  99. break;
  100. }
  101. H[s] = tmp; // 当前待调整的结点放到比其大的孩子结点位置上
  102. }
  103. }
  104. /**
  105. *
  106. * H[0..length-1]
  107. *
  108. */
  109. void BuildingHeap(int H[], int length)
  110. {
  111. // 最后一个有孩子的节点的位置 i= (length -1) / 2
  112. for (int i = (length - 1) / 2; i >= 0; --i)
  113. HeapAdjust(H, i, length);
  114. }
  115. /**
  116. *
  117. */
  118. void HeapSort(int H[], int length)
  119. {
  120. // 初始堆
  121. BuildingHeap(H, length);
  122. // 从最后一个元素开始对序列进行调整
  123. for (int i = length - 1; i > 0; --i)
  124. {
  125. // 交换堆顶元素H[0]和堆中最后一个元素
  126. int temp = H[i];
  127. H[i] = H[0];
  128. H[0] = temp;
  129. // 每次交换堆顶元素和堆中最后一个元素之后,都要对堆进行调整
  130. HeapAdjust(H, 0, i);
  131. }
  132. }
  133. // 冒泡排序,时间复杂度:O(N^2),空间复杂度:O(1)
  134. void BubbleSort(int r[], int n)
  135. {
  136. int low = 0;
  137. int high = n - 1; // 设置变量的初始值
  138. int tmp, j;
  139. while (low < high)
  140. {
  141. for (j = low; j < high; ++j) // 正向冒泡,找到最大者
  142. if (r[j] > r[j + 1])
  143. {
  144. tmp = r[j];
  145. r[j] = r[j + 1];
  146. r[j + 1] = tmp;
  147. }
  148. --high; // 修改high值, 前移一位
  149. for (j = high; j > low; --j) // 反向冒泡,找到最小者
  150. if (r[j] < r[j - 1])
  151. {
  152. tmp = r[j];
  153. r[j] = r[j - 1];
  154. r[j - 1] = tmp;
  155. }
  156. ++low; // 修改low值,后移一位
  157. }
  158. }
  159. // 快速排序递归实现,时间复杂度:O(N*logN), 空间复杂度:O(logN)
  160. int QuickSort(int *a, int low, int high)
  161. {
  162. int i = low; // 第一位
  163. int j = high; // 最后一位
  164. int key = a[i]; // 将第一个数作为基准值-- 先找到一个基准值
  165. while (i < j)
  166. {
  167. while (i < j && a[j] >= key)
  168. {
  169. j--;
  170. }
  171. a[i] = a[j];
  172. while (i < j && a[i] <= key)
  173. {
  174. i++;
  175. }
  176. a[j] = a[i];
  177. }
  178. a[i] = key;
  179. if (i - 1 > low)
  180. {
  181. QuickSort(a, low, i - 1);
  182. }
  183. if (i + 1 < high)
  184. {
  185. QuickSort(a, i + 1, high);
  186. }
  187. return 0;
  188. }
  189. // 归并排序迭代实现,时间复杂度:O(N*logN), 空间复杂度:O(N)
  190. void merge(int arr[], int start, int mid, int end, int len)
  191. {
  192. int result[len];
  193. int k = 0;
  194. int i = start;
  195. int j = mid + 1;
  196. while (i <= mid && j <= end)
  197. {
  198. if (arr[i] < arr[j])
  199. {
  200. result[k++] = arr[i++];
  201. }
  202. else
  203. {
  204. result[k++] = arr[j++];
  205. }
  206. }
  207. if (i == mid + 1)
  208. {
  209. while (j <= end)
  210. result[k++] = arr[j++];
  211. }
  212. if (j == end + 1)
  213. {
  214. while (i <= mid)
  215. result[k++] = arr[i++];
  216. }
  217. for (j = 0, i = start; j < k; i++, j++)
  218. {
  219. arr[i] = result[j];
  220. }
  221. }
  222. void MergeSort(int arr[], int start, int end, int len)
  223. {
  224. if (start >= end)
  225. return;
  226. int mid = (start + end) / 2;
  227. MergeSort(arr, start, mid, len);
  228. MergeSort(arr, mid + 1, end, len);
  229. merge(arr, start, mid, end, len);
  230. }
  231. int main()
  232. {
  233. int i;
  234. int array[] = {9, 5, 6, 1, 4, 7, 3, 8, 2};
  235. int array2[9];
  236. // InsertSort(array, sizeof(array)/sizeof(array[0]));
  237. // ShellSort(array, sizeof(array)/sizeof(array[0]));
  238. // SelectSort(array, sizeof(array)/sizeof(array[0]));
  239. // HeapSort(array, sizeof(array)/sizeof(array[0]));
  240. // BubbleSort(array, sizeof(array)/sizeof(array[0]));
  241. // QuickSort(array, 0, 9-1);
  242. int len = sizeof(array) / sizeof(array[0]);
  243. MergeSort(array, 0, 9 - 1, len);
  244. printf("sort result is:");
  245. for (i = 0; i < 9; i++)
  246. {
  247. printf("%d", array[i]);
  248. }
  249. return 0;
  250. }