常见的排序算法——交换排序

一、冒泡排序

#include <iostream>
using namespace std;

void print_array(int a[], int n)
{
    for(int i = 0; i < n; i++)
        cout << a[i]  << " " ;
    cout << endl;
}

void bubble_sort(int a[], int n)
{
    for(int i = 0; i < n; i++)
    {
        for(int j = n - 1; j > i; j--)        //冒泡排序,从后面到前面两两比较,将小数慢慢放到首位置
        {
            if(a[j] < a[j-1])
            {
                int tmp = a[j];
                a[j] = a[j-1];
                a[j-1] = tmp;
            }
        print_array(a, 9);
        }
    }
}

int main()
{
    int a[] = {7,3,5,8,9,1,2,4,6};
    cout << "before sort:";
    print_array(a, 9);

    bubble_sort(a, 9);
    cout << "after sort :";
    print_array(a, 9);

    return 0;
}

说明:

  冒泡排序是依次比较相邻两个数,将小数放在前面,大数放在后面。

  第一趟:比较第1第2两个数,小数放在前面,大数放在后面;然后比较第2第3个数,小数放在前面,大数放在后面......到最后一个数。第一趟结束,最大的数放在了最后。

  第二趟:比较第1第2两个数,小数放在前面,大数放在后面;然后比较第2第3个数,小数放在前面,大数放在后面......到倒数第二个数。第二趟结束,新的最大数放在了倒数第二。

  ......

  多次循环,完成排序。因为排序过程是小数往前放,大数往后放,相当于气泡上升,所以称为冒泡排序。

  冒泡排序是稳定的,时间复杂度O(n^2)。

二、快速排序

