java数据结构排序算法之树形选择排序详解

本文实例讲述了java数据结构排序算法之树形选择排序。分享给大家供大家参考,具体如下:

这里我们就来说说选择类排序之一的排序:树形选择排序

在简单选择排序中,每次的比较都没有用到上次比较的结果,所以比较操作的时间复杂度是O(N^2),想要降低比较的次数,则需要把比较过程中的大小关系保存下来。树形选择排序是对简单选择排序的改进。

树形选择排序:又称锦标赛排序(Tournament Sort),是一种按照锦标赛的思想进行选择排序的方法。首先对n个记录的关键字进行两两比较,然后在n/2个较小者之间再进行两两比较,如此重复,直至选出最小的记录为止。

算法实现代码如下:

package exp_sort;
public class TreeSelectSort {
 public static int[] TreeSelectionSort(int[] mData) {
  int TreeLong = mData.length * 4;
  int MinValue = -10000;
  int[] tree = new int[TreeLong]; // 树的大小
  int baseSize;
  int i;
  int n = mData.length;
  int max;
  int maxIndex;
  int treeSize;
  baseSize = 1;
  while (baseSize < n) {
   baseSize *= 2;
  }
  treeSize = baseSize * 2 - 1;
  for (i = 0; i < n; i++) {
   tree[treeSize - i] = mData[i];
  }
  for (; i < baseSize; i++) {
   tree[treeSize - i] = MinValue;
  }
  // 构造一棵树
  for (i = treeSize; i > 1; i -= 2) {
   tree[i / 2] = (tree[i] > tree[i - 1] ? tree[i] : tree[i - 1]);
  }
  n -= 1;
  while (n != -1) {
   max = tree[1];
   mData[n--] = max;
   maxIndex = treeSize;
   while (tree[maxIndex] != max) {
    maxIndex--;
   }
   tree[maxIndex] = MinValue;
   while (maxIndex > 1) {
    if (maxIndex % 2 == 0) {
     tree[maxIndex / 2] = (tree[maxIndex] > tree[maxIndex + 1] ? tree[maxIndex]
       : tree[maxIndex + 1]);
    } else {
     tree[maxIndex / 2] = (tree[maxIndex] > tree[maxIndex - 1] ? tree[maxIndex]
       : tree[maxIndex - 1]);
    }
    maxIndex /= 2;
   }
  }
  return mData;
 }
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  int array[] = { 38, 62, 35, 77, 55, 14, 35, 98 };
  TreeSelectionSort(array);
  for (int i = 0; i < array.length; i++) {
   System.out.print(array[i] + " ");
  }
  System.out.println("\n");
 }
}

算法分析:

在树形选择排序中,除了最小的关键字,被选出的最小关键字都是走了一条由叶子结点到跟节点的比较过程,由于含有n个叶子结点的完全二叉树的深度log2n+1,因此在树形选择排序中,每选出一个较小关键字需要进行log2n次比较,所以其时间复杂度是O(nlog2n),移动记录次数不超过比较次数,故总的算法时间复杂度为O(nlog2n),与简单选择排序算法相比,降低了比较次数的数量级,增加了n-1个额外的存储空间存放中间比较结果。

补充:

这里再来介绍对树形选择排序的改进算法,即堆排序算法。

堆排序弥补了树形选择排序算法占用空间多的缺憾。采用堆排序时,只需要一个记录大小的辅助空间。

算法思想是:

把待排序记录的关键字存放在数组r[1...n]中,将r看成是一棵完全二叉树的顺序表示,每个结点表示一个记录,第一个记录r[1]作为二叉树的根,以下每个记录r[2...n]依次逐层从左到右顺序排列,任意结点r[i]的左孩子是r[2*i],右孩子是r[2*i+1];双亲是r[[i/2]]。

堆定义:各结点的关键字值满足下列条件:

r[i].key >= r[2i].key 且 r[i].key >= r[2i+1].key   (i=1,2,……[i/2])

满足上面条件的完全二叉树称为大根堆;相反,如果这颗完全二叉树中任意结点的关键字小于或者等于其左孩子和右孩子的关键字,对应的堆叫做小根堆。

堆排序的过程主要需要解决两个问题:第一个是,按照堆定义建初堆;第二个是,去掉最大元后重建堆,得到次大元。

堆排序即是利用堆的特性对记录序列进行排序,过程如下:

1、对给定序列建堆;
2、输出堆顶;(首元素与尾元素交换)
3、对剩余元素重建堆;(筛选首元素)
4、重复2,3,直至所有元素输出。

注意:“筛选”须从第[n/2]个结点开始,逐层向上倒退,直到根结点。

