首页 > 编程语言 >数据结构第19节 排序算法(1)

数据结构第19节 排序算法(1)

时间:2024-07-10 18:31:00浏览次数:19  
标签:arr 12 22 19 34 64 排序 数据结构

冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

冒泡排序步骤详解

假设我们有以下数组:

int[] arr = {64, 34, 25, 12, 22, 11, 90};

第一轮冒泡排序

初始数组比较结果
6464 > 3434, 64
3464 > 2534, 25, 64
2564 > 1234, 25, 12, 64
1264 > 2234, 25, 12, 22, 64
2264 > 1134, 25, 12, 22, 11, 64
1164 > 90(不变)
最后,64 和 90 比较34, 25, 12, 22, 11, 64, 90

第一轮结束后,最大的元素90已经到达了正确的位置。

第二轮冒泡排序

初始数组比较结果
3434 > 2525, 34
2534 > 1225, 12, 34
1234 > 2225, 12, 22, 34
2234 > 1125, 12, 22, 11, 34
11(不变)
最后,34 和 90 不需要比较,因为90已经在正确的位置

第二轮结束后,次大的元素64已经到达了正确的位置。

在冒泡排序的过程中,每一轮都会把当前未排序部分的最大值“浮”到正确的位置。在前两轮之后,我们已经有了最大值90和次大值64在正确的位置。接下来,我们展示第三轮冒泡排序的详细过程。

假设我们有以下数组:

int[] arr = {34, 25, 12, 22, 11, 64, 90};

第三轮冒泡排序

初始数组比较结果
3434 > 2525, 34
2534 > 1225, 12, 34
1234 > 2225, 12, 22, 34
2234 > 1125, 12, 22, 11, 34
11(不变)
最后,34 和 64 不需要比较,因为64已经在正确的位置

在这一轮结束时,数组的状态如下:

arr = {25, 12, 22, 11, 34, 64, 90};

可以看到,经过第三轮的冒泡,数组中的第三大的值34已经移动到了它的正确位置,即数组的倒数第三位。

第四轮冒泡排序

初始数组比较结果
2525 > 1212, 25
1225 > 2212, 22, 25
2225 > 1112, 22, 11, 25
11(不变)

在这一轮结束时,数组的状态如下:

arr = {12, 22, 11, 25, 34, 64, 90};

第五轮冒泡排序

初始数组比较结果
1212 > 1111, 12
11(不变)

在这一轮结束时,数组的状态如下:

arr = {11, 12, 22, 25, 34, 64, 90};

此时,数组已经完全排序,所有元素都在它们应该在的位置上。

需要注意的是,冒泡排序的优化版本会在一轮遍历中如果没有发生任何交换则停止排序,这意味着数组已经是有序的。在这个例子中,第五轮排序完成后,数组已经是升序排列,所以后续的遍历将不会发生任何变化。

最终的排序结果应该是:

arr = {11, 12, 22, 25, 34, 64, 90};

冒泡排序的Java代码实现

下面是使用Java实现冒泡排序的代码:

public class BubbleSortExample {
    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};

        bubbleSort(arr);

        System.out.println("Sorted array : ");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }

    static void bubbleSort(int[] arr) {
        int n = arr.length;
        boolean swapped;
        for (int i = 0; i < n - 1; i++) {
            swapped = false;
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    // Swap arr[j+1] and arr[j]
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    swapped = true;
                }
            }
            // 如果在某次遍历中没有发生任何交换,说明数组已经排序完成
            if (!swapped)
                break;
        }
    }
}

在这段代码中,我们使用了两层循环。外层循环控制排序的轮数,内层循环负责比较和交换相邻的元素。如果在某次遍历中没有发生任何交换,说明数组已经排序完成,此时可以提前终止排序,以节省不必要的比较。这是冒泡排序的一个优化点。

选择排序(Selection Sort)是一种简单直观的比较排序算法。它的工作原理是遍历数组,每次从未排序的部分找出最小(或最大)的元素,存放到排序序列的起始位置,直到所有元素均排序完毕。

