目录

1 问题描述

2 解决方案

2.1 检验数组中元素的唯一性

2.2 模式计算

 


1 问题描述

在计算机科学中,预排序是一种很古老的思想。实际上,对于排序算法的兴趣很大程度上是因为这样一个事实:如果列表是有序的,许多关于列表的问题更容易求解。显然,对于包含了排序操作,这种算法的时间效率依赖于所选用的排序算法的效率。

对于预排序的具体思想应用请参考下文。


2 解决方案

2.1 检验数组中元素的唯一性

此问题,首先使用合并排序对数组中元素进行一次从小到大的排序,然后,依次检查数组中的元素,看是否有重复元素,如果有这说明该元素不具有唯一性,否则说明该数组中的所有元素具有元素的唯一性。

具体代码如下:

package com.liuzhen.chapter6;public class PresortElementUniqueness {//归并排序public void mergeSort(int[] A){if(A.length > 1){int[] leftA = getHalfArray(A,0);   //数组A的左半部分int[] rightA = getHalfArray(A,1);  //数组A的右半部分
            mergeSort(leftA);mergeSort(rightA);getMerge(A,leftA,rightA);}}/** 参数A:要进行折半的数组* 参数judge:judge == 0表示返回数组A左上半部分,judge != 0表示返回数组A的右半部分* 函数功能:把数组按照长度均分为上半部分和下半部分*/public int[] getHalfArray(int[] A,int judge){int[] result;if(judge == 0){result = new int[A.length/2];for(int i = 0;i < A.length/2;i++)result[i] = A[i];}else{result = new int[A.length - A.length/2];for(int i = 0;i < A.length - A.length/2;i++)result[i] = A[i+A.length/2];}return result;}/**参数A:给定待排序数组*参数leftA:数组A的左半部分*参数rightA:数组的右半部分*函数功能:返回数组A的从小到大排序*/public void getMerge(int[] A,int[] leftA,int[] rightA){int i = 0;       //用于计算当前遍历leftA的元素个数int j = 0;       //用于计算当前遍历rightA的元素个数int count = 0;   //用于计算当前得到按从小到大排序的A的元素个数while(i < leftA.length && j < rightA.length){if(leftA[i] < rightA[j]){A[count++] = leftA[i];i++;}else{A[count++] = rightA[j];j++;}}if(i < leftA.length){while(i < leftA.length)A[count++] = leftA[i++];}if(j < rightA.length){while(j < rightA.length)A[count++] = rightA[j++];}}//判断数组A(PS:数组A已是有序数组)中元素是否具有唯一性public boolean judgeOnlyElement(int[] A){for(int i = 0;i < A.length-1;i++){if(A[i] == A[i+1])return false;}return true;}public static void main(String[] args){PresortElementUniqueness test = new PresortElementUniqueness();int[] A = {3,2,1,8,7,4,3,6,1,7,3,3,7,7,7,7};test.mergeSort(A);System.out.println("使用归并排序后数组A的结果:");for(int i = 0;i < A.length;i++)System.out.print(A[i]+" ");if(test.judgeOnlyElement(A))System.out.println("\n数组A中的元素具有唯一性");elseSystem.out.println("\n数组A中的元素不具有唯一性");int[] B = {9,8,7,6,5,4,3,2,1};test.mergeSort(B);System.out.println("使用归并排序后数组B的结果:");for(int i = 0;i < B.length;i++)System.out.print(B[i]+" ");if(test.judgeOnlyElement(B))System.out.println("\n数组B中的元素具有唯一性");elseSystem.out.println("\n数组B中的元素不具有唯一性");}
}

运算结果:

使用归并排序后数组A的结果:
1 1 2 3 3 3 3 4 6 7 7 7 7 7 7 8
数组A中的元素不具有唯一性
使用归并排序后数组B的结果:
1 2 3 4 5 6 7 8 9
数组B中的元素具有唯一性

2.2 模式计算

在给定的数组列表中最经常出现的一个数值称为模式。例如,对于5,1,5,7,6,5,7来说,模式是5(如果若干个不同的值都是最经常出现的,它们中的任何一个都可以看作模式。)

此处,首先对给定数组中元素使用合并排序进行从小到大排序,然后,依次遍历其中的元素,计算其中重复元素的最大个数,返回该元素的值,即为所求的模式。

具体代码如下:

package com.liuzhen.chapter6;public class PresortElementUniqueness {//归并排序public void mergeSort(int[] A){if(A.length > 1){int[] leftA = getHalfArray(A,0);   //数组A的左半部分int[] rightA = getHalfArray(A,1);  //数组A的右半部分
            mergeSort(leftA);mergeSort(rightA);getMerge(A,leftA,rightA);}}/** 参数A:要进行折半的数组* 参数judge:judge == 0表示返回数组A左上半部分,judge != 0表示返回数组A的右半部分* 函数功能:把数组按照长度均分为上半部分和下半部分*/public int[] getHalfArray(int[] A,int judge){int[] result;if(judge == 0){result = new int[A.length/2];for(int i = 0;i < A.length/2;i++)result[i] = A[i];}else{result = new int[A.length - A.length/2];for(int i = 0;i < A.length - A.length/2;i++)result[i] = A[i+A.length/2];}return result;}/**参数A:给定待排序数组*参数leftA:数组A的左半部分*参数rightA:数组的右半部分*函数功能:返回数组A的从小到大排序*/public void getMerge(int[] A,int[] leftA,int[] rightA){int i = 0;       //用于计算当前遍历leftA的元素个数int j = 0;       //用于计算当前遍历rightA的元素个数int count = 0;   //用于计算当前得到按从小到大排序的A的元素个数while(i < leftA.length && j < rightA.length){if(leftA[i] < rightA[j]){A[count++] = leftA[i];i++;}else{A[count++] = rightA[j];j++;}}if(i < leftA.length){while(i < leftA.length)A[count++] = leftA[i++];}if(j < rightA.length){while(j < rightA.length)A[count++] = rightA[j++];}}//返回数组A(PS:数组A是有序数组)中模式public int presortMode(int[] A){int i = 0;int modeFrequency = 0;int modeValue = 0;while(i < A.length){int temp = i;int count = 0;while(temp < A.length && A[temp] == A[i]){count++;temp++;}if(count > modeFrequency){modeFrequency = count;modeValue = A[i];}i = i+count;}return modeValue;}public static void main(String[] args){PresortElementUniqueness test = new PresortElementUniqueness();int[] A = {3,2,1,8,7,4,3,6,1,7,3,3,7,7,7,7};test.mergeSort(A);System.out.println("使用归并排序后数组A的结果:");for(int i = 0;i < A.length;i++)System.out.print(A[i]+" ");System.out.println("\n数组A中模式为:"+test.presortMode(A));int[] B = {9,8,7,6,5,4,3,2,1};test.mergeSort(B);System.out.println("使用归并排序后数组B的结果:");for(int i = 0;i < B.length;i++)System.out.print(B[i]+" ");System.out.println("\n数组B中模式为:"+test.presortMode(B));}
} 

