首页 > 其他分享 >十大排序(详解)---上

十大排序(详解)---上

时间:2024-12-23 09:59:38浏览次数:10  
标签:arr int 复杂度 len --- 详解 序列 排序

 

文章目录

前言

一、冒泡排序 

     二、插入排序  

         三、堆排序 

              四、希尔排序

                   五、选择排序

总结


前言

      排序算法是计算机科学中用于对元素进行排序的算法。根据不同的需求和数据特性,有多种不同的排序算法,它们在时间复杂度、空间复杂度和稳定性等方面各有千秋。 一起来看看吧!


一、冒泡排序

      冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。

原理:左边大于右边时进行交换,一趟排下来最大的在右边

动图演示:

时间复杂度:最好O(N),最差O(N^2)

空间复杂度:O(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 = sizeof(arr) / sizeof(arr[0]);
        bubble_sort(arr, len);
        int i;
        for (i = 0; i < len; i++)
                printf("%d ", arr[i]);
        return 0;
}

效果演示:

二、插入排序

插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。

思路:

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

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

时间复杂度:最好O(N),最差O(N^2)

空间复杂度:O(1)

动图演示:

代码:

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;
        }
}

效果演示:

三、堆排序

       堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。

分为两种方法:

  1. 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
  2. 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;

思路:

  1. 创建一个堆 H[0……n-1];

  2. 把堆首(最大值)和堆尾互换;

  3. 把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;

  4. 重复步骤 2,直到堆的尺寸为 1。

时间复杂度:Ο(nlogn)

空间复杂度:O(1)

动图演示:

代码:

#include <stdio.h>
#include <stdlib.h>

void swap(int *a, int *b) {
    int temp = *b;
    *b = *a;
    *a = temp;
}

void max_heapify(int arr[], int start, int end) {
    // 建立父節點指標和子節點指標
    int dad = start;
    int son = dad * 2 + 1;
    while (son <= end) { // 若子節點指標在範圍內才做比較
        if (son + 1 <= end && arr[son] < arr[son + 1]) // 先比較兩個子節點大小,選擇最大的
            son++;
        if (arr[dad] > arr[son]) //如果父節點大於子節點代表調整完畢,直接跳出函數
            return;
        else { // 否則交換父子內容再繼續子節點和孫節點比較
            swap(&arr[dad], &arr[son]);
            dad = son;
            son = dad * 2 + 1;
        }
    }
}

void heap_sort(int arr[], int len) {
    int i;
    // 初始化,i從最後一個父節點開始調整
    for (i = len / 2 - 1; i >= 0; i--)
        max_heapify(arr, i, len - 1);
    // 先將第一個元素和已排好元素前一位做交換,再重新調整,直到排序完畢
    for (i = len - 1; i > 0; i--) {
        swap(&arr[0], &arr[i]);
        max_heapify(arr, 0, i - 1);
    }
}

int main() {
    int arr[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };
    int len = (int) sizeof(arr) / sizeof(*arr);
    heap_sort(arr, len);
    int i;
    for (i = 0; i < len; i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

效果演示:

四、希尔排序

       希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;
  • 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;

       希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。

思路:

选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;

按增量序列个数 k,对序列进行 k 趟排序;

每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

时间复杂度:Ο(Nlog^2N)

空间复杂度:O(1)

动图演示:

代码:
void shell_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;
                }
}
效果演示:

五、选择排序

       选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。

思路:

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

重复第二步,直到所有元素均排序完毕。 

时间复杂度:Ο(N^2)

空间复杂度:O(1)

动图演示:


 

代码:
void swap(int *a,int *b) //交換兩個變數
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
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]);    //做交換
        }
}

效果演示:


总结

        以上就是十大排序法中的其中一部分,后续我会带来更多实用的内容,对你有用的话可以点个赞支持一下!  

标签:arr,int,复杂度,len,---,详解,序列,排序
From: https://blog.csdn.net/2401_87734250/article/details/144645353

