排序方法
包括方法是插入排序,归并排序,通用排序,快速排序,第K大元素查找
1.0插入排序
老师在返回试卷给学生之前会,把试卷按学生的名字的字母顺序排序,现在老师要排序的学生的卷子有:Monroe,chin,Flores,Stein,Dare
如图
1.1插入原理
引用
假定n是数组arr的长度.排序关系假定第一个元素被放置到其正确的位置上, 这样需要从1到n-1方位内的n-1个遍对剩余元素进行排序. 对于通用的遍i来说,从0到i-1范围内的元素已i的子列表之内的正确位置上.将arr[i]复制为一个名为target的临时元素.向下扫描列表,比较这个目标值与项arr[i-1],arr[i-2],依次类推.
/**
* 插入排序:插入排序算法在已排列子列表中插入
* @param <T>
* @param arr
*/
public static <T extends Comparable<? super T>> void insertionSort(T[] arr) {
int n = arr.length;
T target;
for (int i = 1; i < n; i++) {
target = arr[i];
int j = i;
while (j > 0 && target.compareTo(arr[j - 1]) < 0) {//i元素找到0到i-1小于i的元素
arr[j] = arr[j - 1];//前后交换
j--;
}
arr[j] = target;
}
}
1.2测试用例
/**
* 测试: 插入排序
*/
public void insertionSort() {
Integer[] intArr = { 2, 5, 3, 5, 4, 7, 5, 1, 8, 9 };
ArraysUtil.printArrays(intArr);//把数组输出到控制台,此类在附件能找到
Arrays.insertionSort(intArr);//Arrays类里面插入排序方法
ArraysUtil.printArrays(intArr);
}
2.0分治排序算法
分解: 将元素分隔成长度相等的两个数组.
递归求解: 将每对已排序的组合为一个大的已排序的列表
分治策略是归并排序, 通过在中性点进行分离, 归并精确对半分隔元素.递归列表分为两个部分,每个部分都含有二分之一的元素;随后将这两个部分再分解为四个部分, 每个部分都含有4分之一的元素,以此类推. 主要子列表具有两个以上或多个元素, 这个分解过程就会继续进行下去.以相反的顺序执行组合时,递归步骤会将一排序的部分列表部分和并越来越大的有序列表,直到算法以升序重够了原始序列
2.1归并排序
一个数组整数int[] arr={7,10,19,25,12,17,21,30,48}现在以归并排序为例
步骤1: 比较arr[indexA]=7与arr[indexB]=12.将较小的元素7复制到数组tempArr的索引indexC处.indexA++;indexC++;
步骤2:比较arr[indexA]=10与arr[indexB]=12.将较小的元素10复制到数组tempArr的索引indexC处.
步骤3:比较arr[indexA]=19与arr[indexB]=12.将较小的元素12复制到数组tempArr的索引indexC处.
步骤4~7:对两个子列表中元素的成对比较继续将元素17,19,21和25复制到数组tempArr.此时, indexA到子列表A的末尾(indexA==mid),indexB引用的值为30
步骤8~9: 合并过程通常选择完一个列表, 另外一个列表的尾部则还为选中.在这个示例子中,子列表b尾部中元素30和48还未负责到tempArr.步骤8和9子列表B的尾部复制到tempArr, 直到indexB到达末尾(indexB==last)
2.1归并排序原理
引用
int mid=(first+last)/2;
每个递归步骤都会生成对于mergeSort()方法的两个调用.其中一个调用使用索引first和mid来的定义用于原始序列下半部分列表的索引范围[first,mid);第二个调用是使用索引mid和last用于原始序列的上半部分的索引范围[mid,last).这个过程可以生成一个递归调用链,从而将原始序列分隔为越来越小的子列表, 直到这些子列表的长度变为1(停止条件).长度为1的显然已经排好序.然后以相反顺序重新访问递归调用链使用合并算法构建越来越大的有序子列表.
public static <T extends Comparable<? super T>> void msort(T[] arr,
T[] tempArr, int first, int last) {
if (first + 1 < last) {
int midpt = (last + first) / 2;
msort(arr, tempArr, first, midpt);
msort(arr, tempArr, midpt, last);
if (arr[midpt - 1].compareTo(arr[midpt]) <= 0)
return;
int indexA, indexB, indexC;
indexA = first;
indexB = midpt;
indexC = first;
while (indexA < midpt && indexB < last) {
if (arr[indexA].compareTo(arr[indexB]) < 0) {
tempArr[indexC] = arr[indexA]; // copy element to tempArr
indexA++; // increment indexA
} else {
tempArr[indexC] = arr[indexB]; // copy element to tempArr
indexB++; // increment indexB
}
// increment indexC
indexC++;
}
while (indexA < midpt) {// 复制前子表尾部
tempArr[indexC] = arr[indexA]; // copy element to tempArr
indexA++;
indexC++;
}
while (indexB < last) {// 复制后子表尾部
tempArr[indexC] = arr[indexB]; // copy element to tempArr
indexB++;
indexC++;
}
for (int i = first; i < last; i++)// 从temp复制到array
arr[i] = tempArr[i];
}
}
2.2测试用例
public void msort() {
Integer[] intArr = { 25, 10, 7, 19, 3, 48, 12, 17, 56, 30, 21 };
Integer[] tempArr = intArr.clone();
GenericUtil.msort(intArr, tempArr, 0, intArr.length);
ArraysUtil.printArrays(intArr);
}
3.0快速排序
快速排序使用一些列递归调用算法将列表分割为若干越来越小的子列表, 这些子列表位于基准值(pivot)左右. 每个递归步骤根据作为列表中心的点值的基准进行选择.分割算法完成交换, 从而使基准值在元素排序后被放置在列表中的正确位置上.此时,下子列表只含小于或等于表准值的元素, 而上字表只含大于或等于基准值的元素.
scanUp继续向上搜索,在索引3处,scanDown停止在索引8处
继续上面的步骤,到达停止条件
在scanDown<=scanUp时,分割过程终止.如果scanDown==scanUp,那么arr[scanDown]<=pivot并且arr[scanUp>=pivot
3.2快速排序
递归调用链
3.3 快速排序查找基准值
public static <T extends Comparable<? super T>> int prvotIndex(T[] arr,
int first, int last) {
int mid, scanUp, scanDown;
T pivot, temp;
if (first == last) {// 空子列
return last;
} else if (first == last - 1) {// 一个元素的子列
return first;
} else {
mid = (first + last) / 2;// 交换prvot和范围的低端和初始化指数scanUp和scandown
pivot = arr[mid];
arr[mid] = arr[first];
arr[first] = pivot;
scanUp = first + 1;
scanDown = last - 1;
for (;;) {
while (scanUp <= scanDown && arr[scanUp].compareTo(pivot) < 0) {//每个步骤开始时都会使用索引scanUp在列表中向上移动,直至该索引停止在应归入上子列表(由大于或等于基准值的元素组成)的某个元素处
scanUp++;
}
while (pivot.compareTo(arr[scanDown]) < 0) {//索引scanDown在列表中向下移动,直至该索引停止在应归入子列表(由小于或等于基准值的元素组成)的某个元素处
scanDown--;
}
if (scanUp >= scanDown) {
break;
}
temp = arr[scanUp];//如果scandown<=scanUp,那么迭代停止.否这,两个扫描在scanUp<scanDown时停止,并且每个索引都指向位于错误列表中的某个元素.通过这两个元素的交换就能够完成列表的重新排列. 扫描结束后,索引scanDown的位置将列表分割为两个子列表.pivotIndex()方法能够交换arr[first]最后哦功能的基准值与arr[scandown],并且scanDown设置为返回值
arr[scanUp] = arr[scanDown];
arr[scanDown] = temp;
scanUp++;
scanDown++;
}
arr[first] = arr[scanDown];
arr[scanDown] = pivot;
return scanDown;
}
}
- 大小: 24.2 KB
- 大小: 13.1 KB
- 大小: 12.7 KB
- 大小: 12.7 KB
- 大小: 13.2 KB
- 大小: 13.3 KB
- 大小: 40.5 KB
- 大小: 11.9 KB
- 大小: 13.3 KB
- 大小: 13.2 KB
- 大小: 5.2 KB
- 大小: 16.4 KB
分享到:
相关推荐
在本系统中,我们主要实现了五种常用的排序算法:冒泡排序法、快速排序法、直接插入排序法、折半插入排序法和树形选择排序法。这些算法都是在计算机科学中最基本和最重要的排序算法,广泛应用于各种数据处理和分析...
常见的经典排序算法有希尔排序、二分插入法、直接插入法、带哨兵的直接排序法、冒泡排序、选择排序、快速排序、堆排序等。 一、希尔排序(Shell 排序法) 希尔排序法,又称宿小增量排序,是 1959 年由 D.L.Shell ...
常见的排序算法有插入排序、快速排序、选择堆积排序法等。 插入排序算法是一种简单的排序算法,适用于小规模的数据结构。该算法将数据结构分成已排序部分和未排序部分,并将未排序部分的元素插入到已排序部分中。...
在计算机科学领域,排序算法是数据处理中的核心部分,它涉及到如何有效地重新排列一组数据,使其按照特定的顺序排列。本资源"总结了各种排序算法,并用C++代码实现,并有演示",提供了丰富的学习材料,包括不同类型...
希尔排序是一种基于插入排序的算法,通过将待排序的数组元素按某个增量分组,然后对每组使用直接插入排序算法排序。随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止...
本篇文章将介绍一种经典的排序算法——**合并排序法**(Merge Sort),并通过C语言实现该算法。合并排序是一种非常有效的排序方法,其核心思想是分治法:将数据分为若干个子集,对这些子集分别进行排序,最后将排序...
最快的排序算法 最快的内部排序法—桶排序法,排序算法数据结构
在IT领域,排序算法是计算机科学中的基础但至关重要的概念,尤其在数据处理和算法设计中扮演着核心角色。本文将深入探讨标题中提到的几种基于比较的排序算法:选择排序、插入排序、归并排序、快速排序、堆排序、冒泡...
最快的排序算法 最快的内部排序法—桶排序法 (1),排序算法数据结构
在计算机科学领域中,排序算法是一种基本的算法,它可以将数据按照一定的顺序排列,以便更好地存储、检索和处理数据。排序算法的速度和效率对程序的性能有着至关重要的影响。 1.冒泡排序算法 冒泡排序算法是一种...
该程序包含7大排序算法: # sort.bubbleSort() #冒泡排序 # sort.shellSort() #希尔排序 # sort.insertionSort() #插入排序 # sort.Selectionsort1() #选择排序 # sort.heapSort() #堆排序 # sort.countSort() ...
根据给定文件的信息,本文将深入探讨C语言中的两种经典排序方法:插入排序法与冒泡排序法。这两种方法在实际编程中应用广泛,对于理解数据结构与算法的基础概念至关重要。 ### 一、冒泡排序法 #### 1.1 基本原理 ...
双向起泡排序法是一种在链表结构中实现的排序算法,尤其适用于双向链表。它借鉴了传统冒泡排序的基本思想,但在链表环境中进行了优化,以提高效率。本篇文章将详细探讨双向起泡排序法及其在带头结点的双向链表中的...
六种排序算法的排序系统 本篇文章主要讲解了六种排序算法的排序系统,包括插入排序、冒泡排序、选择排序、快速排序、堆排序和归并排序。该系统可以让用户选择六种排序算法中的任意一个,并输出结果。 插入排序 ...
在IT领域,排序算法是计算机科学中的基础但至关重要的部分,尤其在数据处理和数据分析中起着关键作用。本文将详细探讨标题所提及的几种排序算法:合并排序、插入排序、希尔排序、快速排序、冒泡排序以及桶排序,并...
在计算机科学中,排序算法是数据结构领域的重要组成部分,它涉及到如何有效地重新排列一组数据,使其按照特定的顺序排列。本资源提供了三种经典的排序算法的C语言实现:堆排序、直接插入排序和快速排序。 首先,让...
在计算机科学领域,排序算法是数据处理中至关重要的一部分,它涉及到如何有效地重新排列一组数据,使其按照特定的顺序排列。本资源提供了七大经典排序算法的实现程序,包括快速排序、冒泡排序、选择排序、归并排序、...
时间复杂度用于衡量排序算法的效率,通常以大O表示法来表示。文档中提到了几种不同排序算法的时间复杂度: - **O(n²)**:插入排序、冒泡排序和选择排序的时间复杂度均为O(n²),这意味着随着数据量的增加,这些...
排序算法是计算机科学中最基础和重要的算法之一,用于将一组数据按照特定的顺序进行排列。本文将对几种常见的内部排序算法和外部排序算法进行详细总结。 首先,排序的基本定义是:给定一个包含n个记录的序列,其...
在编程领域,排序算法是计算机科学中的重要组成部分,特别是在数据处理和算法效率分析上。本文将详细介绍C++中实现的希尔排序、快速排序、堆排序和归并排序这四种经典排序算法。 希尔排序,由Donald Shell于1959年...