(参考资料:

https://www.jianshu.com/p/7631d95fdb0b Python的快速排序算法,类似于左右指针法

https://www.jianshu.com/p/1246ab5f8799 这篇比上面一篇的思想更好,不用考虑最后基准值的排列情况

https://blog.csdn.net/xy913741894/article/details/59110569 概括了几种不同的快速排序方法等等其他内容,左右指针法,前后指针法,挖坑法

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1.挖坑法:

数据:

刚开始,将最右边设置为“坑”。同时设置left指向第一个元素2,right指向最后一个元素5。

  1. 如果v[left] <= pivot,那么left指针右移直到v[left] > pivot停下,那么此时需要填坑,将v[right]也就是pivot初始坑填满,v[right] = v[left],并且此时设置v[left]为坑;
  2. 现在我们移动right,如果v[right] >=pivot,right指针左移直到v[right] < pivot停下,同理此时填坑,v[left] = v[right],并且设置v[right]为坑;
  3. 重复1,2过程直到left,right相遇,此时将v[right] = pivot填满,最后返回right。

图示:

void quick_sort_fill(int s[], int l, int r)
{
    int left = l, right = r;
    int pivot = s[right];

         //递归的时候这个判断一定要有
    if(left < right)
    {
        while(left < right)
        {
            while(s[left] < pivot && left < right)
            {
                left++;
            }
            s[right] = s[left];
        //cout << "before    :";
        //print_array(s, 10);
            while(s[right] >= pivot && left < right)
            {
                right--;
            }
            s[left] = s[right];
        //cout << "sort OVER :";
        //print_array(s, 10);

        }
        s[left] = pivot;    

        quick_sort(s, l, left - 1);
        quick_sort(s, left, r);
    }
}

2.左右指针法:

数据:

刚开始设置基准值pivot为最右边的元素也就是5。设置left指向第一个元素2,right指向最后一个元素5。

  1. 如果v[left] < pivot,将left指针右移,直到v[left] > pivot
  2. 如果v[right] > pivot,将left指针左移,直到v[left] < pivot
  3. 此时交换v[left]和v[right]
  4. 继续重复1,2,3的过程知道left和right相遇,此时left == right,交换v[left]和pivot的值,返回left或者right

注:这种方法是找 left > pivot, right < pivot,然后交换left和right;

另一种方法:找 left > pivot,交换left 和pivot;找 right < pivot,交换right 和 pivot。

//上述的方法:交换left和rightvoid quick_sort_leftright(int s[], int l, int r)
{
    int left = l, right = r;
    int pivot = s[right];

    if(left < right)
    {
        while(left < right)
        {
            while(left < right && s[left] < pivot)
            {
                left++;
            }
            while(left < right && s[right] >= pivot)
            {
                right--;
            }
            int middle = s[left];
            s[left] = s[right];
            s[right] = middle;
        }
        int middle2 = s[left];
        s[left] = pivot;
        s[r] = middle2;
        cout << "before     :";
        print_array(s, 10);

        quick_sort_leftright(s, l, left-1);
        quick_sort_leftright(s, left+1, r);
    }
}

3.前后指针法:

数据:

刚开始设置cur指向第一个元素2,prev指向空。

  1. 如果v[cur] < pivot,那么让prev指针右移  =>  如果prev==cur,则 => 3;如果prev不等于cur,那么交换v[cur]和v[prev]的值 => 3
  2. 如果v[cur] >= pivot,那么 => 3
  3. cur指针右移
  4. 重复1,2的过程直到cur指针指到最右边
  5. 让prev再右移一次,最后交换pivot(也就是v[cur])和v[prev]的值,返回prev

void quick_sort_frontback(int s[], int l, int r)
{
    int prev = l - 1, cur = l;
    int pivot = s[r];

    if(cur < r)
    {
        while(cur < r)
        {
            if(s[cur] < pivot)
            {
                ++prev;
                if(prev != cur)
                {
                    int middle = s[cur];
                    s[cur] = s[prev];
                    s[prev] = middle;
                }
            }
            cur++;
        }
        int middle2 = s[cur];
        s[cur] = s[++prev];
        s[prev] = middle2;

        quick_sort_frontback(s, l, prev-1);
        quick_sort_frontback(s, prev+1, r);
    }
}

说明:

  基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都小于另外一部分的所有数据,然后再递归进行排序。

  最坏时间O(n^2),平均运行时间O(nlogn)。快速排序被认为是当前最优秀的内部排序方法。

原文地址:https://www.cnblogs.com/Brickert/p/10758493.html

时间: 2024-08-29 12:17:52

常见的排序算法——交换排序的相关文章

【转帖】常见的排序算法

常见的排序算法 总结一下常见的排序算法. 排序分内排序和外排序.内排序:指在排序期间数据对象全部存放在内存的排序.外排序:指在排序期间全部对象个数太多,不能同时存放在内存,必须根据排序过程的要求,不断在内.外存之间移动的排序.内排序的方法有许多种,按所用策略不同,可归纳为五类:插入排序.选择排序.交换排序.归并排序.分配排序和计数排序.插入排序主要包括直接插入排序,折半插入排序和希尔排序两种;选择排序主要包括直接选择排序和堆排序;交换排序主要包括冒泡排序和快速排序;归并排序主要包括二路归并(常用

java几种常见的排序算法总结

[java] view plain copy /*************几种常见的排序算法总结***************************/ package paixu; public class PaiXu { final int MAX=20; int num[]=new int[MAX]; { System.out.print("生成的随机数组是:"); for(int i=0;i<20;i++){ num[i]=(int)(Math.random()*100)

数据结构之常见的排序算法c语言实现

常见的简单排序算法有冒泡排序.选择排序.插入排序.快排.堆排序.归并排序.希尔排序等,这些排序的理论在网上有很多,这就只给出常见的排序算法源码,上学时候写的,不足之处欢迎大家指正. 下面几种排序的主函数入口为:     int main(int argc, char* argv[])         {      int i, len;      int a[] = {8,5,6,4,9,10,3,15,2,17};           len = (sizeof(a) / sizeof(a[0

常见比较排序算法的比较

几种常见的排序算法之比较 排序的基本概念以及其算法的种类,介绍几种常见的排序算法的算法:冒泡排序.选择排序.插入排序.归并排序.快速排序.希尔排序的算法和分析它们各自的复杂度,然后以表格的形式,清晰直观的表现出它们的复杂度的不同.在研究学习了之前几种排序算法的基础上,讨论发现一种新的排序算法,并通过了进一步的探索,找到了新的排序算法较之前几种算法的优势与不足. 排序算法,是计算机编程中的一个常见问题.在日常的数据处理中,面对纷繁的数据,我们也许有成百上千种要求,因此只有当数据经过恰当的排序后,才

常见的排序算法

描述: 排序算法可谓数据结构模块中的重中之重,常见的哈希表,二叉树,搜索树/平衡树,位图等数据结构只是处理实际问题的抽象方法,实际在处理接受或生成的数据集时,排序算法显得尤其重要,排序算法家族很庞大,其中包括了冒泡排序,选择排序,插入排序,堆排序,快速排序,归并排序,基数排序,计数排序,希尔排序,箱排序,树型排序等众多算法,每种排序都有各自的特性,没有好坏之分,只有在特定的场景使用合适的排序算法才是上策,单纯的来比显得太过绝对,没有可比性.因为实际需求及各方面条件的限制使得排序算法的可选范围往往

Python全栈开发之5、几种常见的排序算法以及collections模块提供的数据结构

在面试中,经常会遇到一些考排序算法的题,在这里,我就简单了列举了几种最常见的排序算法供大家学习,说不定以后哪天面试正好用上,文章后半段则介绍一下collections模块,因为这个模块相对于python提供的基本数据结构(list,tuple,dict)不被人们所熟悉,但是如果你对他们了解的话,用起来也是非常方便高效的. 排序算法 一.冒泡排序(BubbleSort) 步骤: 比较相邻的元素,如果第一个比第二个大,就交换他们两个. 循环一遍后,最大的数就“浮”到了列表最后的位置. 将剩下的数再次

用Java来写常见的排序算法

随着校招的临近 算法是校招中很重要的一个部分 总结了常见几种排序算法,各种算法的时间复杂度和空间复杂度大家也需要多了解下 package com.huwei.sort; /** * 各种排序算法 * * @author huwei * */ public class Sort { public static void main(String[] args) { int[] a = { 60, 57, 89, 47, 57, 98, 45, 35, 73 }; Sort sort = new So

常见的排序算法--java版

个人总结的常见的排序算法 public class Sort { // 1.冒泡:稳定,最优O(n) 最差O(n^2) 平均O(n^2) private static void sort1(int[] arr) { for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length - 1; j++) { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = ar

几种常见的排序算法

1.插入类排序 在一个已经有序的序列中,插入一个新的记录.有直接插入排序.折半插入排序.希尔排序. 插入类排序 直接插入排序 1 void InsertSort(int R[], int n) 2 { 3 int i, j; 4 int temp; 5 for (i = 1; i < n; ++i) 6 { 7 temp = R[i]; 8 j = i - 1; 9 while (j >= 0 && temp < R[j]) 10 { 11 R[j+1] = R[j];