大厂笔试题
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.

302 lines
9.0 KiB

  1. #include<iostream>
  2. using namespace std;
  3. int len = 10;
  4. int a[10] = {5,7,2,6,4,1,3,9,8,10};
  5. /*
  6. *,O(N^2)O(1)
  7. *n-1
  8. */
  9. void MaoPao(int a[]){
  10. int temp;
  11. int flag = 0;
  12. // n-1趟排序
  13. for(int i = 0; i < len - 1; i++){
  14. for(int j = 0; j < len - 1 -i; j++){
  15. if(a[j] > a[j + 1]){
  16. temp = a[j];
  17. a[j] = a[j + 1];
  18. a[j + 1] = temp;
  19. flag = 1;
  20. }
  21. }
  22. // 若某一趟排序中没有元素交换则说明所有元素已经有序,不需要再排序
  23. if(flag == 0)break;
  24. }
  25. }
  26. /*
  27. *O(N^2)O(1)
  28. *
  29. */
  30. void ChaRu(int a[]){
  31. // 从第一轮就从第二个元素开始找,所以n-1轮就可以
  32. for(int i = 0; i < len - 1; i++){
  33. // 已经有序的最后一个元素
  34. int end = i;
  35. // 需要排序的元素
  36. int temp = a[end + 1];
  37. while(end >= 0){
  38. if(a[end] > temp){
  39. // 直接替换 循环外面再将被替换的值放到适当位置
  40. a[end + 1] = a[end];
  41. end--;
  42. }
  43. else{
  44. break;
  45. }
  46. }
  47. a[end + 1] = temp;
  48. }
  49. }
  50. /*
  51. *O(N^1.5)O(1)
  52. *gapgap个组gap的记录分在同一组内gap逐渐减小重复上述分组和排序的工作gap=1
  53. */
  54. void ShellSort(int a[], int n){
  55. int gap = n;
  56. while (gap > 1)
  57. {
  58. //gap /= 2;
  59. gap = gap / 3 + 1;
  60. for (int i = 0; i < n - gap; i++)
  61. {
  62. int end = i;
  63. int x = a[end + gap];
  64. while (end >= 0)
  65. {
  66. if (a[end] > x)
  67. {
  68. a[end + gap] = a[end];
  69. end -= gap;
  70. }
  71. else
  72. {
  73. break;
  74. }
  75. }
  76. a[end + gap] = x;
  77. }
  78. }
  79. }
  80. /*
  81. *O(N^2); O(1);
  82. *()()().
  83. */
  84. void SelectSort(int a[], int n){
  85. //保存数组的起始位置
  86. int begin = 0;
  87. //保存换数组的末尾位置
  88. int end = n - 1;
  89. int temp;
  90. while (begin < end)
  91. {
  92. int maxi = begin;//保存最大元素下标
  93. int mini = begin;//保存最小元素下标
  94. //遍历数组寻找最小和最大元素
  95. for (int i = begin; i <= end; i++)
  96. {
  97. if (a[i] < a[mini])
  98. {
  99. mini = i;
  100. }
  101. if (a[i] > a[maxi])
  102. {
  103. maxi = i;
  104. }
  105. }
  106. //将最小元素交换到起始位置
  107. temp = a[begin];
  108. a[begin] = a[mini];
  109. a[mini] = temp;
  110. //判断最大值的位置是否在起始位置
  111. if (maxi == begin)
  112. {
  113. maxi = mini;
  114. }
  115. //将最大元素交换到末尾位置
  116. temp = a[end];
  117. a[end] = a[maxi];
  118. a[maxi] = temp;
  119. //移动数组起始和末尾位置
  120. begin++;
  121. end--;
  122. }
  123. }
  124. /*
  125. *O(N*logN)O(1)
  126. *
  127. */
  128. void HeapAdjust(int H[], int s, int length)
  129. {
  130. int tmp = H[s];
  131. // 左孩子结点的位置。(i+1 为当前调整结点的右孩子结点的位置)
  132. int child = 2 * s + 1;
  133. while (child < length)
  134. {
  135. if (child + 1 < length && H[child] < H[child + 1])
  136. { // 如果右孩子大于左孩子(找到比当前待调整结点大的孩子结点)
  137. child++;
  138. }
  139. if (H[s] < H[child])
  140. { // 如果较大的子结点大于父结点
  141. H[s] = H[child]; // 那么把较大的子结点往上移动,替换它的父结点
  142. s = child; // 重新设置s ,即待调整的下一个结点的位置
  143. child = 2 * s + 1;
  144. }
  145. else
  146. { // 如果当前待调整结点大于它的左右孩子,则不需要调整,直接退出
  147. break;
  148. }
  149. H[s] = tmp; // 当前待调整的结点放到比其大的孩子结点位置上
  150. }
  151. }
  152. /**
  153. *
  154. * H[0..length-1]
  155. *
  156. */
  157. void BuildingHeap(int H[], int length)
  158. {
  159. // 最后一个有孩子的节点的位置 i= (length -1) / 2
  160. for (int i = (length - 1) / 2; i >= 0; --i)
  161. HeapAdjust(H, i, length);
  162. }
  163. void HeapSort(int H[], int length)
  164. {
  165. // 初始堆
  166. BuildingHeap(H, length);
  167. // 从最后一个元素开始对序列进行调整
  168. for (int i = length - 1; i > 0; --i)
  169. {
  170. // 交换堆顶元素H[0]和堆中最后一个元素
  171. int temp = H[i];
  172. H[i] = H[0];
  173. H[0] = temp;
  174. // 每次交换堆顶元素和堆中最后一个元素之后,都要对堆进行调整
  175. HeapAdjust(H, 0, i);
  176. }
  177. }
  178. /*
  179. *O(N*logN)O(logN)
  180. *left right left指针先走left和right指针对应位置的值left = right left(right)
  181. */
  182. int PartSort(int a[], int left, int right){
  183. // 选最右面为基准
  184. int key = right;
  185. while(left < right){
  186. //选右边为基准值,左指针先走
  187. while(left < right && a[left] <= a[key]){
  188. left++;
  189. }
  190. //右指针再走
  191. while(left < right && a[right] >= a[key]){
  192. right--;
  193. }
  194. // 交换
  195. int temp = a[right];
  196. a[right] = a[left];
  197. a[left] = temp;
  198. }
  199. int temp = a[key];
  200. a[key] = a[left];
  201. a[left] = temp;
  202. return left;
  203. }
  204. void QuickSort(int a[], int left, int right){
  205. if(left >= right)return;
  206. // 第一次快排
  207. int keyi = PartSort(a, left, right);
  208. // 左子序列快排
  209. QuickSort(a, left, keyi - 1);
  210. // 右子序列快排
  211. QuickSort(a, keyi + 1, right);
  212. }
  213. /*
  214. *O(N*logN)O(N)
  215. *使使
  216. */
  217. void _MergeSort(int* a, int left, int right,int* tmp)
  218. {
  219. //区间中没有元素时不再合并
  220. if (left >= right)
  221. {
  222. return;
  223. }
  224. //划分数组,每次一分为二
  225. int mid = (left + right) / 2;
  226. _MergeSort(a, left, mid,tmp);//划分左区间
  227. _MergeSort(a, mid + 1, right,tmp);//划分右区间
  228. //合并有序序列
  229. int begin1 = left, end1 = mid;//有序序列1
  230. int begin2 = mid + 1, end2 = right;//有序序列2
  231. int i = left;
  232. //注意结束条件为一个序列为空时就停止
  233. while (begin1 <= end1 && begin2 <= end2)
  234. {
  235. if (a[begin1] < a[begin2])
  236. {
  237. tmp[i++] = a[begin1++];
  238. }
  239. else
  240. {
  241. tmp[i++] = a[begin2++];
  242. }
  243. }
  244. //两序列不可能同时为空,将剩余元素合并
  245. while (begin1 <= end1)
  246. {
  247. tmp[i++] = a[begin1++];
  248. }
  249. while (begin2 <= end2)
  250. {
  251. tmp[i++] = a[begin2++];
  252. }
  253. //将合并后的序列拷贝到原数组中
  254. //在这里拷贝的原因是 保证返回到上一层递归后两个子序列中的元素是有序的
  255. int j = 0;
  256. for (j = left; j <= right; j++)
  257. {
  258. a[j] = tmp[j];
  259. }
  260. }
  261. void MergeSort(int* a, int n)
  262. {
  263. //因为需要将两个有序序列合并,需借助额外数组
  264. int* tmp = (int*)malloc(sizeof(int) * n);
  265. if (tmp == NULL)
  266. {
  267. perror("malloc");
  268. exit(-1);
  269. }
  270. _MergeSort(a, 0, n - 1,tmp);
  271. free(tmp);
  272. tmp = NULL;
  273. }
  274. int main(){
  275. // MaoPao(a);
  276. // ChaRu(a);
  277. // ShellSort(a, len);
  278. // SelectSort(a, len);
  279. // HeapSort(a, len);
  280. // QuickSort(a, 0, len - 1);
  281. // MergeSort(a, len);
  282. cout<<"out:"<<endl;
  283. for(int i = 0; i < len; i++){
  284. cout<<a[i];
  285. cout<<',';
  286. }
  287. }