相关文章

  • 【Java教程】Day1-03 环境安装:从安装 JDK 到使用 IDE
    在开始学习Java编程之前,搭建一个合适的开发环境是至关重要的。良好的开发环境不仅能提高你的编程效率,还能帮助你更好地理解Java编程语言的工作原理。本节将带你了解如何安装JDK(Java开发工具包),如何通过命令行编译和运行Java程序,以及如何利用集成开发环境(IDE)来进行更高效......
  • 写一个方法将一个未排序的数组中找出任意两数之和等于给定的数
    在前端开发中,你可以使用JavaScript来编写这个方法。以下是一个简单的示例,展示如何在未排序的数组中找出任意两数之和等于给定数的所有组合:functionfindPairsWithSum(arr,targetSum){constpairs=[];constcomplementMap=newMap();for(leti=0;i<ar......
  • 光伏智能踏勘流程-无人机踏勘
    一、无人机航飞采集屋顶使用无人机+焱图慧云飞控软件踏勘精灵APP,无需专业飞手,操作简单,自适应多场景航拍(二维弓字、三维环绕)。自主巡航作业,支持断点续飞。无人机自主飞行采集数据、自动规划航飞路线,一键采集,快速获取屋顶现状照片数据。踏勘再也不同爬屋顶了。  二、数据上......
  • js逆向-客户端渲染
    这是本文用到的网址西游记_百度小说,是百度小说的西游记。打开网页源代码,发现没有和页面相关的代码所以应该不是直接爬取网页源代码,那就打开开发者工具,刷新网页,但是获取的网页非常多,一个一个寻找太麻烦,所以利用ctrl+f打开搜索,例如,查找第一回很快就可以找到对应网页,或许你以为......
  • 融云IM干货丨pages.json 文件用来对 uni-app 进行全局配置
    在uni-app中,`pages.json`文件是一个非常重要的配置文件,它用于定义应用中的页面路径、窗口表现以及全局配置等。以下是`pages.json`文件的一些关键配置项和它们的作用:1.**pages**:  -这个数组定义了应用中的所有页面路径,每个对象代表一个页面。数组中的每个对象至少包含......
  • 【数字IC&FPGA项目】AHB_UART-FIFO控制器设计
    【数字IC&FPGA项目】AHB_UART-FIFO控制器设计实现一个带FIFO的UART收发控制器,并挂在AHB接口上,分为AHB接口和控制模块、发送FIFO、UART发送器、接收FIFO、UART接收器、波特率分频器模块:各部分实现功能:UART发送器:从发送FIFO中读取一个字节的数据(8bit),进行并/串转换并发送到......
  • .NET 9 New features-AOT相关的改进
    上一篇文章给大家介绍了.NET9Newfeatures-JSON序列化 本篇文章,研究分享一下关于AOT方面的改进1.什么是AOTAOT(Ahead-of-Time)编译是一种在应用程序部署之前,将高级语言代码直接编译为本机机器代码的技术。与传统的即时编译(Just-In-Time,JIT)不同,AOT在应用程序运行之前完成编......
  • 前端-如何把手风琴和表格融合一起
    效果示意图:模板代码:<divstyle="width:80%;overflow-x:scroll;overflow-y:scroll"><divstyle="margin-top:5px;height:500px"><tableclass="header-table"><thead><......
  • 题解 - 换位置游戏
    题目描述N个小朋友(编号为1到N)正在玩一个换位置游戏。从左到右依次排列着N个凳子(编号为1到N,最左边的为1号凳子,最右边的为N号凳子),每个凳子上都有一个数字(凳脚处红色数字),每个数字互不相同,且都是不超过N的正整数。游戏开始前,1号小朋友坐在1号凳子上,2号小......
  • 天地图接口Python代码详解
    天地图是中国国家测绘地理信息局推出的一款权威、全面的在线地理信息系统,提供了丰富的卫星影像、地形、矢量图等地图资源。开发者可以通过天地图提供的API接口,实现地图的展示、搜索、定位等功能。本文将详细介绍如何使用Python调用天地图接口,包括理论概述和详细的代码示例。一、......