简单排序
来源:互联网 发布:php 一致性hash算法 编辑:程序博客网 时间:2024/06/06 01:01
概述
排序是数据处理中十分常见且核心的操作,虽说实际项目开发中很小几率会需要我们手动实现,毕竟每种语言的类库中都有n多种关于排序算法的实现。但是了解这些精妙的思想对我们还是大有裨益的。冒泡,插入这三种排序是最简单的排序,本文将主要讲解这两种排序思想。
关与图解请参照如下地址的博客(是在不好画图,自己的图就是取自这篇博客):http://www.cnblogs.com/chengxiao/p/6103002.html
冒泡排序
冒泡排序的基本思想是,对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。图解如下图所示:
算法如下:
//冒泡排序void Bubble_Sort(int* data ,int size){ for(int i = size-1 ; i >= 0 ; i--){ bool flag = false; //、是否交换标志 for(int j = 0 ; j < i ; j++){ if(data[j+1] < data[j]){ Swap(data[j],data[j+1]); flag = true;//发生了交换 } } if(flag == false){//全程无交换 break; } }}
总结:对于冒泡排序而言,最坏情况是数组完全逆序,时间复杂度为O(n^2),最好情况为数组已经有序,时间复杂度为O(n),平均来看时间复杂度为O(n^2)。
插入排序
直接插入排序基本思想是每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。图解如下:
算法如下:
//直接插入排序void Insertion_Sort(int* data ,int size){ for(int i = 1 ; i < size ; i++){ int tmp = data[i]; int j; for(j = i ; j > 0 && data[j-1] > tmp ; j--){ //前一个数大于后一个树,进行交换 data[j] = data[j-1]; } //找到合适位置,进行插入 data[j] = tmp; }}
由于直接插入排序的插入元素可能每次不在最佳位置上,为了减少移动次数,这里引用折半查找的思想,首先找到元素最佳位置,然后整体进行移动。
算法如下:
//折半插入排序void Binary_Insertion_Sort(int* data,int size){ for(int i = 1 ; i < size ; i++){ int low = 0,high = i-1;//在i之前找到最佳位置 int tmp = data[i],j; while(low <= high){//寻找最佳位置 int mid = (low+high)/2; if(data[mid] < tmp){ //大于中间值,到右半部分寻找 low = mid+1; }else{//小于中间值,到左半部分寻找 high = mid-1; } } for(j = i ; j > low ; j--){ data[j] = data[j-1]; } data[j] = tmp; } }
总结:对于直接插入排序而言,最坏情况是数组全部逆序,这是时间复杂度为O(n^2),最好情况下,数组已经有序,那么算法只是执行一次循环,时间复杂度为O(n)。平均而言时间复杂度为O(n^2)。对于折半插入排序而言,它只是在直接插入排序的基础上用二分法思路进行快速查找元素在这一趟中最佳存放位置,这一步的时间复杂度为O(nlogn),但是仍需用一个循环把相应的元素进行移动。故整体最好时间复杂度为O(nlogn),最差时间复杂度为O(n^2),平均时间复杂度为O(n^2)。
结论
对于下标i
全部代码
#include <iostream>#include <cstdlib>#include <ctime>using namespace std;//初始化数组 void SetArray(int* data,int size){ //srand(time(0)); cout<<"随机初始化"<<size<<"个数"<<endl; for(int i = 0 ; i < size ; i++){ data[i] =rand()%100+1; }}//打印函数 void Print(int* data ,int size){ for(int i = 0 ; i < size ; i++){ cout<<data[i]<<" "; } cout<<endl;}//交换函数 void Swap(int& a ,int& b){ int tmp = a; a = b; b = tmp;}//冒泡排序void Bubble_Sort(int* data ,int size){ for(int i = size-1 ; i >= 0 ; i--){ bool flag = false; //、是否交换标志 for(int j = 0 ; j < i ; j++){ if(data[j+1] < data[j]){ Swap(data[j],data[j+1]); flag = true;//发生了交换 } } if(flag == false){//全程无交换 break; } }}//直接插入排序void Insertion_Sort(int* data ,int size){ for(int i = 1 ; i < size ; i++){ int tmp = data[i]; int j; for(j = i ; j > 0 && data[j-1] > tmp ; j--){ //前一个数大于后一个树,进行交换 data[j] = data[j-1]; } //找到合适位置,进行插入 data[j] = tmp; }}//折半插入排序void Binary_Insertion_Sort(int* data,int size){ for(int i = 1 ; i < size ; i++){ int low = 0,high = i-1;//在i之前找到最佳位置 int tmp = data[i],j; while(low <= high){ int mid = (low+high)/2; if(data[mid] < tmp){ low = mid+1; }else{ high = mid-1; } } for(j = i ; j > low ; j--){ data[j] = data[j-1]; } data[j] = tmp; } } int main(){ cout<<"请输入数组长度:"<<endl; int size,*data; cin>>size; data = new int[size]; SetArray(data,size); cout<<"冒泡排序前:"<<endl; Print(data,size); cout<<"冒泡排序后:"<<endl; Bubble_Sort(data,size); Print(data,size); SetArray(data,size); cout<<"直接插入排序前:"<<endl; Print(data,size); cout<<"直接插入排序后:"<<endl; Insertion_Sort(data,size); Print(data,size); SetArray(data,size); cout<<"折半插入排序前:"<<endl; Print(data,size); cout<<"折半插入排序后:"<<endl; Binary_Insertion_Sort(data,size); Print(data,size); return 0; }
截图如下:
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- 简单排序
- Java设计模式——建造者模式(Builder Pattern)
- 收集整理一些常用的MySQL命令
- DITHER 抖动算法(转载)
- C++ explicit关键字详解
- JAVA线程池原理详解二
- 简单排序
- ServletContext详解
- 课堂练习1: 请定义一个交通工具(Vehicle)的类
- 搜狗词库爬虫(2):基础爬虫框架的运行流程
- 《计算机网络原理》_物理层
- SQL判断成员是否在部门列表中
- 424. Longest Repeating Character Replacement
- 基础复习06
- 可伸缩TextView和TextView显示错位问题