算法分析:

1. 对深度为 k 的堆,“筛选”所需进行的关键字比较的次数至多为2(k-1);
2. n 个关键字的堆深度为  [log2n]+1, 初建堆所需进行的关键字比较的次数至多为:n* [log2n];
3. 重建堆 n-1 次,所需进行的关键字比较的次数不超过:(n-1)*2 [log2n ];

因此,堆排序在最坏情况下,其时间复杂度为O(nlog2n),这是堆排序的最大优点。

更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

(0)

相关推荐

  • java排序算法之_选择排序(实例讲解)

    选择排序是一种非常简单的排序算法,从字面意思我们就可以知道,选择就是从未排序好的序列中选择出最小(最大)的元素,然后与第 i 趟排序的第 i-1(数组中下标从 0 开始) 个位置的元素进行交换,第 i 个元素之前的序列就是已经排序好的序列.整个排序过程只需要遍历 n-1 趟便可排好,最后一个元素自动为最大(最小)值. 举个小例子: arr[] = {3,1,2,6,5,4} 第 1 趟排序: index = 0, min = 1, 交换后 -->  1,3,2,6,5,4 第 2 趟排序: in

  • Java排序算法总结之选择排序

    本文实例讲述了Java排序算法总结之选择排序.分享给大家供大家参考.具体分析如下: 选择排序的基本操作就是每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完.算法不稳定,O(1)的额外的空间,比较的时间复杂度为O(n^2),交换的时间复杂度为O(n),并不是自适应的.在大多数情况下都不推荐使用.只有在希望减少交换次数的情况下可以用.   基本思想   n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果: ①初始状态:

  • Java对数组实现选择排序算法的实例详解

    一. 算法描述     选择排序:比如在一个长度为N的无序数组中,在第一趟遍历N个数据,找出其中最小的数值与第一个元素交换,第二趟遍历剩下的N-1个数据,找出其中最小的数值与第二个元素交换......第N-1趟遍历剩下的2个数据,找出其中最小的数值与第N-1个元素交换,至此选择排序完成. 以下面5个无序的数据为例: 56 12 80 91 20(文中仅细化了第一趟的选择过程) 第1趟:12 56 80 91 20 第2趟:12 20 80 91 56 第3趟:12 20 56 91 80 第4趟

  • Java实现选择排序算法的实例教程

    选择排序概念 选择排序也是一种交换排序算法,和冒泡排序有一定的相似度,因此个人认为选择排序可以视为冒泡排序的一种改进算法.它的思路是这样的: 设现在要给数组arr[]排序,它有n个元素. 1对第一个元素(Java中,下标为0)和第二个元素进行比较,如果前者大于后者,那么它一定不是最小的,但是我们并不像冒泡排序一样急着交换.我们可以设置一个临时变量a,存储这个目前最小的元素的下标.然后我们把这个目前最小的元素继续和第三个元素做比较,如果它仍不是最小的,那么,我们再修改a的值.如此直到和最后一个元素

  • JAVA简单选择排序算法原理及实现

    简单选择排序:(选出最小值,放在第一位,然后第一位向后推移,如此循环)第一位与后面每一个逐个比较,每次都使最小的置顶,第一位向后推进(即刚选定的第一位是最小值,不再参与比较,比较次数减1) 复杂度: 所需进行记录移动的操作次数较少 0--3(n-1) ,无论记录的初始排列如何,所需的关键字间的比较次数相同,均为n(n-1)/2,总的时间复杂度为O(n2):空间复杂度 O(1) 算法改进:每次对比,都是为了将最小的值放到第一位,所以可以一比到底,找出最小值,直接放到第一位,省去无意义的调换移动操作

  • Java 选择排序、插入排序、希尔算法实例详解

    1.基本思想: 在要排序的一组数中,选出最小的一个数与第一个位置的数交换:然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止. 2.实例 3.算法实现 /** * 选择排序算法 * 在未排序序列中找到最小元素,存放到排序序列的起始位置 * 再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾. * 以此类推,直到所有元素均排序完毕. * @param numbers */ public static void selectSort(int[] nu

  • java实现选择排序算法

    java实现选择排序算法 public static void selectSort(int[] array) { for (int i = 0; i < array.length - 1; i++) { int min = i; for (int j = i + 1; j < array.length; j++) { if (array[j] < array[min]) { min = j; } } Sort.swap(array, i, min);//交换i和min } } 选择排序

  • java数据结构排序算法之树形选择排序详解

    本文实例讲述了java数据结构排序算法之树形选择排序.分享给大家供大家参考,具体如下: 这里我们就来说说选择类排序之一的排序:树形选择排序 在简单选择排序中,每次的比较都没有用到上次比较的结果,所以比较操作的时间复杂度是O(N^2),想要降低比较的次数,则需要把比较过程中的大小关系保存下来.树形选择排序是对简单选择排序的改进. 树形选择排序:又称锦标赛排序(Tournament Sort),是一种按照锦标赛的思想进行选择排序的方法.首先对n个记录的关键字进行两两比较,然后在n/2个较小者之间再进

  • java数据结构与算法之简单选择排序详解

    本文实例讲述了java数据结构与算法之简单选择排序.分享给大家供大家参考,具体如下: 在前面的文章中已经讲述了交换类的排序算法,这节中开始说说选择类的排序算法了,首先来看一下选择排序的算法思想: 选择排序的基本算法思想: 每一趟在 n-i+1 (i=1,2,3,--,n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录. 简单选择排序: 设所排序序列的记录个数为n.i取1,2,-,n-1,从所有n-i+1个记录(Ri,Ri+1,-,Rn)中找出排序码最小的记录,与第i个记录交换.执行n-

  • Java数据结构与算法之栈(Stack)实现详解

    本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型顺序栈的设计与实现链式栈的设计与实现栈的应用 栈的抽象数据类型   栈是一种用于存储数据的简单数据结构,有点类似链表或者顺序表(统称线性表),栈与线性表的最大区别是数据的存取的操作,我们可以这样认为栈(Stack)是一种特殊的线性表,其插入和删除操作只允许在线性表的一端进行,一般而言,把允许操作的一端称为栈顶(Top),不可操作的一端称为栈底(Bottom),同时把插入元素的操作

  • java数据结构与算法数组模拟队列示例详解

    目录 一.什么是队列 二.用数组来模拟队列 一.什么是队列 队列是一个有序列表,可以用数组或者链表来实现. 遵循先入先出的原则,即:先存入队列的数据,要先取出.后存入的的数据,后取出. 看一张队列的模拟图,1,2,3表示同一个队列Queue.在队列中有2个指针,front表示队首,rear表示队尾. 图1中表示队列里还没有数据,所以front跟rear初始化都是-1. 当图2中有数据进行存入的时候,front没变,而rear则随着数据的增多而改变.存入了4个数据,于是rear=3. 再看图3,f

  • Java数据结构及算法实例:选择排序 Selection Sort

    /** * 选择排序的思想: * 每次从待排序列中找到最小的元素, * 然后将其放到待排的序列的最左边,直到所有元素有序 * * 选择排序改进了冒泡排序,将交换次数从O(N^2)减少到O(N) * 不过比较次数还是O(N) */ package al; public class SelectSort { public static void main(String[] args) { SelectSort selectSort = new SelectSort(); int[] elements

  • Java实现的各种排序算法(插入排序、选择排序算法、冒泡排序算法)

    一.插入排序算法实现java版本 public static int[] insert_sort(int[] a) { for (int i = 0; i < a.length; i++) { for(int j=i+1;j>0&&j<a.length;j--) { if(a[j]<a[j-1]) { int tmp = a[j]; //这样定义初始化逻辑上是可以的,j变量,每次tmp的值变化的 a[j] = a[j-1]; a[j-1] = tmp; } } }

  • PHP排序算法之简单选择排序(Simple Selection Sort)实例分析

    本文实例讲述了PHP排序算法之简单选择排序(Simple Selection Sort).分享给大家供大家参考,具体如下: 基本思想: 通过 n - i 次关键字间的比较,从 n - i + 1 个记录中选出关键字最小的记录,并和第 i (1 <= i <= n) 个记录交换,执行n-1趟 后就完成了记录序列的排序. 算法实现: <?php //简单选择排序 //交换函数 function swap(array &$arr,$a,$b){ $temp = $arr[$a]; $a

  • Python 选择排序中的树形选择排序

    目录 1.引言 2.问题描述 3.解决方案 4.结语 1.引言 选择排序里面主要讲了三个排序,分别是简单选择排序.树形选择排序.堆排序.今天这篇文章主要讲树形选择排序,树形选择排序也被称为锦标赛排序,树形选择排序运用了锦标赛的思想进行排序,树形选择排序是指首先对n个记录的关键字进行两两比较,然后在n/2个较小者之间再进行两两比较,如此重复,直至选出最小的记录为止. 2.问题描述 给定一个序列,我们将如何用树形选择排序来将它排序呢,下面将结合图形和文字一起讲述. 示例1:对数据表A=(73,45,

随机推荐