排序算法-常用
冒泡排序
排序是将一组数据升序或者降序排列;这里排序会用到比较,比较可以从前向后,也可以从后向前,平均时间复杂度 O ( n 2 ) O(n^2) O(n2),最差时间复杂度 O ( n 2 ) O(n^2) O(n2)。
1、原理和图示
比较相邻的两个位置上的数据,升序则大的交换至右边,相等则不交换,冒泡排序是稳定的排序算法;下面从左至右比较实现降序为例,假设共n个数据项:
1)比较第1个和第2个位置数据,较小的放左边,然后比较第2个和第3个位置数据,较小的放左边,直到比较倒数第n-1个和倒数第n个位置数据,较小放左边;
实现将最小的一个数放在了最右边位置。
2)重复步骤1),但是最小的位置已经放在最后,因此只需比较至倒数第n-2和倒数第n-1位置即可;
3)没重复一次步骤1),后面的位置减少1,共进行n-1轮次即可,第1轮次比较n-1次比较,第2轮次进行n-2次比较,最后一轮次比较1次即可;
4)整个过程就像将当前最小数依次冒泡至当前最左边;
下面是举例:
2、C实现,redhat7.5
#include <stdio.h>
#include <stdlib.h>
void BubbleSort(int data[],int size)
{
if(!data||size<2)
{
return;
}
for(int i=0;i<size-1;i++)
{
bool flag = true;
for(int j=0;j<size-i-1;j++)
{
if(data[j]<data[j+1])
{
flag = false;
int t = data[j+1];
data[j+1] = data[j];
data[j] = t;
}
}
if(flag)
break;
}
}
int main(int argc, char* argv[]){
int dat[8] = {7,1,2,3,4,8,6,2};
printf("sizeof(dat)=%d\n",sizeof(dat));
int size = 8;
int i = 0;
for(i=0;i<size;i++)
{
printf("%d ",dat[i]);
}
printf("\n");
BubbleSort(dat,size);
for(i=0;i<size;i++)
{
printf("%d ",dat[i]);
}
printf("\n");
return 0;
}
快速排序
快速排序是将冒泡排序和分治思想结合的方法。
1、原理和图示
1)单次操作:给定一组数据,选取其中一个为基准值,有两个指针分别从两端向中间遍历,与基准值比较,直到两个指针相遇,将基准值填在相遇位置即可。
2)图示,红色为基准,蓝色为交换值,降序排列
2、C实现,redhat7.5
#include <stdio.h>
#include <stdlib.h>
void QuickSort(int data[],int left,int right)
{
if(left>right||!data)
{
return;
}
int base = data[left];
int i=left;
int j=right;
while(i<j)
{
while(i<j&&base > data[j])
j--;
data[i]=data[j];
while(i<j&&base <= data[i])
i++;
data[j]=data[i];
}
data[i] = base;
QuickSort(data,left,i-1);
QuickSort(data,i+1,right);
}
int main(int argc, char* argv[]){
int dat[8] = {7,1,2,3,4,8,6,2};
printf("sizeof(dat)=%d\n",sizeof(dat));
int size = 8;
int i = 0;
for(i=0;i<size;i++)
{
printf("%d ",dat[i]);
}
printf("\n");
QuickSort(dat,0,size-1);
for(i=0;i<size;i++)
{
printf("%d ",dat[i]);
}
printf("\n");
return 0;
}
插入排序
1、原理和图示
原理:
分两个区域,已排序就绪区、待排序区;步骤是将待排序区的数值一个个的插入到已排序就绪区的正确位置,直到全部排序完毕。
图示:
如下表,左边的黑框是已排序就绪区,右边是待排序区,前十步包含了两圈比较和插入。降序排列
2、C实现,redhat7.5
#include <stdio.h>
#include <stdlib.h>
void InsertSort(int data[],int size)
{
if(size<2||!data)
{
return;
}
int i=0;
int j=0;
int temp=0;
for(i=1;i<size;i++)
{
temp=data[i];
for(j=i-1;j>=0;j--)
{
if(data[j]<temp)
{
data[j+1] = data[j];
}else
{
break;
}
}
data[j+1] = temp;
}
}
int main(int argc, char* argv[]){
int dat[8] = {7,1,2,3,4,8,6,2};
printf("sizeof(dat)=%d\n",sizeof(dat));
int size = 8;
int i = 0;
for(i=0;i<size;i++)
{
printf("%d ",dat[i]);
}
printf("\n");
InsertSort(dat,size);
for(i=0;i<size;i++)
{
printf("%d ",dat[i]);
}
printf("\n");
return 0;
}
选择排序
1、原理和图示
原理:
选择排序思想比较容易理解,就是遍历最大或者最小的数据,放在最前或者最后,依次从待选择区的元素中选择最小或者最大的元素放入已排序的队列尾部或者头部。从左边第一个元素开始,保存临时最大值,找到最大的放在左边,双层循环。直到将所有数据排序好。
图示:降序排列
2、C实现,redhat7.5
#include <stdio.h>
#include <stdlib.h>
void SelectSort(int data[],int size)
{
if(size<2||!data)
{
return;
}
int i=0;
int j=0;
int temp=0;
int max=0;
for(i=0;i<size;i++)
{
max=data[i];
for(j=i;j<size;j++)
{
if(data[j]>max)
{
temp = data[j];
data[j] = max;
max = data[j];
}
}
data[i] = max;
}
}
int main(int argc, char* argv[]){
int dat[8] = {7,1,2,3,4,8,6,2};
printf("sizeof(dat)=%d\n",sizeof(dat));
int size = 8;
int i = 0;
for(i=0;i<size;i++)
{
printf("%d ",dat[i]);
}
printf("\n");
InsertSort(dat,size);
for(i=0;i<size;i++)
{
printf("%d ",dat[i]);
}
printf("\n");
return 0;
}
希尔排序
1、原理和图示
插入排序与分治思想结合,图示省略
2、C实现,redhat7.5
#include <stdio.h>
#include <stdlib.h>
void InsertInSort(int data[],int s,int index)
{
int temp = data[s];
int i = 0;
for(i = s-index;i>0&&temp > data[i];i-=index)
{
data[i+index] = data[i];
}
data[i+index] = temp;
}
void ShellSort(int data[],int size)
{
if(!data||size<2)
{
return;
}
int l = 0;
int index = 0;
for(index = size/2;index>0;index /= 2)
{
for(l=index;l<size;l++)
{
InsertInSort(data,l,index);
}
}
}
int main(int argc, char* argv[]){
int dat[9] = {7,1,2,9,3,4,8,6,2};
int size = sizeof(dat)/sizeof(int);
int i = 0;
for(i=0;i<size;i++)
{
printf("%d ",dat[i]);
}
printf("\n");
ShellSort(dat, size);
for(i=0;i<size;i++)
{
printf("%d ",dat[i]);
}
printf("\n");
return 0;
}
归并排序
1、原理和图示
分治思想的另一种实现,普通排序算法一般都是两层意思,先访问到数据元素,再将其比较或者交换,减少访问次数、比较次数、交换次数都有可能加快速度,图示省略
2、C实现,redhat7.5
#include <stdio.h>
#include <stdlib.h>
void merge(int data[],int left,int mid,int right)
{
int buf[right-left+1];
int l = left;
int m = mid+1;
int i=0;
while(l<=mid&&m<=right)
{
if(data[l]>data[m])
{buf[i++]=data[l++];}
else
{buf[i++]=data[m++];}
}
while(l<=mid){buf[i++]=data[l++];}
while(m<=right){buf[i++]=data[m++];}
for(int j=0;j<i;j++)
data[left++]=buf[j];
}
void MergeSort(int data[],int left,int right)
{
if(!data)
return;
if(left<right)
{
int mid = (right+left)/2;
MergeSort(data, left, mid);
MergeSort(data, mid+1, right);
merge(data, left, mid, right);
}
}
int main(int argc, char* argv[]){
int dat[9] = {7,1,2,9,3,4,8,6,2};
int size = sizeof(dat)/sizeof(int);
int i = 0;
for(i=0;i<size;i++)
{
printf("%d ",dat[i]);
}
printf("\n");
MergeSort(dat, 0, 8);
for(i=0;i<size;i++)
{
printf("%d ",dat[i]);
}
printf("\n");
return 0;
}