排序算法的实现(归并,快排,堆排,希尔排序 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 ...
随机推荐
- Bootstrap css-表格
前言:整理的东西比较基础,有不足的地方欢迎大家批评指正! 1,Bootstrap基本的表格结构 源代码: <table class="table"> <cap ...
- Ubuntu 16.04 安装搜狗输入法
安装步骤: 1.去官网下载文件[https://pinyin.sogou.com/linux/] 2.安装deb安装包: sudo dpkg -i 安装包的名字.deb //(如果安装失败,请重复几次 ...
- luogu P1502 窗口的星星
题目链接 P1502 窗口的星星 题解 扫描线+线段树 线段树的每一个节点处理的是左边框放在当前x-1位置时的框内星星的亮度大小 按照x坐标进行离散化,得到离散化后每一个坐标x的可影响的范围 维护扫描 ...
- 【bzoj3451】Tyvj1953 Normal 期望+树的点分治+FFT
题目描述 给你一棵 $n$ 个点的树,对这棵树进行随机点分治,每次随机一个点作为分治中心.定义消耗时间为每层分治的子树大小之和,求消耗时间的期望. 输入 第一行一个整数n,表示树的大小接下来n-1行每 ...
- Codeforces Round #375 (Div. 2) D. Lakes in Berland 贪心
D. Lakes in Berland 题目连接: http://codeforces.com/contest/723/problem/D Description The map of Berland ...
- UVALive 6910 Cutting Tree 并查集
Cutting Tree 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8& ...
- Windows平台开发Mapreduce程序远程调用运行在Hadoop集群—Yarn调度引擎异常
共享原因:虽然用一篇博文写问题感觉有点奢侈,但是搜索百度,相关文章太少了,苦苦探寻日志才找到解决方案. 遇到问题:在windows平台上开发的mapreduce程序,运行迟迟没有结果. Mapredu ...
- 编译 php-memcache 扩展时提示Cannot find autoconf
下载memcache扩展 http://pecl.php.net/package/memcache ,到 /usr/local/src目录下并解压 [root@bogon src]# .tgz [ro ...
- 使用 IntraWeb (17) - 基本控件之 TIWRadioButton、TIWRadioGroup、TIWCheckBox
TIWRadioButton //单选 TIWRadioGroup //单选组 TIWCheckBox //复选 TIWRadioButton 所在单元及继承链: IWCompRadioButton. ...
- FireDAC 下的 Sqlite [1] - 前言
很长时间没静下心来写博客了, 现在回来, 是 Delphi 不断地进步让我感动.振奋. Delphi XE5 并入了 FireDAC, 第一印象非常好, 恐怕 dbExpress 等等都要靠边站了. ...