常见排序算法的总结与比较

简介:   1 冒泡排序 /*作者:chenguolin功能:测试冒泡排序的效率日期:2013.01.10 22:01*//*1 冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。

 

1 冒泡排序

/*
作者:chenguolin
功能:测试冒泡排序的效率
日期:2013.01.10 22:01
*/
/*
1 冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。
即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。
至此第一趟结束,将最大的数放到了最后。
在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,
大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。
如此下去,重复以上过程,直至最终完成排序。

2 由于在排序过程中总是小数往前放,大数往后放,相当于气泡往上升,所以称作冒泡排序。

3 冒泡排序的时间复杂度为O(n^2),是一个稳定的排序算法
*/

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<ctime>
using namespace std;

const int MAXN = 100;
int arr[MAXN];

//冒泡排序主体
void bubbleSort(){
	for(int i = 0 ; i < MAXN-1 ; i++){
		for(int j = 0 ; j < MAXN-1-i ; j++){
		   if(arr[j] > arr[j+1])
			  swap(arr[j] , arr[j+1]);
		}
	}
}

//输出测试是否排序正确
void output(){
   for(int i = 0 ; i < MAXN ; i++)
	  cout<<arr[i]<<" ";
   cout<<endl;
}

int main(){
	//首先产生随机100000个数
    srand(time(0));
	for(int i = 0 ; i < MAXN ; i++){
	   int tmp = rand();
	   arr[i] = tmp;
	}

	clock_t star , end;
	star = clock();//开始测试
	bubbleSort();
	end = clock();//结束测试
	cout<<"Run time = "<<(end - star)<<endl;//输出几ms
	output();
	return 0;
}


 

2 插入排序

/*
作者:chenguolin
功能:测试插入排序的时间
日期:2013.01.10 22:33
*/

/*
1 假定这个数组的序是排好的,然后从头往后,如果有数比当前外层元素的值大,则将这个数的位置往后挪,直到当前外层元素的值大于或等于它前面的位置为止.
  这具算法在排完前k个数之后,可以保证a[1…k]是局部有序的,保证了插入过程的正确性.

2 插入排序的时间复杂度为O(n^2),是一个稳定的算法。
*/


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<ctime>
using namespace std;

const int MAXN = 100000;
int arr[MAXN];

//直接插入排序的主体
void insertSort(){
	for(int i = 1 ; i < MAXN ; i++){
		int tmp = arr[i];
		int j;
		for(j = i-1 ; j >= 0 ; j--){
			if(arr[j] > tmp)//只要比tmp大就往后移动一位
			  arr[j+1] = arr[j];
			else
			  break;
		}
		arr[j+1] = tmp;//j+1这位插入tmp
	}
}

//输出测试是否正确
void output(){
	for(int i = 0 ; i < MAXN ; i++)
	    cout<<arr[i]<<" ";
	cout<<endl;
}

int main(){
	srand(time(0));
	for(int i = 0 ; i < MAXN ; i++){
	   int tmp = rand();
	   arr[i] = tmp;
	}
	clock_t star , end;
	star = clock();
	insertSort();
	end = clock();
	cout<<"Run time = "<<(end-star)<<" ms"<<endl;
	output();
	return 0;
}


 

3 选择排序

/*
作者:chenguolin
功能:测试选择排序的时间效率
日期:2013.01.10  23:03
*/

/*
1 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 

2 选择排序的时间复杂度O(n^2) , 是不稳定的排序方法。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<algorithm>
using namespace std;

const int MAXN = 100000;
int arr[MAXN];

//选择排序的主体
void selectSort(){
	for(int i = 0 ; i < MAXN-1 ; i++){
		int pos = i;
		for(int j = i+1 ; j < MAXN ; j++){
			if(arr[j] < arr[pos])
		       pos = j;
		}
		swap(arr[pos] , arr[i]);
	}
}

//输出测试数据是否排序正确
void output(){
	for(int i = 0 ; i < MAXN ; i++)
	    cout<<arr[i]<<" ";
	cout<<endl;
}

int main(){
   srand(time(0));
   for(int i = 0 ; i < MAXN ; i++){
       int tmp = rand();  
       arr[i] = tmp;
   }
   clock_t star , end;
   star = clock();
   selectSort();
   end = clock();
   cout<<"Run time = "<<(end-star)<<" ms"<<endl;
   output();
   return 0;
}


 

4 快速排序

/*
作者:chenguolin
功能:测试快速排序的时间效率
日期:2013.01.10 23:45
*/

