美文网首页
排序算法

排序算法

作者: allever | 来源:发表于2018-02-04 11:05 被阅读11次

冒泡排序

思想

比较相邻记录关键字,如果逆序,则进行交换,从而使记录小的像气泡一样逐渐往上“漂浮”(左移),或者说使记录大的像石头那样"下沉"(右移)

算法实现

java实现

原序列

int a[10] = {4,3,2,6,1,9,5,8,7,0};
    private static void popSort(int[] a){
        //最基本的冒泡排序写法
        /*int i;
        for (i=0;i<a.length;i++){
            for (int j=0;j<a.length-1;j++){
                if (a[j]>a[j+1]){
                    int temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }
        }*/

        //改进的冒泡排序写法
        int len = a.length-1;
        boolean flag = true;//用来标识是否发生交换操作
        while (len>0 && flag){
            flag = false;
            for (int j=0;j<len;j++){
                if (a[j] > a[j+1]){
                    //交换
                    int temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                    flag = true;
                }
            }
            show(a);
            len--;
        }
    }

运行结果

原序列: 1 6 5 9 3 8 2 7 0 4 
1 5 6 3 8 2 7 0 4 9 
1 5 3 6 2 7 0 4 8 9 
1 3 5 2 6 0 4 7 8 9 
1 3 2 5 0 4 6 7 8 9 
1 2 3 0 4 5 6 7 8 9 
1 2 0 3 4 5 6 7 8 9 
1 0 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
排序后: 0 1 2 3 4 5 6 7 8 9 

快速排序(冒泡排序升级版)

思想

在待排记录中选择一个记录(通常第一个)作为枢纽(关键记录)pivotkey. 经过一趟排序,以枢纽记录分为两个子表,左边子表记录比枢纽记录小,右边子表比枢纽记录大。然后对每个子表重复以上过程。知道每个子表只有一个记录时,排序结束。

每一趟操做

参考《大话数据结构》有详细解析

  1. 选择表中一个记录作为枢纽(通常是第一个记录) 保存好记录的值pivotkey
  2. (1)从high往左每个记录依次与pivotkey比较,比pivotkey大或相等的,high往左移(high--), 比pivotkey小的结束high移动,交换low和high的值
    (2) 从low往右每个记录依次与pivotkey比较,比pivotkey小或相等的,low往右移(low++), 比pivotkey小的结束low移动,交换low和high的值
  3. 返回pivotkey的值

算法实现

java实现

int a[10] = {4,3,2,6,1,9,5,8,7,0};
    private static void quickSort(int[] a,int low, int high){
        if (low<high){
            int povit = partition(a,low,high);
            quickSort(a,povit+1,high);  //对枢纽记录右边子表进行排序
            quickSort(a,low,povit-1);   //对枢纽记录左边的子表进行排序
        }
    }

    private static int partition(int[] a, int low, int high){
        System.out.println("low = " + low);
        int pivot = a[low]; //用子表的第一个记录作为枢纽记录
        while (low<high){   //
            while (low<high && a[high]>=pivot)  //右往左比较
                high--;                         //如果记录比枢纽记录大或者相等,high向左移动一个
            swap(a,low,high);                   //交换,比枢纽记录小的放左边
            show(a);
            while (low<high && a[low]<=pivot)   //左往右比较
                low++;                          //如果记录比枢纽记录小或者相等,high向右移动一个
            swap(a,low,high);                   //交换,比枢纽记录大的放右边
            show(a);
        }
        System.out.println("pivot = " + pivot);
        System.out.println();
        return low;
    }

调用

quickSort(a, 0, a.length-1);

运行结果

原序列: 1 6 5 9 3 8 2 7 0 4 
low = 0
0 6 5 9 3 8 2 7 1 4 
0 1 5 9 3 8 2 7 6 4 
0 1 5 9 3 8 2 7 6 4 
0 1 5 9 3 8 2 7 6 4 
pivot = 1

low = 2
0 1 4 9 3 8 2 7 6 5 
0 1 4 5 3 8 2 7 6 9 
0 1 4 2 3 8 5 7 6 9 
0 1 4 2 3 5 8 7 6 9 
0 1 4 2 3 5 8 7 6 9 
0 1 4 2 3 5 8 7 6 9 
pivot = 5

low = 6
0 1 4 2 3 5 6 7 8 9 
0 1 4 2 3 5 6 7 8 9 
pivot = 8

low = 6
0 1 4 2 3 5 6 7 8 9 
0 1 4 2 3 5 6 7 8 9 
pivot = 6

low = 2
0 1 3 2 4 5 6 7 8 9 
0 1 3 2 4 5 6 7 8 9 
pivot = 4

low = 2
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
pivot = 3

排序后: 0 1 2 3 4 5 6 7 8 9 

选择排序

思想

一个简单的选择排序算法是这样的:
首先, 找到数组中最小的一个元素
其次, 将它和数组的第一个元素交换位置,(如果第一个元素是最小的那么它就和自己交换).
再次, 在剩下元素中继续找到最小的元素,将它和数组中第二个元素交换位置.
如此反复操作,直到将整个数组排序
这种方法就是简单选择排序.

