十大经典排序算法

1.冒泡排序

动图演示

 代码实现

#include <stdio.h>
void bubble_sort(int arr[], int len) {
        int i, j, temp;
        for (i = 0; i < len - 1; i++)
                for (j = 0; j < len - 1 - i; j++)
                        if (arr[j] > arr[j + 1]) {
                                temp = arr[j];
                                arr[j] = arr[j + 1];
                                arr[j + 1] = temp;
                        }
}
int main() {
        int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
        int len = (int) sizeof(arr) / sizeof(*arr);
        bubble_sort(arr, len);
        int i;
        for (i = 0; i < len; i++)
                printf("%d ", arr[i]);
        return 0;
}

2.选择排序

动图演示:

代码实现

void selection_sort(int arr[], int len)
{
    int i,j;

        for (i = 0 ; i < len - 1 ; i++)
    {
                int min = i;
                for (j = i + 1; j < len; j++)     //走訪未排序的元素
                        if (arr[j] < arr[min])    //找到目前最小值
                                min = j;    //紀錄最小值
                swap(&arr[min], &arr[i]);    //做交換
        }
}

3.插入排序

将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

动图演示:

 代码实现

void insertion_sort(int arr[], int len){
        int i,j,key;
        for (i=1;i<len;i++){
                key = arr[i];
                j=i-1;
                while((j>=0) && (arr[j]>key)) {
                        arr[j+1] = arr[j];
                        j--;
                }
                arr[j+1] = key;
        }
}

4.希尔排序

动图演示:

 代码实现:

void sort(int arr[], int len) {
        int gap, i, j;
        int temp;
        for (gap = len >> 1; gap > 0; gap >>= 1)
                for (i = gap; i < len; i++) {
                        temp = arr[i];
                        for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap)
                                arr[j + gap] = arr[j];
                        arr[j + gap] = temp;
                }
}

 注意:增量序列应该互为质数,例如:【5 2 1】

5.归并排序

动图演示:

 代码实现:

//归并排序
//  编程实现两个有序数组arr1和arr2合并
//  函数参数:有序数组arr1 数组arr1长度 有序数组arr2 数组arr2长度
//  函数返回值:返回从小到大排序后的合并数组
int* merge_array(int *arr1, int n1, int* arr2, int n2)

{
  
    int i=0,j=0,k=0,min,result[n1+n2];
    while(k<n1+n2)
    {
        if(i<n1 && j<n2)
        {
            if(arr1[i]<arr2[j])
            {
                min=arr1[i];
                i++;
            }else{
                min=arr2[j];
                j++;
            }
        }else{
            if(i>=n1)
            {
                min=arr2[j];
                j++;
            }else if(j>=n2)
            {
                min=arr1[i];
                i++;
            }
        }
        result[k]=min;
        k++; 
    }
    for(int n=0;n<k;n++)
    {
        arr1[n]=result[n];
    }
    return arr1;
  
}

//  基于merge_array函数编程实现归并排序:自上而下的递归方法
//  函数参数:有序数组arr 数组arr长度
//  函数返回值:返回从小到大排序后的数组
int* merge_sort(int *arr, int n)

{
    if(n<=1)
        return arr;
    int *arr1,*arr2;
    arr1 = (int*)malloc(sizeof(int)*n);
    arr2 = (int*)malloc(sizeof(int)*n);
    for(int i=0; i<n; i++)
    {
        if(i<n/2)
            arr1[i]=arr[i];
        else
            arr2[i-n/2]=arr[i];
    }
    arr1=merge_sort(arr1,n/2);
    arr2=merge_sort(arr2,n-n/2);
    return merge_array(arr1,n/2,arr2,n-n/2);
   
}

6.快速排序

  • 算法步骤:

    1. 从数列中挑出一个元素,称为基准pivot

    2. 分区partition操作:比基准值小的元素放在左边,比基准值大的元素放在右边;

    3. 递归recursive:把小于基准值元素的子数列和大于基准值元素的子数列分别递归排序。

  • 代码实现:

  • 
    int partition_array(int *arr, int l, int r){
         int key;
        key = arr[l];
        while(l<r){
            while(l <r && arr[r]>= key )
                r--;
            if(l<r)
                arr[l++] = arr[r];
            while( l<r && arr[l]<=key )
                l++;
            if(l<r)
                arr[r--] = arr[l];
        }
        arr[l] = key;
        return l;
    }
    // arr[l, r]分区:选定一个基准,左边比基准小,右边比基准大
    // 返回基准所处位置
    
    void quick_sort(int *arr, int l, int r){
         int pos;
        if (l<r){
            pos = partition_array(arr, l, r);
            quick_sort(arr,l,pos-1);
            quick_sort(arr,pos+1,r);
        }
        return;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值