/*
1 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
  然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 

2 快速排序是随机算法中平均最快的,时间复杂度为O(nLogn),有可能退化成O(n^2)。是一个不稳定的算法

int partition(int *arr, int l, int r){
	int pos = (l+r)>>1;//选择中间的数作为基准
	swap(arr[pos], arr[r]);//把这个数交换到最后一个位置
	int leftSeqNum = l; //左子序列的结束位置

	for(int i = l; i < r; i++){
		if(arr[i] < arr[r]){
		   if(leftSeqNum < i)
			   swap(arr[leftSeqNum], arr[i]);
		   leftSeqNum++;
		}	
	}
	//再把基准的值交换到正确的位置
	swap(arr[leftSeqNum], arr[r]);
	return leftSeqNum;
}
void quickSort(int *arr, int l, int r){
    if(arr == NULL || l == r)
		return;
	int index = partition(arr, l, r);
	if(l < index)
		quickSort(arr, l, index-1);
	if(index < r)
		quickSort(arr, index+1, r);
}
 

5 归并排序

/*
作者:chenguolin
功能:测试归并排序的时间效率
日期:2013.01.11 0:00
*/

/*
1 归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,
  每个子序列是有序的。然后再把有序子序列合并为整体有序序列
2 归并排序是一个不存在最好.最坏的情况的算法,算法的时间复杂度为O(nLogn)。是一个稳定的算法
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<algorithm>
using namespace std;

const int MAXN = 100000;
int arr[MAXN];
int tmpArr[MAXN];

//合并
void merge(int left , int mid , int right){
	int i , j , pos;
	i = left , j = mid+1 , pos = left;
	while(i <= mid && j <= right){
	     if(arr[i] <= arr[j])
			tmpArr[pos++] = arr[i++];
		 else
			tmpArr[pos++] = arr[j++];
	}
	while(i <= mid)
	     tmpArr[pos++] = arr[i++];
	while(j <= right)
	     tmpArr[pos++] = arr[j++];
    for(i = left ; i <= right ; i++)
	    arr[i] = tmpArr[i];
}

//两路-归并排序的主体
void mergeSort(int left , int right){
	if(left < right){
	   int mid = (left+right)>>1;
	   mergeSort(left , mid);
	   mergeSort(mid+1 , right);
	   merge(left , mid , right);//合并两部分
	}
}

//测试输出的数据是否正确
void output(){
    for(int i = 0 ; i < MAXN ; i++)
		cout<<arr[i]<<" ";
	cout<<endl;
}

int main(){
	srand(time(0));
	for(int i = 0 ; i < MAXN ; i++){
	    int tmp = rand();
		arr[i] = tmp;
	} 
	clock_t star , end;
	star = clock();
	mergeSort(0 , MAXN-1);
	end = clock();
	cout<<"Run time = "<<(end-star)<<" ms"<<endl;
	output();
	getchar();
	return 0;
}


/*
Author: chenguolin
Date: 2014-02-24
*/

const int MAXN = 1010;
const int INF = 1<<30;

void merge(int *arr, int left, int mid, int right){
    int tmpLeft[MAXN];
    int tmpRight[MAXN]; 
    //copy to tmp arr
    for(int i = 1, j = left; i <= (mid-left+1); i++, j++)
        tmpLeft[i] = arr[j];
    for(int i = 1, j = mid+1; i <= (right-mid); i++, j++)
        tmpRight[i] = arr[j];
    tmpLeft[mid-left+1] = INF;
    tmpRight[right-mid] = INF;
    //merge two arr
    int l = 1, r = 1;
    for(int i = left; i <= right ; i++){
        if(tmpLeft[l] < tmpRight[r])
            arr[i] = tmpLeft[l++];
        else
            arr[i] = tmpRight[r++];
    }
}

void merge_sort(int *arr, int left, int right){
    if(left < right){
        int mid = (left+right)>>1;
        merge_sort(arr, left, mid);
        merge_sort(arr, mid+1, right);
        merge(arr, left, mid, right);
    }
}

int main(){
    return 0;
}

 

6 堆排序

/*
作者:chenguolin
功能:测试堆排序的时间效率
日期:2013.01.11 0:57
*/

