排序之选择排序:简单选择+堆排序

一、简单选择排序

1、思想:每遍历一次都记住了当前最小(大)元素的位置,最后仅需一次交换操作即可将其放到合适的位置。与冒泡排序相比,移动数据次数少,节省时间 ,性能优于冒泡排序。

2、时间复杂度:

最好:O(N2),正序

最坏:O(N2),逆序

平均:O(N2

3、辅助空间:O(1)

4、稳定性:不稳定,交换过程中可能打乱顺序

5、适用场合:n小的情况

public static void selectSort(int[] a) {
        int i,j,min,t;
        for(j = 0;j < a.length; j++) {
            min = a[j];//将待排序的第一个元素设置为最小值
            t = j; //设置要交换的位置!
            for(i = j+1;i < a.length; i++) {
                if (min > a[i]) {
                    min = a[i];
                    t = i;
                }
            }
            if (t != j) swap(a,j,t);//若不为当前位置则交换
        }
    }

二、堆排序

1、思想:堆排序是一种选择排序,整体主要由构建初始堆+交换堆顶元素和末尾元素并重建堆两部分组成。选择排序主要是比较的次数多,所以从减少比较次数入手来改进选择排序,堆排序利用了完全二叉树的性质,当前结点i的子节点为(2i,2i+1),例如大根堆,则当前结点一定大于或等于其任何子节点。

2、时间复杂度:初始建堆O(n),交换堆顶和末尾元素并重建(logn)

最好:O(nlogn)

最坏:O(nlogn)

平均:O(nlogn)

3、辅助空间:O(1)

4、稳定性:不稳定

 1 import java.util.Scanner;
 2
 3 public class HeapSort {
 4     //堆下标从1开始
 5     //从当前给定的点s开始往下调整
 6     //大顶堆,得到递增数组
 7     public static void adjustHeap(int[] a,int s,int len ) {
 8         int rc,i;
 9         rc = a[s];
10         for(i = s*2 ; i<= len ; i = i*2 ) {
11             if(i < len && a[i]<a[i+1]) i++;//取s的两个子节点中较大一个
12             if(rc > a[i]) break;//将rc和当前较大的子节点比较,若大,则不需再往下调整
13             a[s] = a[i];//取较大子节点移动到s
14             s = i;//s变为移动后的位置
15         }
16         a[s] = rc;//最后将rc放到相应位置
17     }
18
19     public static void heapSort(int[] a) {
20         int i,tmp;
21         for(i = (a.length-1)/2;i > 0; i--)
22             adjustHeap(a, i, a.length-1);
23         for(i = a.length-1; i > 1;i--) {
24             tmp = a[1];
25             a[1] = a[i];
26             a[i] = tmp;
27             adjustHeap(a, 1, i-1);
28             }
29     }
30
31     public static void insertHeap(int[] a,int x) {
32         int c = a.length - 1,temp,f;
33         a[c] = x;
34         temp = a[c];//当前要插入的结点
35         f = c/2;//父节点
36         while(f>=1 && c != 1) {
37             if(temp < a[f]) break;
38             a[c] = a[f];//若当前结点大于父节点,则将父节点往下调整
39             c = f;
40             f = c/2;
41         }
42         a[c] = temp;
43
44     }
45     public static void main(String[] args) {
46         int[] a = new int[10];
47         Scanner cin = new Scanner(System.in);
48         int i=0;
49         while(i<a.length) {
50             a[i] =cin.nextInt();
51             i++;
52         }
53         heapSort(a);
54         //insertHeap(a, 886);
55         for(i = 1;i < a.length;i++) {
56             System.out.print(a[i]+" ");
57         }
58     }
59 }

三、总结

1、堆排序是简单选择排序的一种改进,改进的着眼点是:如何减少关键码的比较次数

2、简单选择排序在一趟排序中仅选出最小关键码,没有把一趟比较结果保存下来,因而记录的比较次数较多。

堆排序在选出最小关键码的同时,也找出较小关键码减少了在后面的选择中的比较次数,从而提高了整个排序的效率。

3、堆排序对原始记录的排列状态并不敏感,相对于快速排序,这是堆排序最大的优点。

原文地址:https://www.cnblogs.com/lizijiangmm/p/8649030.html

时间: 2024-10-11 02:58:36

排序之选择排序:简单选择+堆排序的相关文章

七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)

 写在前面: 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素的任意序列,重新排列成一个按关键字有序的序列.因此排序掌握各种排序算法非常重要.对下面介绍的各个排序,我们假定所有排序的关键字都是整数.对传入函数的参数默认是已经检查好了的.只是简单的描述各个算法并给出了具体实现代码,并未做其他深究探讨. 基础知识: 由于待排序的记录数量不同,使得排序过程中设计的存储器不同,可将排序方法分为两大类:一类是内部排序,指的是待排序记录存放在计算机随机存储器中进行的排序过程.另一类是外部排序,

