今天跟着左老师的视频,理解了四种复杂度为 O(N*log(N))的排序算法,以前也理解过过程,今天根据实际的代码,感觉基本的算法还是很简单的,只是自己写的时候可能一些边界条件,循环控制条件把握不好。

  1. //对于一个int数组,请编写一个选择冒泡算法,对数组元素排序。
  2. //给定一个int数组A及数组的大小n,请返回排序后的数组。
  3. //测试样例:
  4. //[1, 2, 3, 5, 2, 3], 6
  5. //[1, 2, 2, 3, 3, 5]
  6.  
  7. #include <iostream>
  8. using namespace std;
  9. #include<string>
  10.  
  11. void printResult(string str,int* A,int n)
  12. {
  13. cout << str << "的结果:\n";
  14. for (int i = ; i < n; i++)
  15. {
  16. cout << A[i] <<" ";
  17. }
  18. cout << endl;
  19. }
  20. void swap(int *a, int *b)
  21. {
  22. int temp=*a;
  23. *a = *b;
  24. *b = temp;
  25. }
  26.  
  27. //冒泡排序 O(n^2)
  28. class BubbleSort {
  29. public:
  30. int* bubbleSort(int* A, int n) {
  31. // write code here
  32. for (int i = ; i<n; i++)
  33. {
  34. for (int j = ; j<n - i - ; j++)
  35. {
  36. if (A[j]>A[j + ])
  37. {
  38. int temp = A[j];
  39. A[j] = A[j + ];
  40. A[j + ] = temp;
  41. }
  42. }
  43. }
  44. return A;
  45. }
  46. };
  47.  
  48. //请编写一个选择排序算法 O(n^2)
  49. class SelectionSort {
  50. public:
  51. int* selectionSort(int* A, int n) {
  52. // write code here
  53. int k = ;
  54. for (int i = ; i < n-; i++)
  55. {
  56. k = i;
  57. for (int j = i; j < n; j++)
  58. {
  59. if (A[k]>A[j])
  60. {
  61. k = j;
  62. }
  63. }
  64. if (k!=i)
  65. {
  66. int temp = A[i];
  67. A[i] = A[k];
  68. A[k] = temp;
  69. }
  70. }
  71. return A;
  72. }
  73. };
  74.  
  75. //请编写一个插入算法 O(n^2)
  76. class InsertionSort
  77. {
  78. public:
  79. int* insertionSort(int* A, int n)
  80. {
  81. for (int i = ; i < n; i++)
  82. {
  83. int temp = A[i];
  84. int j = i - ;
  85. for (; j >= ;j--) //j前面的已经排好序,从后面往前比较,当没有比当前值大的时候bereak;
  86. {
  87. if (A[j]>temp)
  88. {
  89. A[j + ] = A[j];
  90. }
  91. else
  92. {
  93. break;
  94. }
  95. }
  96. A[j + ] = temp;
  97. }
  98. return A;
  99. }
  100. };
  101.  
  102. //归并排序 O(N*log(N))
  103. class MergeSort {
  104. public:
  105. int* mergeSort(int* A, int n) {
  106. // write code here
  107. mergeSort(A, , n - );
  108. return A;
  109. }
  110. void mergeSort(int* A, int beg, int end)
  111. {
  112. if (beg < end)
  113. {
  114. int mid = beg + (end - beg) / ;
  115. mergeSort(A, beg, mid);
  116. mergeSort(A, mid + , end);
  117. merge(A,beg,mid,end);
  118. }
  119. return;
  120. }
  121. void merge(int* A, int beg_, int mid_, int end_)
  122. {
  123. int *B = new int[end_ - beg_ + ];
  124. int index1 = beg_;
  125. int index2 = mid_ + ;
  126. int i = ;
  127. while (index1<=mid_&&index2<=end_)
  128. {
  129. if (A[index1]<=A[index2])
  130. {
  131. B[i++] = A[index1++];
  132. }
  133. else
  134. {
  135. B[i++] = A[index2++];
  136. }
  137. }
  138. while (index1 <= mid_)
  139. {
  140. B[i++] = A[index1++];
  141. }
  142. while (index2<=end_)
  143. {
  144. B[i++] = A[index2++];
  145. }
  146. //memcpy(A,B,end_-beg_+1);
  147. for (int i = ; i < end_ - beg_ + ;i++)
  148. {
  149. A[beg_+i] = B[i]; //A[beg_++] 不能写,改变了输入参数
  150. }
  151. delete[] B;
  152. }
  153. };
  154.  
  155. //快速排序 O(N*log(N))
  156. #include <math.h>
  157. class QuickSort {
  158. public:
  159. int* quickSort(int* A, int n) {
  160. // write code here
  161. quickSort(A, , n - );
  162. return A;
  163. }
  164. void quickSort(int* A, int low, int high)
  165. {
  166. if (low <= high)
  167. {
  168. int part = partition(A, low, high);
  169. quickSort(A, low, part - );
  170. quickSort(A, part + , high);
  171. }
  172. return;
  173. }
  174.  
  175. int partition(int* A, int low, int high)
  176. {
  177. int privotKey = A[low]; //基准元素
  178. while (low < high)
  179. { //从表的两端交替地向中间扫描
  180. while (low < high && A[high] >= privotKey)
  181. --high; //从high 所指位置向前搜索,至多到low+1 位置。将比基准元素小的交换到低端
  182. swap(&A[low], &A[high]);
  183. while (low < high && A[low] <= privotKey)
  184. ++low;
  185. swap(&A[low], &A[high]);
  186. }
  187. return low;
  188. }
  189. };
  190. class QuickSort2 {
  191. public:
  192. int* quickSort(int* A, int n) {
  193. // write code here
  194. quickSort(A, , n - );
  195. return A;
  196. }
  197. void quickSort(int* A, int low, int high)
  198. {
  199. if (low <= high)
  200. {
  201. int randn = low + rand() % (high - low + ); //随机选择关键字的下标
  202. swap(&A[randn], &A[high]); //void swap(int* A,int index1,int index2) //最好都操作下标
  203.  
  204. int part = partition(A, low, high);
  205. quickSort(A, low, part - );
  206. quickSort(A, part + , high);
  207. }
  208. return;
  209. }
  210.  
  211. int partition(int* A, int low, int high) //O(N)
  212. {
  213. //int pivot = A[low];//很多随机选择放在这里面,而且是以值的形式确定,而非下标标记为关键字
  214.  
  215. int pivot = low-; //关键字的位置
  216. for (int i = low ; i <= high; i++)
  217. {
  218. if (A[i] <= A[high])
  219. {
  220. swap(&A[i], &A[++pivot]); //感觉这样会把A数组前面的值覆盖?-->其实没有交换的效果就是把前面的交换到后面
  221. }
  222. }
  223. return pivot;
  224. }
  225. };
  226.  
  227. //推排序 O(N*log(N))
  228. class HeapSort {
  229. public:
  230. int* heapSort(int* A, int n) {
  231. // write code here
  232. buildHeap(A, n); //初始时构建堆
  233. //从最后一个元素开始对序列进行调整
  234. for (int i = n - ; i >= ;i--)
  235. {
  236. swap(&A[], &A[i]);
  237. heapAdjust(A,,i);
  238. }
  239. return A;
  240. }
  241.  
  242. void buildHeap(int* A, int size_A)
  243. {
  244. for (int i = (size_A)/ -; i >= ; i--)
  245. {
  246. heapAdjust(A,i,size_A);
  247. }
  248. }
  249.  
  250. void heapAdjust(int* A, int root, int size_A) //大顶堆
  251. {
  252. int leftchild = * root + ;
  253. if (leftchild<size_A) //递归形式
  254. {
  255. int rightchild = leftchild + ;
  256. if (rightchild<size_A)
  257. {
  258. if (A[leftchild]<A[rightchild])
  259. {
  260. leftchild = rightchild;
  261. }
  262. }
  263. //leftchild为左右子节点中较大的结点
  264. if (A[root]<A[leftchild])
  265. {
  266. int temp = A[root];
  267. A[root] = A[leftchild]; //将较大结点值上移到根节点
  268. A[leftchild] = temp; //完成交换,子节点变为以前的根节点
  269. heapAdjust(A, leftchild, size_A);
  270. }
  271. }
  272. return;
  273. }
  274. };
  275. class HeapSort2 {
  276. public:
  277. int* heapSort(int* A, int n) {
  278. // write code here
  279. buildHeap(A, n); //初始时构建堆
  280. //从最后一个元素开始对序列进行调整
  281. for (int i = n - ; i >= ; i--)
  282. {
  283. swap(&A[], &A[i]);
  284. heapAdjust(A, , i);
  285. }
  286. return A;
  287. }
  288.  
  289. void buildHeap(int* A, int size_A)
  290. {
  291. for (int i = (size_A - ) / ; i >= ; i--)
  292. {
  293. heapAdjust(A, i, size_A);
  294. }
  295. }
  296.  
  297. void heapAdjust(int* A, int root, int size_A) //调整为大顶堆
  298. {
  299. int temp = A[root];
  300. int leftchild = * root + ;
  301. while (leftchild < size_A) //非递归形式
  302. {
  303. int rightchild = leftchild + ;
  304. if (rightchild < size_A)
  305. {
  306. if (A[leftchild] < A[rightchild])
  307. {
  308. leftchild = rightchild;
  309. }
  310. }
  311. //leftchild为左右子节点中较大的结点
  312. if (A[root] < A[leftchild])
  313. {
  314. A[root] = A[leftchild]; //将较大结点值上移到根节点
  315. root = leftchild; //更新新的根节点
  316. leftchild = * root + ;
  317. }
  318. else //当前结点大于左右子节点则不需要调整
  319. {
  320. break;
  321. }
  322. A[root] = temp; //完成交换,子节点变为以前的根节点
  323. }
  324. return;
  325. }
  326. };
  327.  
  328. //希尔排序 O(N*log(N)) ---不稳定
  329. class ShellSort {
  330. public:
  331. int* shellSort(int* A, int n) {
  332. // write code here
  333. int dk = n / ;
  334. while (dk>=)
  335. {
  336. shellSort2(A,n,dk);
  337. dk /= ;
  338. }
  339. return A;
  340. }
  341. void shellSort(int* A, int n, int dk)
  342. {
  343. for (int i = dk; i < n;i++)
  344. {
  345. int index = i; //当前访问的位置
  346. while (index>=dk)
  347. {
  348. if (A[index-dk]>A[index])
  349. {
  350. swap(&A[index-dk],&A[index]); //交换不算最优,找到插入位置才交换
  351. index -= dk;
  352. }
  353. else
  354. {
  355. break;
  356. }
  357. }
  358. }
  359. }
  360. void shellSort2(int* A,int n,int dk)
  361. {
  362. for (int i = dk; i < n;i++)
  363. {
  364. if (A[i]<A[i-dk]) //找到插入位置
  365. {
  366. int x = A[i];//复制哨兵
  367. A[i] = A[i - dk];
  368. int j = i - dk; //从该位置向前查找
  369. while (x<A[j]&&j>=) //防止j越界
  370. {
  371. A[j] = A[j - dk];
  372. j -= dk; //向前移动
  373. }
  374. A[j + dk] = x;// 插入到正确位置
  375. }
  376. }
  377. }
  378.  
  379. };
  380.  
  381. #define N 13
  382. int main()
  383. {
  384. //待排数据输入方式:
  385. /*int N = 0;
  386. cout << "排序数据个数:\n";
  387. cin >> N;
  388. int* A = new int[N];
  389. cout << "请输入待排序的数据:\n";
  390. for (int i = 0; i < N; i++)
  391. {
  392. cin >> A[i];
  393. }*/
  394. //数据直接给定
  395. int B[N] = { , , , , , };
  396. int C[] = { , , , , , , , , , , , , };
  397. int* A = C;
  398.  
  399. //从文件中读取,大量数据,计算时间复杂度
  400.  
  401. printResult("待排原始数据:", C, N);
  402.  
  403. BubbleSort bubble;
  404. bubble.bubbleSort(A,N);
  405. printResult("bubbleSort", A, N);
  406.  
  407. SelectionSort select;
  408. select.selectionSort(A, N);
  409. printResult("selectSort", A, N);
  410.  
  411. InsertionSort insert;
  412. insert.insertionSort(A, N);
  413. printResult("InsetSort", A, N);
  414.  
  415. MergeSort merge;
  416. merge.mergeSort(A, N);
  417. printResult("MergeSort", A, N);
  418.  
  419. QuickSort qucik;
  420. qucik.quickSort(A, N);
  421. printResult("QucikSort",A,N);
  422.  
  423. QuickSort2 qucik2;
  424. qucik2.quickSort(A, N);
  425. printResult("QucikSort2", A, N);
  426.  
  427. HeapSort heap;
  428. heap.heapSort(A, N);
  429. printResult("heapSort", A, N);
  430.  
  431. HeapSort2 heap2;
  432. heap2.heapSort(A, N);
  433. printResult("heapSort2", A, N);
  434.  
  435. ShellSort shell;
  436. shell.shellSort(A,N);
  437. printResult("shellSort", A, N);
  438.  
  439. return ;
  440. }

