排序综合算法

先看运行结果,要不然怕没动力看下去排序算法基础、改进综合://冒泡排序//定向冒泡[鸡尾酒]排序//选择排序//改进的选择排序//直接插入排序//二分插入排序//希尔排序//自顶向下地归并排序//自底向上地归并排序//堆排序//快速排序//改进的快速排序:三向切分快速排序(运行平台:VS(WIN32 控制台应用程序) 或者 DEV-C++ 均试验过可行)(图片中的运...
摘要由CSDN通过智能技术生成

先看运行结果,要不然怕没动力看下去

排序算法基础、改进综合:
//冒泡排序
//定向冒泡[鸡尾酒]排序
//选择排序
//改进的选择排序
//直接插入排序
//二分插入排序
//希尔排序
//自顶向下地归并排序
//自底向上地归并排序
//堆排序
//快速排序
//改进的快速排序:三向切分快速排序

(运行平台:VS(WIN32 控制台应用程序) 或者 DEV-C++ 均试验过可行)
(图片中的运行时间单位是:ms)
(测试文件:10Kints.txt 1万个整数,一行一个数
100Kints.txt 10万个整数,一行一个数
1Mints.txt 100万个整数,一行一个数
当然也可以不是整数,因为算法已经用了类模板。
自己用随机数函数产生就可以了。)
(在对10万和100万个数字排序的时候,已经不调用了某些排序算法,因为这些低级的排序算法需要的时间太长了,如果有耐心等,倒可以试一下)
在这里插入图片描述

SortAlgorithm.h

#pragma once

#include<iostream>
#include<fstream>
using namespace std;

template <class DataType>
class SortAlgorithm
{
public:
	void BubbleSort(DataType arr[],int n);                    //冒泡排序
	void CocktailSort(DataType arr[], int n);                 //定向冒泡[鸡尾酒]排序
	void SelectionSort(DataType arr[], int n);                //选择排序
	void ModifiedSelectionSort(DataType arr[],int n);         //改进的选择排序
	void InsertionSort(DataType arr[], int n);                //直接插入排序
	void BinaryInsertionSort(DataType arr[], int n);          //二分插入排序
	void ShellSort(DataType arr[], int n);                    //希尔排序
	void Merge(DataType arr[], int from, int mid, int to, DataType aux[]);      //将 a[from...mid] 和 a[mid+1...to]归并
	void MergeSortBytop_down(DataType arr[], int from, int to, DataType aux[]); //自顶向下地归并排序时所调用的下一层函数
	void MergeSortBytop_down(DataType arr[], int n);          //自顶向下地归并排序
	void MergeSortBydown_top(DataType arr[], int n);          //自底向上地归并排序
	void QuickSort(DataType arr[], int from, int to);         //快速排序所调用的下一层函数
	void QuickSort(DataType arr[], int n);                    //快速排序
	void QuickSortIn3Way(DataType arr[], int from, int to);   //改进的快速排序:三向切分快速排序所调用的下一层函数
	void QuickSortIn3Way(DataType arr[], int n);              //改进的快速排序:三向切分快速排序
	void Swap(DataType arr[], int i, int j);                  //交换下标为i,j的两个元素
	void Print(DataType arr[], int n);                        //若使用该函数,建议定义的测试数组长度不超过300,否则控制台会产生输出截断
	void OutputInFile(DataType arr[], int n, string filename);//把排序结果输出到文件中。
	bool Less(DataType v, DataType w);                        //若v<w,返回true
	int CompareTo(int i, int j);                              //改进的快速排序:三向切分快速排序所调用的下一层函数的下一层函数
	int Partition(DataType arr[], int from, int to);          //切分数组为arr[from...j-1]、arr[j]、arr[j+1...to]
	int Min(int i, int j);//返回i与j中的最小值

};