算法实现

C语言

原序列

int a[10] = {4,3,2,6,1,9,5,8,7,0};
/**简单选择排序
 * */
void SelectSort(int a[], int length){
    int i, j;
    int min;
    for (i = 0; i < length; ++i) {
        min = i;
        for (j = i+1; j < length; ++j) {
            if (a[j] < a[min]){
                min = j;
            }
            //printf("min = %d\n", min);//调试加上,
        }
        if (min != i){
            int temp = a[i];
            a[i] = a[min];
            a[min] = temp;
        }
        show(a,length);
    }
}

运行结果:

原序列: 4 3 2 6 1 9 5 8 7 0 
0 3 2 6 1 9 5 8 7 4 
0 1 2 6 3 9 5 8 7 4 
0 1 2 6 3 9 5 8 7 4 
0 1 2 3 6 9 5 8 7 4 
0 1 2 3 4 9 5 8 7 6 
0 1 2 3 4 5 9 8 7 6 
0 1 2 3 4 5 6 8 7 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
0 1 2 3 4 5 6 7 8 9 
排序后: 0 1 2 3 4 5 6 7 8 9

java实现

原序列:

int[] a = {1,6,5,9,3,8,2,7,0, 4};

第一次从0-9中选择最小的与第0个交换
第二次从1-9中选择最小的与第1个交换
重复以上步骤

    private static void selectSort(int[] a){
        System.out.println("选择排序算法:");
        int min, i, j;
        for (i=0; i<a.length; i++){
            min = i;
            for (j=i+1; j<a.length; j++){
                if (a[j] < a[min]){
                    min = j;
                }
            }
            //System.out.println("min = " + min);
            int temp = a[i];
            a[i] = a[min];
            a[min] = temp;
            System.out.print("第" + (i+1) + "次排序后:");
            show(a);
        }
    }

运行结果:

原序列: 1 6 5 9 3 8 2 7 0 4 
选择排序算法:
第1次排序后:0 6 5 9 3 8 2 7 1 4 
第2次排序后:0 1 5 9 3 8 2 7 6 4 
第3次排序后:0 1 2 9 3 8 5 7 6 4 
第4次排序后:0 1 2 3 9 8 5 7 6 4 
第5次排序后:0 1 2 3 4 8 5 7 6 9 
第6次排序后:0 1 2 3 4 5 8 7 6 9 
第7次排序后:0 1 2 3 4 5 6 7 8 9 
第8次排序后:0 1 2 3 4 5 6 7 8 9 
第9次排序后:0 1 2 3 4 5 6 7 8 9 
第10次排序后:0 1 2 3 4 5 6 7 8 9 
排序后: 0 1 2 3 4 5 6 7 8 9 

插入排序

思想

和整理扑克牌一样, 将每一张牌插入到其他已经有序的牌中的适当位置.在计算机实现中,为了要给插入的元素腾出空间, 我们需要将其余所有元素在插入之前都向右移动一位. 这种算法叫做插入排序.

实现

C语言实现

原序列

int a[10] = {4,3,2,6,1,9,5,8,7,0};
/**
 * 直接插入排序*/
void InsertSort(int a[], int length){
    int i,j;
    for (i = 0; i < length- 1; ++i) {
        for (j = i+1; j > 0 ; j--) {
            if (a[j] < a[j-1]){
                //交换
                int temp = a[j];
                a[j] = a[j-1];
                a[j-1] = temp;
            }
        }
        show(a,MAX_SIZE);
    }
}

运行结果:

原序列: 4 3 2 6 1 9 5 8 7 0 
3 4 2 6 1 9 5 8 7 0 
2 3 4 6 1 9 5 8 7 0 
2 3 4 6 1 9 5 8 7 0 
1 2 3 4 6 9 5 8 7 0 
1 2 3 4 6 9 5 8 7 0 
1 2 3 4 5 6 9 8 7 0 
1 2 3 4 5 6 8 9 7 0 
1 2 3 4 5 6 7 8 9 0 
0 1 2 3 4 5 6 7 8 9 
排序后: 0 1 2 3 4 5 6 7 8 9

Java实现

原序列:

int[] a = {1,6,5,9,3,8,2,7,0,4};

第一次把第2个数依次从右往左和1个数比较
第二次把第3个数依次从右往左和2个数比较
重复以上步骤

    private static void insertSort(int[] a){
        System.out.println("插入排序算法:");
        int i, j;
        for (i=0; i<a.length; i++){
            for (j=i; j>0; j--){
                if (a[j] < a[j-1]){
                    int temp = a[j];
                    a[j] = a[j-1];
                    a[j-1] = temp;
                }
            }
            System.out.print("第" + (i+1) + "次排序后:");
            show(a);
        }
    }

运行结果