常见排序算法导读(3)[简单选择排序]

这一节将介绍简单选择排序(Simple Selection Sort). 在介绍简单排序算法之前,先给出排序的确切定义,并简单介绍一下排序算法的稳定性. 排序的确切定义 假设含有n个对象的序列为{R[0], R[1], ..., R[n-1]}, 其对应的关键字(key)序列为{K[0], K[1], ..., K[n-1]}. 所谓排序, 就是确定0, 1, ..., n-1的一种排列p[0], p[1], ..., p[n-1], 使各个关键字满足如下的非递减(升序)或非递增(降序)关系:

直接插入排序、二分插入排序、希尔排序、冒泡排序与简单选择排序

一.直接插入排序 稳定,时间复杂度:最好O(n).最差O(n^2).平均O(n^2),空间复杂度O(1) void InsertSort(int L[], int n) { int i, j,key; for (i = 1; i<n; i++) if(L[i] < L[i-1])//需要将L[i]插入到有序表L[0...i-1] { key = L[i]; for(j = i-1; j >= 0 && key < L[j]; j--)//后移 L[j+1] = L[

(二)选择排序之二:简单选择排序

选择排序分为:简答选择排序.树形选择排序.堆排序,今天来学一下简答选择排序. 具体代码如下: package com.cust.heap; /** * * 描述:简单选择排序 * @author cookie */ public class 简单选择排序 { public static void main(String[] args) { int[] array = new int[]{2,5,6,9,4,1,7}; print(array);//打印 for(int i = 0; i < ar

排序算法篇--之简单选择排序

简单选择排序,就是执行n-i次比较,然后从n-i+1个数据中选择最小的值,如果最小值不是第i(1=<i<=n)个,则和第i个交换. 1 <?php 2 $arr = array(9,5,4,8,7,6,0,3,2,1); 3 4 /** 5 * 返回经过简单选择排序算法排序后的数组 6 * @param $array array 要进行排序的数组 7 * return array 进过排序后的数组 8 */ 9 function SelectSort($array){ 10 11 for

Java排序算法(二):简单选择排序

[基本思想] 在要排序的一组数中.选出最小的一个数与第一个位置的数交换:然后在剩下的数中再找出最小的与第二个位置的数交换,如此循环至倒数第二个数和最后一个数比較为止. 算法关键:找到最小的那个数.并用变量记住它的下标. [java实现] public class SimpleSelectionSort { public static void main(String[] args) { int[] arr = { 9, 1, 5, 8, 3, 7, 4, 6, 2 }; System.out.p

排序算法学习之简单排序(冒泡排序,简单选择排序,直接插入排序)

一.冒泡排序 冒泡排序算是最基础的一种算法了,复杂度为O(N^2),其基本思想是:从最低端数据开始,两两相邻比较,如果反序则交换.代码如下: /*最基本的冒泡排序*/ void BubbleSort1 (int n, int *array) /*little > big*/ { int i, j; for (i=0; i<n-1; i++) { for (j=n-1; j>i; j--) { if (array[j] < array[j-1]) { int temp = array

Java数据结构系列之——简单排序:冒泡、简单选择、直接插入

package SimpleSort; public class SimpleSort { /** * 冒泡排序:每次循环过程中,小的排在后面的数会像水中的 * 气泡一样慢慢往上冒,所以命名为冒泡排序了,我猜是这样子的..... */ public void BubbleSort(int[] array){ for(int i=0;i<array.length;i++){ for(int j=array.length-1;j>i;j--){//注意此处j是从后往前循环 if(array[j-1

算法导论 第6章 堆排序(简单选择排序、堆排序)

堆数据结构实际上是一种数组对象,是以数组的形式存储的,可是它能够被视为一颗全然二叉树,因此又叫二叉堆.堆分为下面两种类型: 大顶堆:父结点的值不小于其子结点的值,堆顶元素最大 小顶堆:父结点的值不大于其子结点的值,堆顶元素最小 堆排序的时间复杂度跟合并排序一样,都是O(nlgn),可是合并排序不是原地排序(原地排序:在排序过程中,仅仅有常数个元素是保存在数组以外的空间),合并排序的全部元素都被复制到另外的数组空间中去,而堆排序是一个原地排序算法. 1.在堆排序中,我们通常使用大顶堆来实现,因为堆

【算法拾遗(java描写叙述)】--- 选择排序(直接选择排序、堆排序)

选择排序的基本思想 每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,知道所有记录排序完毕.主要有两种选择排序方法:直接选择排序(或称简单选择排序)和堆排序. 直接选择排序 基本思想 第i趟排序開始时,当前有序区和无序区分别为R[1 -- i-1]和R[i -- n](1 <= i <= n-1),该趟排序则是从当前无序区中选出关键字最小的记录R[k],将它与无序区的第一个记录R[i]交换,使R[1 -- i]和R[i+1 -- n]分别变为新的有序区和新的无序区.