/*
【1】【【冒泡排序】】
(1)冒泡排序算法的运作如下:
  比较相邻的元素,如果前一个比后一个大,就把它们两个调换位置。
  对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  针对所有的元素重复以上的步骤,除了最后一个。
  持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
(2)
   分类 -------------- 内部比较排序
   数据结构 ---------- 数组
   最差时间复杂度 ---- O(n^2)
   最优时间复杂度 ---- 如果能在内部循环第一次运行时,使用一个旗标来表示有无需要交换的可能,可以把最优时间复杂度降低到O(n)
   平均时间复杂度 ---- O(n^2)
   所需辅助空间 ------ O(1)
   稳定性 ------------ 稳定
*/

/*
【2】【【鸡尾酒排序】】
(1)也叫定向冒泡排序,是冒泡排序的一种改进。此算法与冒泡排序的不同处在于从低到高然后从高到低,
     而冒泡排序则仅从低到高去比较序列里的每个元素。他可以得到比冒泡排序稍微好一点的效能。
(2)
  分类 -------------- 内部比较排序
  数据结构 ---------- 数组
  最差时间复杂度 ---- O(n^2)
  最优时间复杂度 ---- 如果序列在一开始已经大部分排序过的话,会接近O(n)
  平均时间复杂度 ---- O(n^2)
  所需辅助空间 ------ O(1)
  稳定性 ------------ 稳定
*/

/*
【3】【【选择排序】】
(1)工作原理:初始时在序列中找到最小(大)元素,放到序列的起始位置作为已排序序列;
               然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。
               以此类推,直到所有元素均排序完毕。
       NOTICE: 选择排序与冒泡排序的区别:冒泡排序通过依次交换相邻两个顺序不合法的元素位置,
               从而将当前最小(大)元素放到合适的位置;而选择排序每遍历一次都记住了当前最小
              (大)元素的位置,最后仅需一次交换操作即可将其放到合适的位置。
(2)
   分类 -------------- 内部比较排序
   数据结构 ---------- 数组
   最差时间复杂度 ---- O(n^2)
   最优时间复杂度 ---- O(n^2)
   平均时间复杂度 ---- O(n^2)
   所需辅助空间 ------ O(1)
   稳定性 ------------ 不稳定
*/

/*
【4】【【改进的选择排序】】
(1)改进的选择排序算法的运作如下:
     将要交换的两个元素,不立即直接交换,而是先取出后面的元素,将后面元素之前的元素直到前一个元素“向后平移”
	 一个位置,再将取出的该元素赋在前面空出的位置(当前正要确定元素正确定位的位置)上,就可成为一个稳定的排序。
(2)
  分类 -------------- 内部比较排序
  最差时间复杂度 ---- O(n^3)
  最优时间复杂度 ---- O(n^3)
  平均时间复杂度 ---- O(n^3)
  所需辅助空间 ------ O(1)
  稳定性 ------------ 稳定
*/

/*
【5】【【二分插入排序】】
(1)插入排序的改进:二分插入排序
     对于插入排序,如果比较操作的代价比交换操作大的话,
     可以采用二分查找法来减少比较操作的次数,我们称为二分插入排序.
(2)
  分类 -------------- 内部比较排序
  数据结构 ---------- 数组
  最差时间复杂度 ---- O(n^2)
  最优时间复杂度 ---- O(nlogn)
  平均时间复杂度 ---- O(n^2)
  所需辅助空间 ------ O(1)
  稳定性 ------------ 稳定
*/

/*
【6】【【希尔排序】】
(1)插入排序的更高效改进:希尔排序(Shell Sort)
    希尔排序,也叫递减增量排序,是插入排序的一种更高效的改进版本。希尔排序是不稳定的排序算法。

   希尔排序是基于插入排序的以下两点性质而提出改进方法的:
(01)插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序
   的效率但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;
(02)希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样 
   可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越 
   小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,
   需排序的数据几乎是已排好的了(此时插入排序较快)。
(03)假设有一个很小的数据在一个已按升序排好序的数组的末端。如果用复杂度
   为O(n^2)的排序(冒泡排序或直接插入排序),可能会进行n次的比较和交换
   才能将该数据移至正确位置。而希尔排序会用较大的步长移动数据,所以小数据
   只需进行少数比较和交换即可到正确位置。
(2)
  分类 -------------- 内部比较排序
  数据结构 ---------- 数组
  最差时间复杂度 ---- 根据步长序列的不同而不同。已知最好的为O(n(logn)^2)
  最优时间复杂度 ---- O(n)
  平均时间复杂度 ---- 根据步长序列的不同而不同。
  所需辅助空间 ------ O(1)
  稳定性 ------------ 不稳定
*/

