Java实现各种内部排序算法

数据结构中常见的内部排序算法:

  插入排序:直接插入排序、折半插入排序、希尔排序

  交换排序:冒泡排序、快速排序

  选择排序:简单选择排序、堆排序

  归并排序、基数排序、计数排序

直接插入排序

  思想:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中,直到全部记录插入完成。

  性能:时间复杂度:最好o(n):有序,最坏o(n^2):逆序,平均o(n^2);空间复杂度o(1);稳定

 1   public int[] straightInsertSort(int array[]){
 2         int temp;
 3         for(int i=1; i<array.length; i++){ //依次对1到array.length-1个元素进行处理
 4             temp = array[i];
 5             for(int j=0; j<i; j++){  //已排好序的0到i-1个元素
 6                 if(temp < array[j]){  //插入位置j
 7                     for(int k=i-1;k>=j;k--){  //将j到i-1个元素向后移一个位置
 8                         array[k+1]=array[k];  //此时array[i]为已排好序的子数组中的最大值
 9                     }
10                     array[j] = temp;  //将第i个元素插入到位置j上
11                     break;
12                 }
13             }
14         }
15         return array;
16     }

折半插入排序:

  思想:利用折半查找的方法找出元素的待插入位置,然后再统一移动待插入位置之后的所有元素,最后将待插入元素插入到相应位置。

  性能:平均情况下,比较次数o(nlogn),移动次数o(n^2)

     时间复杂度:最好o(n):有序,最坏o(n^2):逆序,平均o(n^2);空间复杂度o(1);稳定

 1     public int[] binaryInsertSort(int[] array){
 2         int temp,low,high;
 3         for(int i=1; i<array.length; i++){
 4             temp = array[i];
 5             //从已排好序的0到i-1个元素中,折半查找出元素的待插入位置
 6             low = 0;
 7             high = i-1;
 8             while(low <= high){
 9                 if(array[(low+high)/2] <= array[i]){
10                     low = (low+high)/2 + 1;
11                 }else{
12                     high = (low+high)/2 - 1;
13                 }
14             }
15             //移动待插入位置low到i-1间的所有元素
16             for(int j=i-1; j>=low; j-- ){
17                 array[j+1] = array[j];
18             }
19             array[low] = temp;
20         }
21         return array;
22     }

希尔排序:

  思想:将排序表分割成若干个形如L[i,i+d,i+2d,...,i+kd]的“特殊”子表,分别进行直接插入排序,当整个表中元素已呈现“基本有序”时,再对全体记录进行一次直接插入排序(d=1时)。

     步长设置:d1=array.length/2;di=di/2,最后一个增量为1;

  性能:时间复杂度:最坏o(n^2),平均o(n^1.3),空间复杂度o(1),不稳定

 1 public int[] shellSort(int[] array){
 2         for(int d=array.length/2; d>=1; d=d/2){ //用步长值来控制循环次数
 3             for(int i=d;i<array.length;i++){
 4                 int temp = array[i];
 5                 if(temp < array[i-d]){  //将array[i]插入到有序增量子表中
 6                     int j;
 7                     for(j=i-d;j>=0 && temp<array[j];j-=d){
 8                         array[j+d]=array[j];  //记录后移,寻找插入位置
 9                     }
10                     array[j+d] = temp;
11                 }
12             }
13         }
14         return array;
15     }

冒泡排序:

  思想:对于待排序表,从前往后两两比较相邻元素的值,若为逆序,则交换,直到序列比较完成。如此,每次冒泡即可得到当前待排表中的最大元素,并已放置在相应的位置。

  性能:时间复杂度:最好o(n)有序,最坏o(n^2)逆序,平均o(n^2),空间复杂度o(1),稳定

 1     public int[] bubbleSort(int[] array){
 2         boolean flag = false; //用来标记该序列是否已是有序
 3         for(int i=0;i<array.length-1;i++){ //做n-1趟冒泡
 4             for(int j=0;j<array.length-i-1;j++){
 5                 if(array[j]>array[j+1]){
 6                     int temp = array[j];
 7                     array[j] = array[j+1];
 8                     array[j+1] = temp;
 9                     flag = true;  //有元素交换,则该序列初始状况不是有序的
10                 }
11             }
12             if(flag == false){  //本趟遍历后没有发生交换,说明表已经有序
13                 return array;
14             }
15         }
16         return array;
17     }

