首页 > 其他分享 >冒泡排序

冒泡排序

时间:2024-09-14 13:51:27浏览次数:3  
标签:tmp end int 冒泡排序 gap ++ 排序

1. 插入排序

1.1 基本思想

直接插入排序是一种简单的插入排序法。其基本思想是把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。


1.2 直接插入排序

当插入第i(i>=1)个元素时,前面的array[0], array[1],…, array[i - 1]已经排好序,此时用array[i]的排序码与array[i - 1], array[i - 2],… 的排序码顺序进行比较,找到插入位置,即将array[i]插入,原来位置上的元素顺序后移。

void InsertSort(int* a, int n) {

   for (int i = 0; i < n - 1; i++) {

       int end = i;

       int tmp = a[end + 1];

       while (end >= 0) {

           if (a[end] > tmp) {

               a[end + 1] = a[end];

               end--;

           } else {

               break;

           }

       }

       a[end + 1] = tmp;

   }

}


特性总结:

元素集合越接近有序,直接插入排序算法的时间效率越高。

时间复杂度:O(N^2)。

空间复杂度:O(1)。

1.3 希尔排序

希尔排序法又称缩小增量法。先选定一个整数(通常是gap = n/3 + 1),把待排序文件所有记录分成各组,所有距离相等的记录分在同一组内,并对每一组内的记录进行排序,然后gap = gap / 3 + 1得到下一个整数,再将数组分成各组,进行插入排序,当gap = 1时,就相当于直接插入排序。

void ShellSort(int* a, int n) {

   int gap = n;

   while (gap > 1) {

       gap = gap / 3 + 1;

       for (int i = 0; i < n - gap; i++) {

           int end = i;

           int tmp = a[end + gap];

           while (end >= 0) {

               if (a[end] > tmp) {

                   a[end + gap] = a[end];

                   end -= gap;

               } else {

                   break;

               }

           }

           a[end + gap] = tmp;

       }

   }

}


特性总结:

希尔排序是对直接插入排序的优化。

当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序,这样整体而言,可以达到优化的效果。

2. 选择排序

2.1 基本思想

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。


2.2 直接选择排序

在元素集合array[i]--array[n - 1]中选择关键码最大(小)的数据元素。

若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换。

在剩余的array[i]--array[n - 2](array[i + 1]--array[n - 1])集合中,重复上述步骤,直到集合剩余 1 个元素。

void SelectSort(int* a, int n) {

   int begin = 0, end = n - 1;

   while (begin < end) {

       int mini = begin, maxi = begin;

       for (int i = begin; i <= end; i++) {

           if (a[i] > a[maxi]) {

               maxi = i;

           }

           if (a[i] < a[mini]) {

               mini = i;

           }

       }

       if (begin == maxi) {

           maxi = mini;

       }

       swap(&a[mini], &a[begin]);

       swap(&a[maxi], &a[end]);

       ++begin;

       --end;

   }

}


特性总结:

直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用。

时间复杂度:O(N^2)。

空间复杂度:O(1)。

2.3 堆排序

堆排序是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。通过堆来进行选择数据。排升序要建大堆,排降序建小堆。


3. 交换排序

3.1 基本思想

根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置。交换排序的特点是将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。


3.2 冒泡排序

代码实现:

void BubbleSort(int* a, int n) {

   int exchange = 0;

   for (int i = 0; i < n; i++) {

       for (int j = 0; j < n - i - 1; j++) {

           if (a[j] > a[j + 1]) {

               exchange = 1;

               swap(&a[j], &a[j + 1]);

           }

       }

       if (exchange == 0) {

           break;

       }

   }

}


特性总结:

时间复杂度:O(N^2)。

空间复杂度:O(1)。

3.3 快速排序

基本思想:快速排序是 Hoare 于 1962 年提出的一种二叉树结构的交换排序方法。任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后对左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

//快速排序

void QuickSort(int* a, int left, int right) {

   if (left >= right) {

       return;

   }

   int meet = _QuickSort(a, left, right);

   QuickSort(a, left, meet - 1);

   QuickSort(a, meet + 1, right);

}


_QuickSort方法有多种实现方式,如 hoare 版本、挖坑法、lomuto 前后指针等。

特性总结:

时间复杂度:O(nlogn)。

空间复杂度:O(logn)。

3.4 非递归版本

非递归版本的快速排序需要借助数据结构栈。


4. 归并排序

4.1 算法思想

归并排序是建立在归并操作上的一种有效的排序算法,采用分治法的典型应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。


4.2 代码实现