/*
【7】【【归并排序】】
(1)归并排序是创建在归并操作上的一种有效的排序算法,效率为O(nlogn),1945年由冯·诺伊曼首次提出。

(2)归并排序的实现分为递归实现与非递归(迭代)实现。递归实现的归并排序是算法设计中分治策略的典型应用,
我们将一个大问题分割成小问题分别解决,然后用所有小问题的答案来解决整个大问题。非递归(迭代)实现的
归并排序首先进行是两两归并,然后四四归并,然后是八八归并,一直下去直到归并了整个数组。

(3)归并排序算法主要依赖归并(Merge)操作。归并操作指的是将两个已经排序的序列合并成一个序列的操作,归并操作步骤如下:
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
设定两个指针,最初位置分别为两个已经排序序列的起始位置
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针到达序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
(2)
分类 -------------- 内部比较排序
数据结构 ---------- 数组
最差时间复杂度 ---- O(nlogn)
最优时间复杂度 ---- O(nlogn)
平均时间复杂度 ---- O(nlogn)
所需辅助空间 ------ O(n)
稳定性 ------------ 稳定
*/

/*
【8】【【堆排序】】
堆排序(Heap Sort):
堆排序是指利用堆这种数据结构所设计的一种选择排序算法。
堆是一种近似完全二叉树的结构(通常堆是通过一维数组来实现的),
并满足性质:以最大堆(也叫大根堆、大顶堆)为例,其中父结点的值总是大于它的孩子节点。

我们可以很容易的定义堆排序的过程:
(1)由输入的无序数组构造一个最大堆,作为初始的无序区
(2)把堆顶元素(最大值)和堆尾元素互换
(3)把堆(无序区)的尺寸缩小1,并调用heapify(A, 0)从新的堆顶元素开始进行堆调整
(4)重复步骤2,直到堆的尺寸为1

分类 -------------- 内部比较排序
数据结构 ---------- 数组
最差时间复杂度 ---- O(nlogn)
最优时间复杂度 ---- O(nlogn)
平均时间复杂度 ---- O(nlogn)
所需辅助空间 ------ O(1)
稳定性 ------------ 不稳定
*/

/*
【9】【【快速排序】】
快速排序(Quick Sort)
快速排序是由东尼·霍尔所发展的一种排序算法。
在平均状况下,排序n个元素要O(nlogn)次比较。
在最坏状况下则需要O(n^2)次比较,但这种状况并不常见。
事实上,快速排序通常明显比其他O(nlogn)算法更快,
因为它的内部循环可以在大部分的架构上很有效率地被实现出来。

快速排序使用分治策略(Divide and Conquer)来把一个序列分为两个子序列。步骤为:
1.从序列中挑出一个元素,作为"基准"(pivot).
2.把所有比基准值小的元素放在基准前面,所有比基准值大的元素放在基准的后面(相同的数可以到任一边),这个称为分区(partition)操作。
3.对每个分区递归地进行步骤1~2,递归的结束条件是序列的大小是0或1,这时整体已经被排好序了。

分类 ------------ 内部比较排序
数据结构 --------- 数组
最差时间复杂度 ---- 每次选取的基准都是最大(或最小)的元素,导致每次只划分出了一个分区,
                    需要进行n-1次划分才能结束递归,时间复杂度为O(n^2)
最优时间复杂度 ---- 每次选取
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值