排序算法的实现(归并,快排,堆排,希尔排序 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 ...
随机推荐
- Xamarin-Android_BaseAdapter 简单的复用
Xamarin-Android_BaseAdapter 简单的复用 缘由: 本人是一枚 小菜 初学Xamarin-Android 正在学习ListView 控件 发现这个控件的自定义布局 用的那叫一 ...
- 深入理解指针—>结构体里的成员数组和指针
单看这文章的标题,你可能会觉得好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Laruence同学出了一个关于C语言的题,微博链接.微博截图如 ...
- [Java]如何把当前时间插入到数据库
[Java]如何把当前时间插入到数据库 1.在orderDao.java中 /** 设置订单*/ public void setOrder(Order order){ Date time = new ...
- 本地hosts文件IP地址解析
localhost是一个域名,127.0.0.1为IP地址.Windows系统中,约定127.0.0.1为本地IP地址.localhost是其对应的域名.配置是在hosts文件中设置的,Windows ...
- ADO.NET理论+实践
题记: 每一事物的产生和存在都有其特定的理由. 理论:ADO.NET是一组与数据源进行交互的面向对象类库.通常情况下数据源就是数据库,当然同样也能是文本文件,Excel表格或XML文件,我们知道的数 ...
- 液晶电视插有线电视信号线的是哪个接口 HDMI是什么接口
1.液晶电视插有线电视信号线的接口(模拟信号)是射频接口(也叫RF接口,同轴电缆接口,闭路线接口),数字信号就得通过机顶盒转换成模拟信号视频输出至电视,才能正常收看电视节目. 2.电视机或高清机顶盒上 ...
- 报错:TargetException, 非静态方法需要一个目标
如果实例为null,调用实例方法会报如上错. 解决办法: 检查实例是否为null,考虑什么情况下实例为null,然后排除实例为null的情况.
- Delphi数学运算当中四舍五入的问题
在最近版本的Delphi Pascal 编译器中,Round 函数是以 CPU 的 FPU (浮点部件) 处理器为基础的.这种处理器采用了所谓的 "银行家舍入法",即对中间值 (如 ...
- 线程、线程ID获取
一.进程ID获取 1.1 当前进程的Id 方法1 通过进程名获取 下面的例子中,也包含了获取该进程下的线程的方法. System.Diagnostics.Process[] processes:bo ...
- python测试开发django-36.一对一(OneToOneField)关系查询
前言 前面一篇在xadmin后台一个页面显示2个关联表(OneToOneField)的字段,使用inlines内联显示.本篇继续学习一对一(OneToOneField)关系的查询. 上一篇list_d ...