选择排序步骤详解

假设我们有以下数组:

int[] arr = {64, 34, 25, 12, 22, 11, 90};

第一轮选择排序

步骤描述
初始遍历整个数组寻找最小值
比较64 vs 34 vs 25 vs 12 vs 22 vs 11 vs 90
结果发现 11 是最小值
交换11 与第一个元素 64 交换位置

第二轮选择排序

步骤描述
初始从第二个元素开始遍历寻找最小值
比较64 vs 34 vs 25 vs 12 vs 22 vs 90
结果发现 12 是最小值
交换12 与第二个元素 64 交换位置

第三轮选择排序

步骤描述
初始从第三个元素开始遍历寻找最小值
比较34 vs 25 vs 22 vs 90
结果发现 22 是最小值
交换22 与第三个元素 34 交换位置

依此类推,直到整个数组排序完成

选择排序的Java代码实现

下面是使用Java实现选择排序的代码:

public class SelectionSortExample {
    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        
        selectionSort(arr);
        
        System.out.println("Sorted array : ");
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }

    static void selectionSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            // Find the minimum element in unsorted array
            int minIndex = i;
            for (int j = i + 1; j < n; j++) {
                if (arr[minIndex] > arr[j]) {
                    minIndex = j;
                }
            }
            // Swap the found minimum element with the first element
            int temp = arr[minIndex];
            arr[minIndex] = arr[i];
            arr[i] = temp;
        }
    }
}

在这段代码中,我们使用了两层循环。外层循环迭代整个数组,而内层循环则用于找到剩余未排序部分的最小元素。一旦找到了最小元素,我们就将其与未排序部分的第一个元素交换。这样,每一次外层循环的迭代都会将未排序部分的最小元素放置到正确的位置上。

性能分析

选择排序的时间复杂度为O(n^2),无论在最好、最坏还是平均情况下都是如此。这是因为对于n个元素的数组,需要进行n次查找最小值的操作,每次查找都需要遍历剩下的元素,所以总的操作次数大约是n*(n-1)/2。尽管其实现简单,但在大数据量的情况下,选择排序的效率较低。

插入排序(Insertion Sort)是一种简单直观的排序算法,其工作原理类似于人们手动排序扑克牌的方式。在插入排序中,数组被分为已排序和未排序两部分。初始时,已排序部分只包含第一个元素,未排序部分包含剩余的所有元素。算法通过从未排序部分取出一个元素,并在已排序部分找到正确的位置将其插入,逐步扩大已排序部分的范围,直至整个数组排序完成。

插入排序步骤详解

假设我们有以下数组:

int[] arr = {64, 34, 25, 12, 22, 11, 90};

第一轮插入排序

步骤描述
初始已排序部分:64,未排序部分:34, 25, 12, 22, 11, 90
插入34 插入到已排序部分的适当位置
结果已排序部分变为:34, 64

第二轮插入排序

步骤描述
初始已排序部分:34, 64,未排序部分:25, 12, 22, 11, 90
插入25 插入到已排序部分的适当位置
结果已排序部分变为:25, 34, 64

第三轮插入排序

步骤描述
初始已排序部分:25, 34, 64,未排序部分:12, 22, 11, 90
插入12 插入到已排序部分的适当位置
结果已排序部分变为:12, 25, 34, 64

依此类推,直到整个数组排序完成

插入排序的Java代码实现

下面是使用Java实现插入排序的代码:

public class InsertionSortExample {
    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        
        insertionSort(arr);
        
        System.out.println("Sorted array : ");
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }

    static void insertionSort(int[] arr) {
        int n = arr.length;
        for (int i = 1; i < n; ++i) {
            int key = arr[i];
            int j = i - 1;
            
            /* Move elements of arr[0..i-1], that are greater than key,
               to one position ahead of their current position */
            while (j >= 0 && arr[j] > key) {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = key;
        }
    }
}