原序列: 1 6 5 9 3 8 2 7 0 4 
插入排序算法:
第1次排序后:1 6 5 9 3 8 2 7 0 4 
第2次排序后:1 6 5 9 3 8 2 7 0 4 
第3次排序后:1 5 6 9 3 8 2 7 0 4 
第4次排序后:1 5 6 9 3 8 2 7 0 4 
第5次排序后:1 3 5 6 9 8 2 7 0 4 
第6次排序后:1 3 5 6 8 9 2 7 0 4 
第7次排序后:1 2 3 5 6 8 9 7 0 4 
第8次排序后:1 2 3 5 6 7 8 9 0 4 
第9次排序后:0 1 2 3 5 6 7 8 9 4 
第10次排序后:0 1 2 3 4 5 6 7 8 9 
排序后: 0 1 2 3 4 5 6 7 8 9 

希尔排序

思想

希尔排序的思想是使数组中任意间隔为h的元素都是有序的. 这样的数组成为h有序数组
简单地说, 一个h有序数组就是h个互相独立的有序数组编织在一起组成的一个数组.
在进行排序时, 如果h很大, 我们能将元素移动到很远的地方, 为实现更小的h有序数组创造方便, 用这种方式,对于任意以1结尾的h序列, 我们都能够将数组排序.
这就是希尔排序.

实现

C语言实现

/**
 * 希尔排序*/
 void ShellSort(int a[], int length){
    int h = 1;  //增量
    //while(h <= length/3) h = 3*h + 1;   //增量初始值 我写的
    while(h < length/3) h = 3*h + 1;   //增量初始值

    while (h >= 1){     //对每个增量都进行排序
        int i;
        for (i = h; i < length; ++i) {      //对同一增量的每个分组进行排序
            int j;
            //for (j = i; j < length; j= j-h) {   //对每个分组进行插入排序     我写的
            for (j = i; j >= h; j= j-h) {   //对每个分组进行插入排序
                if(a[j] < a[j-h]){
                    int temp = a[j];
                    a[j] = a[j-h];
                    a[j-h] = temp;
                }

            }
        }
        show(a,MAX_SIZE);
        h = h/3;
    }
}

运行结果

原序列: 4 3 2 6 1 9 5 8 7 0 
1 0 2 6 4 3 5 8 7 9 
0 1 2 3 4 5 6 7 8 9 
排序后: 0 1 2 3 4 5 6 7 8 9 

Java实现

    private static void shellSort(int[] a){
        int N = a.length;
        int h = 1;
        while (h < (N/3)) h = h * 3 + 1;
        while (h >= 1){
            for (int i=h; i<N; i++){
                for (int j=i; j>=h;j=j-h){
                    //进行插入排序
                    if (a[j] < a[j-h]){
                        int temp = a[j];
                        a[j]= a[j-h];
                        a[j-h] = temp;
                    }
                }
            }
            System.out.print("h = " + h + ": ");
            show(a);
            h = h/3;
        }
    }

运行结果:

原序列: 1 6 5 9 3 8 2 7 0 4 
h = 4: 0 4 2 7 1 6 5 9 3 8 
h = 1: 0 1 2 3 4 5 6 7 8 9 
排序后: 0 1 2 3 4 5 6 7 8 9 

相关文章

  • java实现快速排序、归并排序、希尔排序、基数排序算法...

    快速排序算法 归并排序算法 希尔排序算法 基数排序算法

  • web开发需要知道的几个算法

    算法分类 快速排序算法 深度优先算法 广度优先算法 堆排序算法 归并排序算法

  • 算法学习(1)-排序算法

    八大排序算法九大排序算法再总结[经典排序算法][集锦][直观学习排序算法] 视觉直观感受若干常用排序算法 快速排序...

  • 经典排序算法总结

    经典排序算法集锦 冒泡法 排序算法入门之冒泡排序 排序算法入门之冒泡排序优化

  • 前端算法学习-第一篇

    冒泡排序算法 冒泡排序算法是最慢的排序算法之一,也是最容易实现的排序算法。之所以叫冒泡排序是因为使用这种算法排序时...

  • 七大排序算法之冒泡排序

    七大排序算法之冒泡排序 @(算法笔记)[排序算法, 冒泡排序, C++实现] 冒泡排序介绍 冒泡排序是七大排序算法...

  • 算法-选择排序

    算 法:选择排序算法时间复杂度: 选择排序算法概述 选择排序伪代码 选择排序实现 选择排序算法概述 排序算法有许...

  • 浅谈排序算法

    排序算法有很多种,今天先谈谈一些简单的排序算法。包括桶排序、冒泡排序和快速排序算法。后期总结各种排序算法。 桶排序...

  • 线性排序

    桶排序、计数排序、基数排序 一、线性排序算法介绍 1.线性排序算法包括桶排序、计数排序、基数排序。2.线性排序算法...

  • 算法4:插入排序和选择排序算法的比较

    排序算法列表电梯: 选择排序算法:详见 《算法4》2.1 - 选择排序算法(Selection Sort), Py...

网友评论

      本文标题:排序算法

      本文链接:https://www.haomeiwen.com/subject/nohmzxtx.html