排序算法的实现(归并,快排,堆排,希尔排序 O(N*log(N)))的更多相关文章

  1. Python学习(三) 八大排序算法的实现(下)

    本文Python实现了插入排序.基数排序.希尔排序.冒泡排序.高速排序.直接选择排序.堆排序.归并排序的后面四种. 上篇:Python学习(三) 八大排序算法的实现(上) 1.高速排序 描写叙述 通过 ...

  2. 排序算法的实现之Javascript(常用)

    排序算法的实现之Javascript 话不多说,直接代码. 1.冒泡排序 1.依次比较相邻的两个数,如果前一个比后一个大,则交换两者的位置,否则位置不变 2.按照第一步的方法重复操作前length-1 ...

  3. 各类排序算法的实现C#版

    using System;using System.CodeDom;using System.Collections.Generic;using System.Linq;using System.Ru ...

  4. Javascript十大排序算法的实现方法

    上一篇中,实现了Javascript中的冒泡排序方法,下面把剩余的九种排序算法实现 选择排序: var array = []; for(var i=0;i<100000;i++){ var x ...

  5. 一起学Hadoop——二次排序算法的实现

    二次排序,从字面上可以理解为在对key排序的基础上对key所对应的值value排序,也叫辅助排序.一般情况下,MapReduce框架只对key排序,而不对key所对应的值排序,因此value的排序经常 ...

  6. 几种常见排序算法之Java实现(插入排序、希尔排序、冒泡排序、快速排序、选择排序、归并排序)

    排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列. 稳定度(稳定性)一个排序算法是稳定的,就是当有两个相等记录的关 ...

  7. 八大排序算法的python实现(二)希尔排序

    代码: #coding:utf-8 #author:徐卜灵 # 希尔排序的实质就是分组插入排序,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. # 希尔排序,也称递减增量排序算法, ...

  8. 【js基础】js排序方法——快排+堆排+插排+选择排

    快排 Array.prototype.fastSort = function(){ var arr = this; function sort(left, right, arr){ if( left ...

  9. Python之基本排序算法的实现

    import cProfile import random class SortAlgorithm: def __init__(self,unsortedlist=[]): self.unsorted ...

随机推荐

  1. 漏洞利用查询工具sandi

    漏洞利用查询工具sandi   在渗透测试中,一旦发现漏洞,就需要查找该漏洞的利用方式.由于漏洞众多,就需要渗透测试人员从海量的漏洞信息找出可用攻击载荷.Kali Linux内置了一个查询工具sand ...

  2. windows下elasticsearch启动

    windows下启动elasticsearch,依赖于配置好JAVA_HOME D:\Program Files\Java\jdk1.7.0_71 命令行启动elasticsearch.bat即可实现 ...

  3. Centos 首次运行MySQL

    1:启动MySQL systemctl start mysqld.service 2:查看MySQL运行状态 systemctl status mysqld.service 3:查看默认密码 grep ...

  4. hdu 5768 Lucky7 容斥

    Lucky7 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5768 Description When ?? was born, seven crow ...

  5. j.u.c系列(09)---之并发工具类:CyclicBarrier

    写在前面 CyclicBarrier是一个同步辅助类,允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).因为该 barrier 在释放等待线程后可以重用,所以 ...

  6. j.u.c系列(03)---之AQS:AQS简介

    写在前面 Java的内置锁一直都是备受争议的,在JDK 1.6之前,synchronized这个重量级锁其性能一直都是较为低下,虽然在1.6后,进行大量的锁优化策略,但是与Lock相比synchron ...

  7. jQueryUI常用功能实战

    本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery ( ...

  8. MongoDB简单使用 —— 驱动

    C#中可以通过官方的驱动MongoDB.Drvier来使用,使用Nuget安装即可. Install-Package MongoDB.Driver Bson文档操作: using MongoDB.Bs ...

  9. HappyJTAG2 - JTAG AND SPI AVR8 interface EMBEDDED JTAG ! EMBEDDED SPI !

    New version released ! V2.45 (Check version list for details) This construction is based on HappyJTA ...

  10. EasyNetQ介绍

    EasyNetQ 是一个容易使用,坚固的,针对RabbitMQ的 .NET API. 假如你尽可能快的想去安装和运行RabbitMQ,请去看入门指南.EasyNetQ是为了提供一个尽可能简洁的适用与R ...