排序算法的实现(归并,快排,堆排,希尔排序 O(N*log(N)))
今天跟着左老师的视频,理解了四种复杂度为 O(N*log(N))的排序算法,以前也理解过过程,今天根据实际的代码,感觉基本的算法还是很简单的,只是自己写的时候可能一些边界条件,循环控制条件把握不好。
- //对于一个int数组,请编写一个选择冒泡算法,对数组元素排序。
- //给定一个int数组A及数组的大小n,请返回排序后的数组。
- //测试样例:
- //[1, 2, 3, 5, 2, 3], 6
- //[1, 2, 2, 3, 3, 5]
- #include <iostream>
- using namespace std;
- #include<string>
- void printResult(string str,int* A,int n)
- {
- cout << str << "的结果:\n";
- for (int i = ; i < n; i++)
- {
- cout << A[i] <<" ";
- }
- cout << endl;
- }
- void swap(int *a, int *b)
- {
- int temp=*a;
- *a = *b;
- *b = temp;
- }
- //冒泡排序 O(n^2)
- class BubbleSort {
- public:
- int* bubbleSort(int* A, int n) {
- // write code here
- for (int i = ; i<n; i++)
- {
- for (int j = ; j<n - i - ; j++)
- {
- if (A[j]>A[j + ])
- {
- int temp = A[j];
- A[j] = A[j + ];
- A[j + ] = temp;
- }
- }
- }
- return A;
- }
- };
- //请编写一个选择排序算法 O(n^2)
- class SelectionSort {
- public:
- int* selectionSort(int* A, int n) {
- // write code here
- int k = ;
- for (int i = ; i < n-; i++)
- {
- k = i;
- for (int j = i; j < n; j++)
- {
- if (A[k]>A[j])
- {
- k = j;
- }
- }
- if (k!=i)
- {
- int temp = A[i];
- A[i] = A[k];
- A[k] = temp;
- }
- }
- return A;
- }
- };
- //请编写一个插入算法 O(n^2)
- class InsertionSort
- {
- public:
- int* insertionSort(int* A, int n)
- {
- for (int i = ; i < n; i++)
- {
- int temp = A[i];
- int j = i - ;
- for (; j >= ;j--) //j前面的已经排好序,从后面往前比较,当没有比当前值大的时候bereak;
- {
- if (A[j]>temp)
- {
- A[j + ] = A[j];
- }
- else
- {
- break;
- }
- }
- A[j + ] = temp;
- }
- return A;
- }
- };
- //归并排序 O(N*log(N))
- class MergeSort {
- public:
- int* mergeSort(int* A, int n) {
- // write code here
- mergeSort(A, , n - );
- return A;
- }
- void mergeSort(int* A, int beg, int end)
- {
- if (beg < end)
- {
- int mid = beg + (end - beg) / ;
- mergeSort(A, beg, mid);
- mergeSort(A, mid + , end);
- merge(A,beg,mid,end);
- }
- return;
- }
- void merge(int* A, int beg_, int mid_, int end_)
- {
- int *B = new int[end_ - beg_ + ];
- int index1 = beg_;
- int index2 = mid_ + ;
- int i = ;
- while (index1<=mid_&&index2<=end_)
- {
- if (A[index1]<=A[index2])
- {
- B[i++] = A[index1++];
- }
- else
- {
- B[i++] = A[index2++];
- }
- }
- while (index1 <= mid_)
- {
- B[i++] = A[index1++];
- }
- while (index2<=end_)
- {
- B[i++] = A[index2++];
- }
- //memcpy(A,B,end_-beg_+1);
- for (int i = ; i < end_ - beg_ + ;i++)
- {
- A[beg_+i] = B[i]; //A[beg_++] 不能写,改变了输入参数
- }
- delete[] B;
- }
- };
- //快速排序 O(N*log(N))
- #include <math.h>
- class QuickSort {
- public:
- int* quickSort(int* A, int n) {
- // write code here
- quickSort(A, , n - );
- return A;
- }
- void quickSort(int* A, int low, int high)
- {
- if (low <= high)
- {
- int part = partition(A, low, high);
- quickSort(A, low, part - );
- quickSort(A, part + , high);
- }
- return;
- }
- int partition(int* A, int low, int high)
- {
- int privotKey = A[low]; //基准元素
- while (low < high)
- { //从表的两端交替地向中间扫描
- while (low < high && A[high] >= privotKey)
- --high; //从high 所指位置向前搜索,至多到low+1 位置。将比基准元素小的交换到低端
- swap(&A[low], &A[high]);
- while (low < high && A[low] <= privotKey)
- ++low;
- swap(&A[low], &A[high]);
- }
- return low;
- }
- };
- class QuickSort2 {
- public:
- int* quickSort(int* A, int n) {
- // write code here
- quickSort(A, , n - );
- return A;
- }
- void quickSort(int* A, int low, int high)
- {
- if (low <= high)
- {
- int randn = low + rand() % (high - low + ); //随机选择关键字的下标
- swap(&A[randn], &A[high]); //void swap(int* A,int index1,int index2) //最好都操作下标
- int part = partition(A, low, high);
- quickSort(A, low, part - );
- quickSort(A, part + , high);
- }
- return;
- }
- int partition(int* A, int low, int high) //O(N)
- {
- //int pivot = A[low];//很多随机选择放在这里面,而且是以值的形式确定,而非下标标记为关键字
- int pivot = low-; //关键字的位置
- for (int i = low ; i <= high; i++)
- {
- if (A[i] <= A[high])
- {
- swap(&A[i], &A[++pivot]); //感觉这样会把A数组前面的值覆盖?-->其实没有交换的效果就是把前面的交换到后面
- }
- }
- return pivot;
- }
- };
- //推排序 O(N*log(N))
- class HeapSort {
- public:
- int* heapSort(int* A, int n) {
- // write code here
- buildHeap(A, n); //初始时构建堆
- //从最后一个元素开始对序列进行调整
- for (int i = n - ; i >= ;i--)
- {
- swap(&A[], &A[i]);
- heapAdjust(A,,i);
- }
- return A;
- }
- void buildHeap(int* A, int size_A)
- {
- for (int i = (size_A)/ -; i >= ; i--)
- {
- heapAdjust(A,i,size_A);
- }
- }
- void heapAdjust(int* A, int root, int size_A) //大顶堆
- {
- int leftchild = * root + ;
- if (leftchild<size_A) //递归形式
- {
- int rightchild = leftchild + ;
- if (rightchild<size_A)
- {
- if (A[leftchild]<A[rightchild])
- {
- leftchild = rightchild;
- }
- }
- //leftchild为左右子节点中较大的结点
- if (A[root]<A[leftchild])
- {
- int temp = A[root];
- A[root] = A[leftchild]; //将较大结点值上移到根节点
- A[leftchild] = temp; //完成交换,子节点变为以前的根节点
- heapAdjust(A, leftchild, size_A);
- }
- }
- return;
- }
- };
- class HeapSort2 {
- public:
- int* heapSort(int* A, int n) {
- // write code here
- buildHeap(A, n); //初始时构建堆
- //从最后一个元素开始对序列进行调整
- for (int i = n - ; i >= ; i--)
- {
- swap(&A[], &A[i]);
- heapAdjust(A, , i);
- }
- return A;
- }
- void buildHeap(int* A, int size_A)
- {
- for (int i = (size_A - ) / ; i >= ; i--)
- {
- heapAdjust(A, i, size_A);
- }
- }
- void heapAdjust(int* A, int root, int size_A) //调整为大顶堆
- {
- int temp = A[root];
- int leftchild = * root + ;
- while (leftchild < size_A) //非递归形式
- {
- int rightchild = leftchild + ;
- if (rightchild < size_A)
- {
- if (A[leftchild] < A[rightchild])
- {
- leftchild = rightchild;
- }
- }
- //leftchild为左右子节点中较大的结点
- if (A[root] < A[leftchild])
- {
- A[root] = A[leftchild]; //将较大结点值上移到根节点
- root = leftchild; //更新新的根节点
- leftchild = * root + ;
- }
- else //当前结点大于左右子节点则不需要调整
- {
- break;
- }
- A[root] = temp; //完成交换,子节点变为以前的根节点
- }
- return;
- }
- };
- //希尔排序 O(N*log(N)) ---不稳定
- class ShellSort {
- public:
- int* shellSort(int* A, int n) {
- // write code here
- int dk = n / ;
- while (dk>=)
- {
- shellSort2(A,n,dk);
- dk /= ;
- }
- return A;
- }
- void shellSort(int* A, int n, int dk)
- {
- for (int i = dk; i < n;i++)
- {
- int index = i; //当前访问的位置
- while (index>=dk)
- {
- if (A[index-dk]>A[index])
- {
- swap(&A[index-dk],&A[index]); //交换不算最优,找到插入位置才交换
- index -= dk;
- }
- else
- {
- break;
- }
- }
- }
- }
- void shellSort2(int* A,int n,int dk)
- {
- for (int i = dk; i < n;i++)
- {
- if (A[i]<A[i-dk]) //找到插入位置
- {
- int x = A[i];//复制哨兵
- A[i] = A[i - dk];
- int j = i - dk; //从该位置向前查找
- while (x<A[j]&&j>=) //防止j越界
- {
- A[j] = A[j - dk];
- j -= dk; //向前移动
- }
- A[j + dk] = x;// 插入到正确位置
- }
- }
- }
- };
- #define N 13
- int main()
- {
- //待排数据输入方式:
- /*int N = 0;
- cout << "排序数据个数:\n";
- cin >> N;
- int* A = new int[N];
- cout << "请输入待排序的数据:\n";
- for (int i = 0; i < N; i++)
- {
- cin >> A[i];
- }*/
- //数据直接给定
- int B[N] = { , , , , , };
- int C[] = { , , , , , , , , , , , , };
- int* A = C;
- //从文件中读取,大量数据,计算时间复杂度
- printResult("待排原始数据:", C, N);
- BubbleSort bubble;
- bubble.bubbleSort(A,N);
- printResult("bubbleSort", A, N);
- SelectionSort select;
- select.selectionSort(A, N);
- printResult("selectSort", A, N);
- InsertionSort insert;
- insert.insertionSort(A, N);
- printResult("InsetSort", A, N);
- MergeSort merge;
- merge.mergeSort(A, N);
- printResult("MergeSort", A, N);
- QuickSort qucik;
- qucik.quickSort(A, N);
- printResult("QucikSort",A,N);
- QuickSort2 qucik2;
- qucik2.quickSort(A, N);
- printResult("QucikSort2", A, N);
- HeapSort heap;
- heap.heapSort(A, N);
- printResult("heapSort", A, N);
- HeapSort2 heap2;
- heap2.heapSort(A, N);
- printResult("heapSort2", A, N);
- ShellSort shell;
- shell.shellSort(A,N);
- printResult("shellSort", A, N);
- return ;
- }
排序算法的实现(归并,快排,堆排,希尔排序 O(N*log(N)))的更多相关文章
- Python学习(三) 八大排序算法的实现(下)
本文Python实现了插入排序.基数排序.希尔排序.冒泡排序.高速排序.直接选择排序.堆排序.归并排序的后面四种. 上篇:Python学习(三) 八大排序算法的实现(上) 1.高速排序 描写叙述 通过 ...
- 排序算法的实现之Javascript(常用)
排序算法的实现之Javascript 话不多说,直接代码. 1.冒泡排序 1.依次比较相邻的两个数,如果前一个比后一个大,则交换两者的位置,否则位置不变 2.按照第一步的方法重复操作前length-1 ...
- 各类排序算法的实现C#版
using System;using System.CodeDom;using System.Collections.Generic;using System.Linq;using System.Ru ...
- Javascript十大排序算法的实现方法
上一篇中,实现了Javascript中的冒泡排序方法,下面把剩余的九种排序算法实现 选择排序: var array = []; for(var i=0;i<100000;i++){ var x ...
- 一起学Hadoop——二次排序算法的实现
二次排序,从字面上可以理解为在对key排序的基础上对key所对应的值value排序,也叫辅助排序.一般情况下,MapReduce框架只对key排序,而不对key所对应的值排序,因此value的排序经常 ...
- 几种常见排序算法之Java实现(插入排序、希尔排序、冒泡排序、快速排序、选择排序、归并排序)
排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列. 稳定度(稳定性)一个排序算法是稳定的,就是当有两个相等记录的关 ...
- 八大排序算法的python实现(二)希尔排序
代码: #coding:utf-8 #author:徐卜灵 # 希尔排序的实质就是分组插入排序,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. # 希尔排序,也称递减增量排序算法, ...
- 【js基础】js排序方法——快排+堆排+插排+选择排
快排 Array.prototype.fastSort = function(){ var arr = this; function sort(left, right, arr){ if( left ...
- Python之基本排序算法的实现
import cProfile import random class SortAlgorithm: def __init__(self,unsortedlist=[]): self.unsorted ...
随机推荐
- 漏洞利用查询工具sandi
漏洞利用查询工具sandi 在渗透测试中,一旦发现漏洞,就需要查找该漏洞的利用方式.由于漏洞众多,就需要渗透测试人员从海量的漏洞信息找出可用攻击载荷.Kali Linux内置了一个查询工具sand ...
- windows下elasticsearch启动
windows下启动elasticsearch,依赖于配置好JAVA_HOME D:\Program Files\Java\jdk1.7.0_71 命令行启动elasticsearch.bat即可实现 ...
- Centos 首次运行MySQL
1:启动MySQL systemctl start mysqld.service 2:查看MySQL运行状态 systemctl status mysqld.service 3:查看默认密码 grep ...
- hdu 5768 Lucky7 容斥
Lucky7 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5768 Description When ?? was born, seven crow ...
- j.u.c系列(09)---之并发工具类:CyclicBarrier
写在前面 CyclicBarrier是一个同步辅助类,允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).因为该 barrier 在释放等待线程后可以重用,所以 ...
- j.u.c系列(03)---之AQS:AQS简介
写在前面 Java的内置锁一直都是备受争议的,在JDK 1.6之前,synchronized这个重量级锁其性能一直都是较为低下,虽然在1.6后,进行大量的锁优化策略,但是与Lock相比synchron ...
- jQueryUI常用功能实战
本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery ( ...
- MongoDB简单使用 —— 驱动
C#中可以通过官方的驱动MongoDB.Drvier来使用,使用Nuget安装即可. Install-Package MongoDB.Driver Bson文档操作: using MongoDB.Bs ...
- 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 ...
- EasyNetQ介绍
EasyNetQ 是一个容易使用,坚固的,针对RabbitMQ的 .NET API. 假如你尽可能快的想去安装和运行RabbitMQ,请去看入门指南.EasyNetQ是为了提供一个尽可能简洁的适用与R ...