在这段代码中,我们使用了一个循环来迭代数组中的每个元素,除了第一个元素外(因为单个元素自动认为是已排序的)。对于每个元素,我们将其保存在一个变量key中,然后在已排序的部分中找到它的正确位置,并将所有比key大的元素向右移动一位,为key腾出空间,最后将key插入到正确的位置。

性能分析

插入排序的时间复杂度在最好情况(数组已经是排序的)下为O(n),在最坏情况(数组是逆序的)和平均情况下为O(n^2)。尽管对于大规模数据而言效率较低,但对于小规模数据或部分已排序的数据,插入排序的性能仍然相当不错。

标签:arr,12,22,19,34,64,排序,数据结构
From: https://blog.csdn.net/hummhumm/article/details/140327417

相关文章

  • 【数据结构】12.排序
    一、排序的概念及其运用1.1排序的概念排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j......
  • 【数据结构】—— 双向链表
    文章目录1、双向链表的概念2、双向链表的接口实现2.1结构2.2初始化申请节点2.3插入数据尾插头插指定位置之后插入数据2.4删除数据尾删头删指定位置删除2.5查找2.6打印2.7销毁3、链表和顺序表的区别4、问题与思考1、双向链表的概念双向链表(DoublyLinkedList)是......
  • 洛谷P1347 排序
    传送门Abstract这篇题解主要介绍了拓扑排序的唯一性问题和存在性问题。Idea要想解决这题需要考虑到一下两点:拓扑排序的核心思路在于将所有入度为0的点一次加入序列,如果在某一个时刻图中存在多个入度为0的点,那么我们将无法判断它们的先后顺序,此时,拓扑序列就不唯一了。假设......
  • 浙大数据结构慕课课后习题(02-线性结构2 一元多项式的乘法与加法运算)
    题目要求设计函数分别求两个一元多项式的乘积与和。输入格式:输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。输出格式:输出分2行,分别以指数递降方式输出乘积多项式以及和多项......
  • 研0 冲刺算法竞赛 day14 P1957 口算练习题
    思路:分别考虑以运算符或数字开头,为运算符,直接读入后面两个数字;为数字,在读入一个数字即可代码:#include<iostream>#include<cstring>#include<cstdio>usingnamespacestd;intmain(){ intN; cin>>N; charc[10],str[55],f; while(N--) { cin>>c; int......
  • 题解:P10732 [NOISG2019 Prelim] Palindromic FizzBuzz
    题解:P10732[NOISG2019Prelim]PalindromicFizzBuzz题意题意十分明了,给予你一个区间,判断区间中每一个数是否是回文数。思路思路比较简单,首先将每一个数按每一位放入一个数组中,顺序无论由前到后和由后到前都可以。接下来将数组折半循环,判断前后是否一样。一样的话是回文数,......
  • Python教程:sort和sorted实现排序之对比
    总的来说,sort是应用在列表上的方法,修改原始列表。内建函数sorted可对所有可迭代的对象进行排序操作,返回新的对象。list.sort()方法效率会比sorted(iter)稍微高些。一、sort函数sort()函数用于对原列表进行排序,如果指定参数,则依据指定的函数进行排序。列表才可以进行修......
  • 数据结构--第八章排序
    注:内容参考王道2024考研复习指导以及《数据结构》一、排序的基本概念排序(sort),就是重新排列表中的元素,使表中的元素满足按关键字有序的过程。排序算法的评价指标时间复杂度空间复杂度稳定性算法的稳定性,若待排序表中有两个元素Ri​和Rj​,其对应的关键字相同即keyi​=keyj......
  • 观《深入理解C#有感》--- 排序搜索
    关于在无序列表中,找到所需数据的五种写法classProgram{classProduct{publicstringname;publicintprice;publicoverridestringToString(){returnname;......
  • 太原理工数据结构实验报告(计科)
    实验一线性表一、实验目的和要求本次实验的主要目的是为了使学生熟练掌握线性表的基本操作在顺序存储结构和链式存储结构上的实现,提高分析和解决问题的能力。要求仔细阅读并理解下列例题,上机通过,并观察其结果,然后独立完成后面的实验题。(1学时)二、实验内容和原理1.建立如......