在数据结构的书中肯定有一章的内容是实现排序,不同的排序方法适用的场景不同,时间复杂度也不同,在本篇博客中写到了三种最基本的排序,另外,希尔排序,快速排序分别是插入和冒泡排序的衍生,故熟悉基本的排序思想变得尤为重要,在此附上三种基本排序的源码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//定义交换函数
void my_swap(int *a,int x,int y)
{
int temp;
temp=a[x];
a[x]=a[y];
a[y]=temp;
}
//定义打印函数
void my_print(int *a,int len)
{
for(int i=0;i<len;i++)
printf("%d ",a[i]);
printf("\n");
}
void SelecSort(int *a,int len)
{
for(int i=0;i<len;i++)
{
int k=i;
//找到最小元素下标
for(int j=i+1;j<len;j++)
{
if(a[j]<a[k])
k=j;
}
//if(k!=i)
my_swap(a,i,k);
}
}
void InsertSort(int *a,int len)
{
int k=-1;
for(int i=1;i<len;i++)
{
k=i;//等待插入的位置
int temp=a[i];//拿出待插入的值
for(int j=i-1;a[j]>temp&&j>=0;j--)
{
a[j+1]=a[j];//元素后移
k=j;
}
a[k]=temp;
}
}
void BubbleSort(int *a,int len)
{
int flag=1;//优化,若不发生交换,则不再进行排序
for(int i=0; i<len&&flag ;i++)
{
flag=0;
for(int j=i+1;j<len;j++)
{
if(a[i]>a[j])
{
my_swap(a,i,j);
flag=1;
}
}
}
}
void main()
{
int array[]={3,4,2,1,6,9,8,7,5};
int len= sizeof(array)/sizeof(array[0]);
SelecSort(array,len);//选择法排序
my_print(array,len);
InsertSort(array,len);
my_print(array,len);
BubbleSort(array,len);
my_print(array,len);
printf("\n");
printf("hello\n");
}
首先是选择排序,选择排序在第一次外循环结束时找出一个此次循环的最小值下标,通过交换函数将其交换到合适的位置。比如,在i=0时,找出i=1开始至最后一个元素,并保存value值最小的下标记为k,在内循环结束时将下标为K的value交换到下标为0的位置处。同理,i=1时,通过内循环将此次内循环里最小值(此值实际上为次小值,最小值已经被正确排序到下标为0处)。
下面介绍插入排序,插入排序时效率较高的一种基本排序方法,并且希尔排序仅仅是在其上略加改动。插入排序可以分为两步,1:将待排序的元素取出。2:将满足条件的元素后移。由于第一个元素,即下标为0的元素无需插入,故整个插入算法从下标为1的元素开始,若其小于其之前的元素,则将其取出(定义临时变量保存之),同时,将所有满足条件(大于它或者小于它)的值后移。最后将临时变量插入到待插入的位置即可。
接下来是最为熟悉的冒泡排序,相信刚拿到排序的要求的程序员第一反应就是写出冒泡排序法,在这里要提的是关于冒泡法的优化,即设立一个flag标记。 在此段程序中我初始化了一个flag,在每次排序之前,假设此数组已是有序,故将flag赋值为0,但若是在此次排序中发生了交换,即数组并不有序,则重新将flag赋值为1,让其进行下一次排序。这样可以避免在数组已经有序的情况之下进行无用的排序操做。