排序算法的实现(归并,快排,堆排,希尔排序 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 ...
随机推荐
- @repository的含义,并且有时候却不用写,为什么?
//最后发现是这样的:@repository跟@Service,@Compent,@Controller这4种注解是没什么本质区别,都是声明作用,取不同的名字只是为了更好区分各自的功能.下图更多的作用 ...
- Python学习——set集合的补充
set 是一个无序且不重复的元素集合>>> num = {1,2,3,4,5} 1.add()添加一个元素 >>> num.add(6) >>> ...
- 1722 最优乘车 1997年NOI全国竞赛
题目描述 Description H城是一个旅游胜地,每年都有成千上万的人前来观光.为方便游客,巴士公司在各个旅游景点及宾馆,饭店等地都设置了巴士站并开通了一些单程巴上线路.每条单程巴士线路从某个巴士 ...
- HDU 3802Ipad,IPhone
前两块可以看成是不是二次剩余,快速幂计算即可. 后半部分可以看成x1=a+b+2ab,x2=a+b-2ab为特征方程x^2-px-qx=0的两根 然后可以通过韦达定理求出p和q,因此递推式为A(n+2 ...
- BZOJ.4072.[SDOI2016]征途(DP 斜率优化)
题目链接 题目要求使得下面这个式子最小(\(\mu=\frac{\sum_{i=1}^ma_i}{m}\)是平均数,\(a_i\)为第\(i\)段的和): \[\frac{\sum_{i-1}^m(\ ...
- 使用CefSharp在.Net程序中嵌入Chrome浏览器(七)——右键菜单
一个常用的功能就是禁止浏览器本身的右键菜单,靠在WPF中拦截鼠标事件是不行的,可以通过设置MenuHandler来实现. 首先实现一个IContextMenuHandler. public class ...
- External Input Counter and External interrupt
External Input Counter and External interrupt : count the input signal from the button. So what is t ...
- Both - Either - Neither English Grammar
http://www.grammar.cl/english/both-either-neither.htm Both, Either, Neither Summary Chart We use bot ...
- 关于bootstrap的treeview不显示多选(复选框)的问题,以及联动选择的问题,外加多选后取值
最近做项目用到了treeview.因为涉及到多选的问题,很是棘手,于是乎,我决定查看原生JS,探个究竟.需要引用官方的bootstrap-treeview.js都知道吧,对于所需要引用的,我就不多说了 ...
- Android WebView加载Html右边空白问题的解决方案
用WebView显示Html时,右边会出现一条空白区,如下图所示: 最开始的时候,认为是网页本身的空白. 后来发现网页本身无问题,且这个空白区是跟Scroll Bar 的位置和粗细比较相符,于是去控制 ...