运算结果:

使用归并排序后数组A的结果:
1 1 2 3 3 3 3 4 6 7 7 7 7 7 7 8
数组A中模式为:7
使用归并排序后数组B的结果:
1 2 3 4 5 6 7 8 9
数组B中模式为:1

转载于:https://www.cnblogs.com/liuzhen1995/p/6415979.html

算法笔记_036:预排序(Java)相关推荐

  1. 算法笔记(JavaScript版)——排序

    算法笔记(JavaScript版)--排序 本文内容根据Rebert Sedgewick和Kevin Wayne的<算法(第四版)>整理,原代码为java语言,自己修改为JavaScrip ...

  2. 算法练习5---快速排序Java版

    基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成 ...

  3. 排序算法之简单插入法排序(Java)

    简单插入排序    时间复杂度  O(n*n)  稳定的排序算法 逐一取出元素,在已排好的元素序列中从后向前扫描,插入到适当的位置 部分代码如下: public static void insert_ ...

  4. 排序算法之选择法排序(Java)

    选择排序    时间复杂度  O(n*n)  不稳定的排序算法 思想是:每一趟从待排序的数据元素中选出最小的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完. 下面是关键部分代码: ...

  5. 算法笔记_010:插入排序(Java)

    1 问题描述 给定一组数据,使用插入排序得到这组数据的非降序排列. 2 解决方案 2.1 插入排序原理简介 引用自百度百科: 有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求 ...

  6. 蓝桥试题 算法提高 冒泡法排序 JAVA

    资源限制 时间限制:1.0s 内存限制:512.0MB 输入10个数,用"冒泡法"对10个数排序(由小到大)这10个数字在100以内. 样例输入 1 3 6 8 2 7 9 0 4 ...

  7. 《算法笔记》-各种排序算法、散列、递归、贪心、二分、双指针、随机选择算法(知识点+例题+代码)

    一.排序 1.冒泡排序 进行数组大小-1趟排序 int a[]={3,4,1,5,2};//从小到大排序 //第一趟 3,4,

  8. 算法笔记4.1--EXCEL排序

    题目描述 Excel可以对一组纪录按任意指定列排序.现请你编写程序实现类似功能. 对每个测试用例,首先输出1行"Case i:",其中 i 是测试用例的编号(从1开始).随后在 N ...

  9. 算法笔记1926ProblemC Excel排序

    题目描述 Excel可以对一组纪录按任意指定列排序.现请你编写程序实现类似功能. 对每个测试用例,首先输出1行"Case i:",其中 i 是测试用例的编号(从1开始).随后在 N ...

最新文章

  1. 深入理解JavaScript模拟私有成员
  2. 数据结构:选择排序(Selection sort)
  3. scalac和classpath的设置
  4. TLS/SSl 相关攻击漏洞及检测方法(testssl.sh)
  5. Deep Image Prior:深度卷积网络先天就理解自然图像
  6. 03_ Flume采集(监听)目录到HDFS案例
  7. 从零开始学编程-从C开始
  8. 神州计算机u盘启动,神舟台式机bios怎么设置从u盘启动
  9. 求两个数的最小公倍数
  10. 《半小时漫画中国哲学史》读书摘记
  11. uniapp引用外部在线js
  12. 内存碎片---内部碎片外部碎片
  13. GFD563A101 3BHE046836R0101
  14. 解决rdm连接虚拟机redis失败,idea无法连接
  15. 梦三花重金修改服务器,可重置狐金踏云花姐
  16. JSD-2204-Java语言基础-分支结构-循环-Day04
  17. ApacheCamel简介
  18. Fortran中subroutine和function的区别
  19. 二级计算机考证需要多少钱
  20. 华为C8813流畅刷机包 B177定制 大运存 最新V6 省电流畅到爆表

热门文章

  1. 使用cocopods安装Alamofire后各种报错
  2. KVM之一:安装准备(基于CentOS6.7)
  3. POJ3728 THE MERCHANT LCA RMQ DP
  4. html5标签兼容低版本浏览器
  5. C++中宏的定义与用法(现已被内联函数所代替)
  6. 社交网站 分享 +button
  7. 关于排版与交互的问题
  8. ADO.NET常用对象详解之:Command对象
  9. 关于Cortex-M3处理器内核中断异常处理机制你了解多少?
  10. Java虚拟机专题之类加载机制