快速排序:

  思想:基于分治的思想:在待排序表中任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独立的两部分,使得一部分中所有元素小于pivot,另一部分中所有元素大于或等于pivot,则pivot放在了其最终位置上,这个过程称为一趟快速排序。而后递归地对两个子表重复上述过程,直到每部分内只有一个元素或空为止。

  性能: 空间复杂度:需要递归工作栈:最坏o(n),平均o(logn)

      时间复杂度:最坏:o(n^2)初始表基本有序或基本逆序,平均o(n*logn)

      不稳定

 1   public int[] quickSort(int[] array,int low,int high){
 2         if(low<high){  //递归跳出的条件
 3             int mid= partition(array, low, high); //划分,得到枢值所在的下表
 4             quickSort(array,low,mid-1);  //依次对两个子表进行递归排序
 5             quickSort(array,mid+1,high);
 6         }
 7         return array;
 8     }
 9     //快速排序的划分函数
10     public int partition(int[] array,int low, int high){
11         int pivot = array[low];  //每次取数组中的第一个元素为基准
12         while(low < high){  //跳出循环的条件
13             while(low<high && array[high] > pivot){  //从右边开始找到第一个小于或等于pivot的值
14                 high--;
15             }
16             while(low<high && array[low] < pivot){   //从左边开始找到第一个大于或等于pivot的值
17                 low++;
18             }
19             int temp = array[low];   //交换
20             array[low] = array[high];
21             array[high] = temp;
22             if(low<high && array[low] == pivot && array[high] == pivot){  //特殊情况
23                 low++;
24             }
25         }
26         return low;
27     }

简单选择排序:

  思想:

  性能:时间复杂度:o(n^2),空间复杂度o(1),不稳定

    public int[] simpleSelectSort(int[] array){
        for(int i=0;i<array.length -1;i++){  //一共进行n-1趟
            int min = i;  //记录最小元素位置
            for(int j=i+1;j<array.length;j++){ //在array[i,...,n-1]中选择最小的元素
                if(array[j] < array[min]){
                    min = j;   //更新最小元素的位置
                }
            }
            int temp = array[i];  //将最小元素与第i个位置交换
            array[i] = array[min];
            array[min] = temp;
        }
        return array;
    }

归并排序:

  思想:

  性能:空间复杂度:o(n);时间复杂度:o(nlogn);稳定

 1   public int[] mergeSort(int[] array,int low, int high){
 2         if(low < high){  //递归结束的条件
 3             int mid = (low + high)/2;  //二路归并排序,从中间划分两个子序列
 4             mergeSort(array, low, mid); //对左侧子序列进行递归排序
 5             mergeSort(array, mid+1, high); //对右侧子序列进行递归排序
 6             merge(array,low,mid,high); //归并
 7         }
 8         return array;
 9     }
10
11     //将前后相邻的两个有序表归并为一个有序表
12     private void merge(int[] array,int low, int mid, int high){
13         int[] tempArray = new int[array.length];  //辅助数组tempArray
14         for(int i=low;i<=high;i++){ //将array数组中[low...high]复制到辅助数组tempArray中
15             tempArray[i] = array[i];
16         }
17         int i,j,k;
18         for(i=low,j=mid+1,k=i;i<=mid && j<=high;k++){
19             if(tempArray[i]>tempArray[j]){  //比较tempArray的左右两端中的元素
20                 array[k] = tempArray[j++];  //将较小值复制到array中
21             }else{
22                 array[k] = tempArray[i++];
23             }
24         }
25         while(i<=mid){    //若第一个表未检测完,复制
26             array[k++] = tempArray[i++];
27         }
28         while(j<=high){      //若第二个表未检测完,复制
29             array[k++] = tempArray[j++];
30         }
31     }

计数排序:

  思想:

  性能:

 1     public int[] countSort(int[] array){
 2         int[] tempArray = new int[array.length];
 3         for(int i=0;i<array.length;i++){
 4             int count = 0;
 5             for(int j=0;j<array.length;j++){
 6                 if(array[i]>array[j]){
 7                     count++;
 8                 }
 9             }
10             tempArray[count] = array[i];
11         }
12         return tempArray;
13     }
时间: 2024-08-22 16:32:12

Java实现各种内部排序算法的相关文章

数据结构6种内部排序算法的比较

