简易的选择排序与快速排序

选择排序的思路非常简单,就是依次从头到尾挑选合适的元素放到前面。如果总共有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");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值