void _MergeSort(int* a, int left, int right, int* tmp) {

   if (left >= right) {

       return;

   }

   int mid = (right + left) / 2;

   _MergeSort(a, left, mid, tmp);

   _MergeSort(a, mid + 1, right, tmp);

   int begin1 = left, end1 = mid;

   int begin2 = mid + 1, end2 = right;

   int index = begin1;

   while (begin1 <= end1 && begin2 <= end2) {

       if (a[begin1] < a[begin2]) {

           tmp[index++] = a[begin1++];

       } else {

           tmp[index++] = a[begin2++];

       }

   }

   while (begin1 <= end1) {

       tmp[index++] = a[begin1++];

   }

   while (begin2 <= end2) {

       tmp[index++] = a[begin2++];

   }

   for (int i = left; i <= right; i++) {

       a[i] = tmp[i];

   }

}


void MergeSort(int* a, int n) {

   int* tmp = new int[n];

   _MergeSort(a, 0, n - 1, tmp);

   delete[] tmp;

}


特性总结:

时间复杂度:O(nlogn)。

空间复杂度:O(n)。

5. 测试代码:排序性能对比

通过生成随机数组,分别使用不同的排序算法进行排序,并记录运行时间,以比较各种排序算法的性能。


标签:tmp,end,int,冒泡排序,gap,++,排序
From: https://blog.51cto.com/u_16271212/12016321

相关文章

  • 冒泡排序理解
    1.1思路冒泡排序是一种简单的排序方法。基本思路是通过两两比较相邻的元素并交换它们的位置,从而使整个序列按照顺序排列。该算法一趟排序后,最大值总是会移到数组的最后面,那么接下来就不用再考虑这个最大值。一直重复这样的操作,最终就可以得到排序完成的数组。这种算法是稳......
  • [c++][笔记]浅谈几种排序方式---冒泡排序,选择排序,桶排序
     一、algorithm里的sort函数 #include<cstdio>//数据小的可以用iostream#include<algorithm>//不能忘记算法库,否则会编译失败。usingnamespacestd;intmain(){intn;scanf("%d",&n);inta[n+5]={};for(inti=1;i<=n;i++){......
  • C语言 跟着Mr.狠人一起实现冒泡排序
    冒泡排序(bubblesort)基本原理很简单,如图所示: 这边方便大家快速观察顺序:这边我们可以观察出冒泡排序是两两相比,每一趟都能确定最后一位成为本趟的最大值。 10个数字9趟就完成了。那我们试着写写代码吧voidbubble_sort(intarr[],intsz){ inti=0;//趟数 for......
  • 「NOI2022 D2T2 冒泡排序」题解
    题意uoj768构造长为\(n\)的序列\(a\),满足\(m\)条限制:\(\min_{j=L_i}^{R_i}\{a_j\}=V_i\),要求逆序对数最少题解21pts暴力先进行一些观察:逆序对只关心相对大小,所以\(\foralla_j\)必然\(\in\{V_i\}\),可以完全离散化经典结论:若\(i<j,a_i>a_j\)且交换后合法,则交换......
  • 冒泡排序算法
    冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复进行的,直到没有再需要交换的元素为止,这意味着数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(或说是......
  • python冒泡排序
    1、什么是冒泡排序  BubbleSort是最简单和通用的排序方法,基本思想是:在待排序的一组数据中,将相邻的两个数进行比较,若前面的数比后面的数大,就交换两个数,否则不交换;如此下去,直至完成最终排序。由此可得,在排序的过程中,大的数据往下沉,小的数据往上浮,就像气泡一样。于是将这种算......
  • 函数qsort的使用与冒泡排序模拟实现qsort
    目录一.qsort函数的使用示例二.使用冒泡排序模拟实现qsort函数二.1.冒泡排序 二.2.模拟实现qsort函数一.qsort函数的使用1.1.qsort函数是用来排序任意数据类型的数组,对其中的元素进行一定规则的排列2.qsort不返回任何值3.qsort的第一个参数是一个void*指针,指向......
  • C语言新手小白详细教程:冒泡排序
    ......
  • 交换排序(冒泡排序和快速排序)
    一、基本思想所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置。交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。二、冒泡排序1.核心思想两两相邻的元素进行比较2.动图展示3.代码展示voidSwap(int*......
  • Java实现冒泡排序和插入排序算法
    冒泡排序算法步骤1、比较相邻的元素,如果第一个比第二个大,就交换它们两个;2、对每一对相邻元素作同样的比价,从开始第一对到结尾的最后一对,这样在最后的元素就是最大的数;3、针对所有的元素重复以上的步骤,除了数组最后已经排好序的数组;4、重复步骤1~3,直到排序完成。代码实现pac......