java堆排序代码

Python014

java堆排序代码,第1张

//从a[index]到a[len]除了a[index]外其它元素满足一个堆,把a[index]调整到合适位置

//这个堆满足父节点>孩子结点,且要保证2*index能取到index的左孩子,

public static void adjustHeap(int[] a,int index,int len){

int scn=a[index]

for(int i=2*indexi<=mi*=2){

if(i<m&&a[i]<a[i+1])i+=1

if(!a[i]>scn)break

a[index]=a[i]index=i

}

a[index]=scn

}

//数组a从a[1]开始存放元素,如果想从a[0]开始则要调整adjustHeap代码,以便满足完全二叉树

//性质,代码未经测试

public static void heapSort(int[] a){

for(int i=(a.length-1)/2i>0i--)

adjustHeap(a,i,a.length-1)

int tmp

for(int i=a.length-1i>1i--){

tmp=a[i]

a[i]=a[1]

a[1]=tmp

adjustHeap(a,1,i-1)

}

}

java常见的排序分为:

1 插入类排序

主要就是对于一个已经有序的序列中,插入一个新的记录。它包括:直接插入排序,折半插入排序和希尔排序

2 交换类排序

这类排序的核心就是每次比较都要“交换”,在每一趟排序都会两两发生一系列的“交换”排序,但是每一趟排序都会让一个记录排序到它的最终位置上。它包括:起泡排序,快速排序

3 选择类排序

每一趟排序都从一系列数据中选择一个最大或最小的记录,将它放置到第一个或最后一个为位置交换,只有在选择后才交换,比起交换类排序,减少了交换记录的时间。属于它的排序:简单选择排序,堆排序

4 归并类排序

将两个或两个以上的有序序列合并成一个新的序列

5 基数排序

主要基于多个关键字排序的。

下面针对上面所述的算法,讲解一些常用的java代码写的算法

二 插入类排序之直接插入排序

直接插入排序,一般对于已经有序的队列排序效果好。

基本思想:每趟将一个待排序的关键字按照大小插入到已经排序好的位置上。

算法思路,从后往前先找到要插入的位置,如果小于则就交换,将元素向后移动,将要插入数据插入该位置即可。时间复杂度为O(n2),空间复杂度为O(1)

package sort.algorithm

public class DirectInsertSort {

public static void main(String[] args) {

// TODO Auto-generated method stub

int data[] = { 2, 6, 10, 3, 9, 80, 1, 16, 27, 20 }

int temp, j

for (int i = 1i <data.lengthi++) {

temp = data[i]

j = i - 1

// 每次比较都是对于已经有序的

while (j >= 0 &&data[j] >temp) {

data[j + 1] = data[j]

j--

}

data[j + 1] = temp

}

// 输出排序好的数据

for (int k = 0k <data.lengthk++) {

System.out.print(data[k] + " ")

}

}

}

三 插入类排序之折半插入排序(二分法排序)

条件:在一个已经有序的队列中,插入一个新的元素

折半插入排序记录的比较次数与初始序列无关

思想:折半插入就是首先将队列中取最小位置low和最大位置high,然后算出中间位置mid

将中间位置mid与待插入的数据data进行比较,

如果mid大于data,则就表示插入的数据在mid的左边,high=mid-1

如果mid小于data,则就表示插入的数据在mid的右边,low=mid+1

最后整体进行右移操作。

时间复杂度O(n2),空间复杂度O(1)

package sort.algorithm

//折半插入排序

public class HalfInsertSort {

public static void main(String[] args) {

int data[] = { 2, 6, 10, 3, 9, 80, 1, 16, 27, 20 }

// 存放临时要插入的元素数据

int temp

int low, mid, high

for (int i = 1i <data.lengthi++) {

temp = data[i]

// 在待插入排序的序号之前进行折半插入

low = 0

high = i - 1

while (low <= high) {

mid = (low + high) / 2

if (temp <data[mid])

high = mid - 1

else

// low=high的时候也就是找到了要插入的位置,

// 此时进入循环中,将low加1,则就是要插入的位置了

low = mid + 1

}

// 找到了要插入的位置,从该位置一直到插入数据的位置之间数据向后移动

for (int j = ij >= low + 1j--)

data[j] = data[j - 1]

// low已经代表了要插入的位置了

data[low] = temp

}

for (int k = 0k <data.lengthk++) {

System.out.print(data[k] + " ")

}

}

}

四 插入类排序之希尔排序

希尔排序,也叫缩小增量排序,目的就是尽可能的减少交换次数,每一个组内最后都是有序的。

将待续按照某一种规则分为几个子序列,不断缩小规则,最后用一个直接插入排序合成

空间复杂度为O(1),时间复杂度为O(nlog2n)

算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成。

package sort.algorithm

public class ShellSort {

public static void main(String[] args) {

int a[] = { 1, 54, 6, 3, 78, 34, 12, 45, 56, 100 }

double d1 = a.length

int temp = 0

while (true)

{

//利用这个在将组内倍数减小

//这里依次为5,3,2,1

d1 = Math.ceil(d1 / 2)

//d为增量每个分组之间索引的增量

int d = (int) d1

//每个分组内部排序

for (int x = 0x <dx++)

{

//组内利用直接插入排序

for (int i = x + di <a.lengthi += d) {

int j = i - d

temp = a[i]

for (j >= 0 &&temp <a[j]j -= d) {

a[j + d] = a[j]

}

a[j + d] = temp

}

}

if (d == 1)

break

}

for (int i = 0i <a.lengthi++)

System.out.print(a[i]+" ")

}

}

五 交换类排序之冒泡排序

交换类排序核心就是每次比较都要进行交换

冒泡排序:是一种交换排序

每一趟比较相邻的元素,较若大小不同则就会发生交换,每一趟排序都能将一个元素放到它最终的位置!每一趟就进行比较。

时间复杂度O(n2),空间复杂度O(1)

package sort.algorithm

//冒泡排序:是一种交换排序

public class BubbleSort {

// 按照递增顺序排序

public static void main(String[] args) {

// TODO Auto-generated method stub

int data[] = { 2, 6, 10, 3, 9, 80, 1, 16, 27, 20, 13, 100, 37, 16 }

int temp = 0

// 排序的比较趟数,每一趟都会将剩余最大数放在最后面

for (int i = 0i <data.length - 1i++) {

// 每一趟从开始进行比较,将该元素与其余的元素进行比较

for (int j = 0j <data.length - 1j++) {

if (data[j] >data[j + 1]) {

temp = data[j]

data[j] = data[j + 1]

data[j + 1] = temp

}

}

}

for (int i = 0i <data.lengthi++)

System.out.print(data[i] + " ")

}

}

可以实现比较器Comparator来定制排序方案,同时使用Colletions.sort的方式进行排序,代码如下:

public void sortDesc(List<Long>s){

Collections.sort(s, new Comparator<Long>() {

public int compare(Long o1, Long o2) {

Long result = o2 - o1

return result.intValue()

}

})

s.forEach(item->{

System.out.print(item +" ")

})

}

同时常用的比较排序算法主要有:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等。

java的冒泡排序实现如下:

public static void bubbleSort(int []arr) {        for(int i =0i<arr.length-1i++) {            for(int j=0j<arr.length-i-1j++) {//-1为了防止溢出                if(arr[j]>arr[j+1]) {                    int temp = arr[j]                                         arr[j]=arr[j+1]                                         arr[j+1]=temp            }            }            }    }

还有非比较排序,时间复杂度可以达到O(n),主要有:计数排序,基数排序,桶排序等。