选择排序的思路非常简单,就是依次从头到尾挑选合适的元素放到前面。如果总共有n个节点,那么选择一个合适的节点需要比较n次,而总共要选择n次,因此总的时间复杂度是O(n2)。
选择排序的思路是,假设有一个数组:3 2 5 1 7
假设第一个数为最小值和后续的数字进行比较,如 3>2 ,此时min的值=2,让2继续进行比较,
当2>1,这时min=1,当for结循环束,没有比1更小的数时,使用一个for循环找到最小值的坐标如这个数组中 1 的下标为 3 (数组的下标从0 开始),设置一个中间变量d,第一次选择排序就是
a[0]=3,min=1;
d=a[0];
a[0]=min;
a[3]=d;交换数值后,a[0]=1,a[3]=3
则第一次选择排序后 数组:1 2 5 3 7。后续以此类推,将a[0],a[1]......慢慢选择到合适的位置
void sort(int a[],int len)
{
int min,d,k=0;
for(int i=0;i<len-1;i++)
{
min=a[i]; //假设a[i]为最少值
for(int j=i+1;j<len;j++)
{
if(min>a[j]) //判断后续的数字若是小于min
{
min=a[j]; //将a[j]设置为最低值,继续进行排序
k++;
}
}
if(k!=0) //判断是否进行了交换数值
{
for(int m=1;m<len;m++)
{
if(a[m]==min) //寻找最小值的坐标,进行交换
{
d=a[i];
a[i]=min;
a[m]=d;
}
}
}
k=0;
}
代码演示效果如下:
代码如下:有需要的小伙伴可以参考(可以根据题目条件进行修改代码)
#include<stdio.h>
void sort(int a[],int len)
{
int min,d,k=0;
for(int i=0;i<len-1;i++)
{
min=a[i]; //假设a[i]为最少值
for(int j=i+1;j<len;j++)
{
if(min>a[j]) //判断后续的数字若是小于min
{
min=a[j]; //将a[j]设置为最低值,继续进行排序
k++;
}
}
if(k!=0) //判断是否进行了交换数值
{
for(int m=1;m<len;m++)
{
if(a[m]==min) //寻找最小值的坐标,进行交换
{
d=a[i];
a[i]=min;
a[m]=d;
}
}
}
k=0;
}
printf("排序后的数组:");
for(int i=0;i<len;i++)
{
printf("%d\t\t",a[i]);
}
}
int main()
{
int j,a[5]={0};
int len=sizeof(a)/sizeof(int);
printf("请输入任意的5个数:\n");
for(int j=0;j<5;j++)
{
scanf("%d",&a[j]);
}
printf("排序前的数组:");
for(int j=0;j<5;j++)
{
printf("%d\t\t",a[j]);
}
printf("\n");
sort(a,len);
}
快速排序
快排是一种递归思想的排序算法,先比较其他的排序算法,它需要更多内存空间,但快排的语句频度是最低的,理论上时间效率是最高的。
快速排序的核心点就是找到一个支点如上图所示。
核心代码如下我带大家一步步看,假设现有一个7个数的数组:54 3 95 14 67 9 20
从注释快速排序中开始看,将数组和长度传入partion,定义i和j将数组中的第一位和最后一位标记出
54 3 95 14 67 9 20
i j 开始判断右边是否小于左边,如果小于退出,并且交换数值。
第一次交换后数组成 20 3 95 14 67 9 54 开始第二次判断
i j
第二次交换后数组 20 3 54 14 67 9 95 返回 i 的值 i=2
i j
返回后再次进行函数,不过这次的数组长度为2,数组 20 3 交换后 数组 3 20
在进行一次函数,函数从arr[3]开始,数组长度为4,数组 14 67 9 95
i j
交换后的数组 9 67 14 95
i j
交换 9 14 67 95
i j
第一次快速排序后,数组 3 20 54 9 14 67 95,第一次快速排序后数组并非出现规律状
第二次快快速排序后,数组 3 14 20 9 54 67 95,第二次快速排序中出现支点54
快速排序理解起来比较麻烦,但快速排序是常用的排序方法,可以用草稿纸慢慢理解。
int partion(int *arr, int len)
{
int i, j;
if(len <= 1)
return 0;
i = 0;
j = len-1;
while(i < j)
{
//找到右边小于左边值,则退出
while( arr[i] < arr[j] && i < j) //只要右边比左边大,j可以向左移动
{
j--;
}
swap(&arr[i], &arr[j]);
//找到左边大于右边值,则退出
while( arr[i] <= arr[j] && i < j) //只要右边比左边大,i可以向右移动
{
i++;
}
swap(&arr[i], &arr[j]);
}
//返回支点
return i;
}
//快速排序
void quicksort(int *arr,int len)
{
if(len <= 1)
return;
int pivot = partion(arr, len);
// display(arr, len);
quicksort(arr, pivot);
quicksort(arr+pivot+1, len-pivot-1);
}
void swap(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
代码演示效果如下:
代码如下:
#include <stdio.h>
//快速排序
void quicksort(int *p,int len);
//交换数值
void swap(int *a, int *b);
//输出数组
void display(int *arr, int len);
int main(void)
{
int i, len;
int arr[7];
len = sizeof(arr)/sizeof(int);
printf("请输入7个整数:\n");
for(i=0; i<7; i++)
{
scanf("%d", &arr[i]);
}
printf("排序前数据:\n");
display(arr, len);
quicksort(arr, len);
printf("排序后数据:\n");
display(arr, len);
}
int partion(int *arr, int len)
{
int i, j;
if(len <= 1)
return 0;
i = 0;
j = len-1;
while(i < j)
{
//找到右边小于左边值,则退出
while( arr[i] < arr[j] && i < j) //只要右边比左边大,j可以向左移动
{
j--;
}
swap(&arr[i], &arr[j]);
//找到左边大于右边值,则退出
while( arr[i] <= arr[j] && i < j) //只要右边比左边大,i可以向右移动
{
i++;
}
swap(&arr[i], &arr[j]);
}
//返回支点
return i;
}
//快速排序
void quicksort(int *arr,int len)
{
if(len <= 1)
return;
int pivot = partion(arr, len);
// display(arr, len);
quicksort(arr, pivot);
quicksort(arr+pivot+1, len-pivot-1);
}
void swap(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
//输出数组
void display(int *arr, int len)
{
int i;
for(i=0; i<len; i++)
{
printf("%d\t", arr[i]);
}
printf("\n");
}