/*
1 堆是一棵完全二叉树
2 堆排序首先是先把一个无序的序列整成一个最大堆,然后利用每次取出堆的“根节点+调整堆为最大堆”这种思路对一个序列排序
3 一个具有n个元素的数组,利用堆排序需要总共需要n次调整(第一次是调整为最大堆+排序的n-1调整)
4 堆排序的时间复杂度为O(nLogn),是一个不稳定的算法.
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<algorithm>
using namespace std;

const int MAXN = 100000+10;
const int N = MAXN-10;
int arr[MAXN];

//调整为最大堆
void adjustMaxHeap(int n , int size){
	int l_child , r_child , MAX;
	l_child = 2*n , r_child = 2*n+1 , MAX = n;
	if(l_child <= size && arr[l_child] > arr[MAX])
		MAX = l_child;
	if(r_child <= size && arr[r_child] > arr[MAX])
		MAX = r_child;
	if(MAX != n){//这里只有当MAX != n的时候才进行向下的调整,否则已经是最大或者到叶子节点不用调整
		swap(arr[n] , arr[MAX]);
	    adjustMaxHeap(MAX , size);
	}
}

//把无序序列建成一个最大堆
void initMaxHeap(){
    for(int i = N/2 ; i >= 1 ; i--)//从第一个非叶子节点n/2~1之间做n/2次调整
		adjustMaxHeap(i , N);
}

//堆排序
void heapSort(){
	int size = N;//size是实时的记录堆的元素个数
	for(int i = N ; i >= 2 ; i--){//如果是n个元素只要n-1次即可,当一个元素的时候就是最大不用做
	   swap(arr[i] , arr[1]);//把堆的根节点取出,把第i个元素换上去,这个时候size--就不会去调整到i了。
	   size--;
	   adjustMaxHeap(1 , size);//每次都要进行调整
	}
}

//测试输出数据是否正确
void output(){
	for(int i = 1 ; i <= N ; i++)
		cout<<arr[i]<<" ";
	cout<<endl;
}

int main(){
   srand(time(0));
   for(int i = 1 ; i <= N ; i++){
      int tmp = rand();
	  arr[i] = tmp;
   }
   clock_t star , end;
   star = clock();
   initMaxHeap();
   heapSort();
   end = clock();
   cout<<"Run time = "<<(end-star)<<" ms"<<endl;
   output();
   getchar();
   return 0;
}


 

 

 

 

 

 

 

目录
相关文章
|
9月前
|
Android开发 开发者 Python
手撸了一个全自动微信清粉小工具(源码详解)
微信清理僵尸粉工具利用Python和`uiautomator2`库,通过模拟转账操作自动检测并标记微信好友列表中被删除、被拉黑或账号存在问题的“僵尸粉”。工具支持开启调试模式、自动打开微信、获取好友信息、判断好友状态、管理标签等功能,最终将检测结果记录到文件中,便于用户管理和清理好友列表。此工具适用于Android设备,已在OPPO Reno4 Pro上测试成功。
595 5
|
11月前
|
存储 缓存 监控
如何提高数据驱动方式的性能和可维护性?
【10月更文挑战第13天】 本文深入探讨了提高数据驱动方式性能与可维护性的关键方法和策略,包括优化数据结构选择、数据缓存策略、合理的数据更新策略、数据压缩与精简、代码结构优化、测试与监控、版本控制与协作管理、文档化与知识共享、持续优化的意识及结合实际案例分析,旨在为数据驱动的高效和可持续发展提供全面指导。
|
9月前
|
数据库
脏读、幻读、不可重复读的定义?
脏读、不可重复读和幻读是数据库事务处理中的三种异常现象。脏读指读取未提交的修改数据;不可重复读指同一事务中多次读取数据不一致;幻读指读取记录范围时,前后读取结果数量不一致。这些现象通常由并发事务操作引起。
353 7
|
10月前
|
传感器 缓存 网络协议
CoAP 协议与 HTTP 协议的区别
CoAP(Constrained Application Protocol)协议是为资源受限的设备设计的轻量级协议,适用于物联网场景。相比HTTP,CoAP具有低功耗、低带宽占用和简单易实现的特点,支持多播通信和无连接的交互模式。
|
传感器 存储 安全
机器通信 | 《5G移动无线通信技术》之八
本节主要介绍了机器通信的内容以及超可靠机器类通信。
机器通信  | 《5G移动无线通信技术》之八
|
传感器 人工智能 供应链
报告发布丨数字化助力乡村振兴:《县域数字生态创新趋势展望》
报告指出,借助数字新基建打造“新时空”,县域数字生态加速构建,并揭示了数字技术加速下沉全面赋能县域经济、新型信息基础设施重构县域生产要素、数字化加持下县域生态价值逐步释放等九大趋势。
报告发布丨数字化助力乡村振兴:《县域数字生态创新趋势展望》
|
Java 关系型数据库 数据库连接
快速配置多数据源(整合MyBatis)
本文内容: 在Springboot+Mybatis项目的基础上,学习多数据源的快速配置 避免网上某些配置数据源文章的深坑
535 0
|
存储 运维 算法
云仿真平台有哪些特点
云仿真按照服务模式为用户提供OTS仿真软件,该服务模式采用云计算、大数据算法和人工智能技术实现,遵循软件即服务(saas)的概念,无需安装就可以运行。 仿真软件统一部署在云(公有云或私有云)服务器上,用户可以通过网络获得平台提供的服务,例如仿真操作、理论学习、仿真评估、教师管理、理论考试等。用户可以在云仿真平台操作环境、化工、食品等环境中操作虚拟仿真软件。
云仿真平台有哪些特点
|
安全 搜索推荐
秒懂云通信:如何用阿里云平台发短信?
手把手教你如何用阿里云平台发短信,超详细控制台步骤解析,快速上手!更有1650元短信体验代金券和免费试用,点击速抢!
4169 0
秒懂云通信:如何用阿里云平台发短信?