1.需求分析 (1)输入数据的形式为:伪随机数产生程序产生,且每次输入数不少于100个,至少要用5组不同的输入数据 (2)输出的形式为:输出关键字参加的比较次数和关键字的移动次数(关键字交换计为3次移动)的数据 (3)程序能达到的功能:对起泡排序,直接插入排序,简单选择排序,快速排序,希尔排序,堆排序这6种常用的内部排序算法进行比较,比较的指标为有关键字参加的比较次数和关键字的移动次数(关键字交换计为3次移动) (4)测试数据:正确输入为由伪随机数产生程序产生100个随机数,然后输出比较结果,错

内部排序算法(一):交换排序(冒泡排序,快速排序)

这是我的博文系列<内部排序算法>的第一篇.所谓排序,就是要整理文件中的记录,使之按关键字递增(或递减)次序排列起来.所谓内部排序,是指在排序过程中,若整个文件都是放在内存中处理,排序时不涉及数据的内.外存交换(外排序的定义则相反). 内部排序法按照策略可以划分为五类:插入排序.选择排序.交换排序.归并排序和分配排序.待排文件的存储方式采用顺序表(或直接用向量)作为存储结构(其他的存储结构还有以链表作为存储结构等). 在这个系列的博文中,我按照排序算法的给出,排序算法的分析(包括算法的时空复杂度

java实现的集中排序算法

嗯,在经典的排序算法里面,有:冒泡排序,选择排序,插入排序,希尔排序,二叉归并排序,快速排序,堆排序 下面给出java的实现方式,不过快速排序没有搞定,研究中 package net.itaem.sort; /** * 数组排序 * */ public class ArraySorted { /** * 冒泡排序(而且是简单的冒泡排序,应该属于交换排序,不属于经典的冒泡排序) * */ public static void bubble(int[] source){ if(source.leng

八大内部排序算法(上)-冒泡、直接插入、简单选择、快速

八大内部排序算法(上)冒泡.直接插入.简单选择.快速 排序分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 1.直接插入排序 将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表.即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止. 要点:设立哨兵,作为临时存储和判断数组边界之用. 直接插入实现如下:

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

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

内部排序算法小结

内部排序算法主要分为插入类排序.交换类排序和选择类排序,它们在性能上的差异主要体现在时间复杂度.空间复杂度和稳定性.各种排序算法都会进行元素间的比较和移动,时间复杂度主要由整个排序过程中的比较次数和移动次数决定.空间复杂度体现在除了待排序记录本身所占的空间,排序过程中占用了多少辅助空间. 1.插入类排序 直接插入排序 如果待排序记录之间是顺序排列,此时整个排序过程中元素比较的次数为n-1次,移动次数为0次.如果待排序记录之间是逆序排列,第i趟排序比较次数为i,移动的次数为i+1,其中i的范围是2

java集合提供的排序算法

java集合提供的排序算法 Arrays.sort()排序算法 如果数组长度大于等于286且连续性好的话,就用归并排序,如果大于等于286且连续性不好的话就用双轴快速排序.如果长度小于286且大于等于47的话就用双轴快速排序,如果长度小于47的话就用插入排序. Collection.sort()的排序算法 如果LegacyMergeSort.userRequested为true的话就会使用归并排序 如果不为true的话就会用一个叫TimeSort的排序算法 原文地址:https://www.cn

[转载]图解程序员必须掌握的Java常用8大排序算法

这篇文章主要介绍了Java如何实现八个常用的排序算法:插入排序.冒泡排序.选择排序.希尔排序 .快速排序.归并排序.堆排序和LST基数排序,分享给大家一起学习. 分类1)插入排序(直接插入排序.希尔排序)2)交换排序(冒泡排序.快速排序)3)选择排序(直接选择排序.堆排序)4)归并排序5)分配排序(基数排序) 所需辅助空间最多:归并排序所需辅助空间最少:堆排序平均速度最快:快速排序 不稳定:快速排序,希尔排序,堆排序. 先来看看8种排序之间的关系: 1.直接插入排序 (1)基本思想:在要排序的一

(2)Java数据结构--二叉树 -和排序算法实现

=== 注释:此人博客对很多个数据结构类都有讲解-并加以实例 Java API —— ArrayList类 & Vector类 & LinkList类Java API —— BigDecimal类Java API —— BigInteger类Java API —— Calendar类Java API —— DateFormat类Java API —— Date类Java API —— HashMap类 & LinkedHashMap类Java API —— JDK5新特性Java