简单排序
2017-09-24 16:03
148 查看
概述
排序是数据处理中十分常见且核心的操作,虽说实际项目开发中很小几率会需要我们手动实现,毕竟每种语言的类库中都有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;
}
截图如下:
相关文章推荐
- iOS数组内存放自定义model的简单排序方法
- SortedList、SortedSet、HashSet、Hashtable、Dictionary、SortedDictionary 排序/可重复排序/过滤重复排序等简单对比
- 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现)
- 简单的选择排序
- jQuery实现div横向拖拽排序的简单实例
- 【排序】1.1简单桶排序
- wikioi 1545 最简单的排序
- c+两种简单的数组排序,冒泡排序和类似选择排序的思考
- 冒泡,插入,折半插入,希尔,快速,简单选择排序源码总结
- RecyclerView上下拖动条目排序,左右划出屏幕删除条目的最简单的实现
- 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现)
- 【数据结构】简单查找和排序
- 排序算法之简单排序
- JavaScript 实现页面元素(ul-li)的简单排序
- 常见开放接口签名简单实现-请求参数排序加密
- 几种简单的排序
- jquery拖拽排序简单实现方法(效果增强版)
- 一个简单的合并排序
- 排序(一)——几种简单的排序算法
- 我的hadoop初学程序------简单数据排序-------Sort