j++;
if(temp>a[j])//a[i]>a[j]
flag=1;//标记结束筛选条件
else{//否则把a[j]上移
a[i]=a[j];
i=j;
j=2*i+1;
}
}
a[i]=temp;//把最初的a[i]赋予最后的a[j]
}
publicstaticvoidinitCreateHeap(int[]a){
intn=a.length;
for(inti=(n-1)/2;i>=0;i--)
createHeap(a,n,i);
}
publicstaticvoidheapSort(int[]a){
inttemp;
intn=a.length;
initCreateHeap(a);//初始化创建最大堆
for(inti=n-1;i>0;i--){//当前最大堆个数每次递减1
//把堆顶a[0]元素和当前最大堆的最后一个元素交换
temp=a[0];
a[0]=a[i];
a[i]=temp;
createHeap(a,i,0);//调整根结点满足最大堆
}
}
publicstaticvoidmain(String[]args){
int[]test={10,50,32,5,76,9,40,88};
intn=test.length;
heapSort(test);
for(inti=0;iSystem.out.print(test[i]+"");
}
}
三、交换排序
Ø冒泡排序:
BubbleSort
排序方法最好时间平均时间最坏时间辅助空间稳定性
冒泡排序O(n)O(n2)O(n2)O
(1)稳定
冒泡排序的基本思想是:
设数组a中存放了n个数据元素,循环进行n-1趟如下的排序过程:
第1趟时,依次比较相临两个数据元素a[i]和a[i+1](i=0,1,2,…,n-2),若为逆序,即a[i]>a[i+1],则交换两个数据元素,否则不交换,这样数值最大的数据元素将被放置在a[n-1]中。
第2趟时,循环次数减1,即数据元素个数为n-1,操作方法和第1趟的类似,这样整个n个数据元素集合中数值次大的数据元素将被放置在a[n-2]中。
当第n-1趟结束时,整个n个数据元素集合中次小的数据元素将被放置在a[1]中,a[0]中放置了最小的数据元素。
publicclassBubbleSort{
publicstaticvoidbubbleSort(int[]a){
inti,j,flag=1;
inttemp;
intn=a.length;
for(i=1;iflag=0;
for(j=0;jif(a[j]>a[j+1]){
flag=1;
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
publicstaticvoidmain(String[]args){
int[]test={64,5,7,89,6,24};
intn=test.length;
bubbleSort(test);
for(inti=0;iSystem.out.print(test[i]+"");
}
}
Ø快速排序:
QuickSort
排序方法最好时间平均时间最坏时间辅助空间稳定性
快速排序O(nlog2n)O(nlog2n)O(n2)O(log2n)不稳定
快速排序是一种二叉树结构的交换排序方法。
快速排序算法的基本思想是:
设数组a中存放了n个数据元素,low为数组的低端下标,high为数组的高端下标,从数组a中任取一个元素(通常取a[low])做为标准元素,以该标准元素调整数组a中其他各个元素的位置,使排在标准元素前面的元素均小于标准元素,排在标准元素后面的均大于或等于标准元素。
这样一次排序过程结束后,一方面将标准元素放在了未来排好序的数组中该标准元素应位于的位置上,另一方面将数组中的元素以标准元素为中心分成了两个子数组,位于标准元素左边子数组中的元素均小于标准元素,位于标准元素右边子数组中的元素均大于等于或标准元素。
对这两个子数组中的元素分别再进行方法类同的递归快速排序。
算法的递归出口条件是low≥high。
publicclassQuickSort{
publicstaticvoidQuickSort(int[]a,intlow,inthigh){
inti,j;
inttemp;
i=low;
j=high;
temp=a[low];//取第一个元素为标准数据元素
while(i//在数组的右端扫描
while(ij--;
if(ia[i]=a[j];
i++;
}
//在数组的左端扫描
while(ii++;
if(ia[j]=a[i];
j--;
}
}
a[i]=temp;
if(low
QuickSort(a,low,i-1);//对左端子集合递归
if(iQuickSort(a,j+1,high);//对右端子集合递归
}
publicstaticvoidmain(String[]args){
int[]test={60,55,48,37,10,90,84,36};
intn=8;
QuickSort(test,0,7);
for(inti=0;iSystem.out.print(test[i]+"");
}
}
四、归并排序
排序方法最好时间平均时间最坏时间辅助空间稳定性
归并排序O(nlog2n)O(nlog2n)O(nlog2n)O(n)稳定
Ø归并排序:
MergeSort
归并排序主要是二路归并排序。
二路归并排序的基本思想是:
设数组a中存放了n个数据元素,初始时我们把它们看成是n个长度为1的有序子数组,然后从第一个子数组开始,把相临的子数组两两合并,得到n/2个(若n/2为小数则上取整)长度为2的新的有序子数组(当n为奇数时最后一个新的有序子数组的长度为1);对这些新的有序子数组再两两归并;如此重复,直到得到一个长度为n的有序数组为止。
多于二路的归并排序方法和二路归并排序方法类同。
publicclassMergeSort{
publicstaticvoidmerge(int[]a,int[]swap,intk){
intn=a.length;
intm=0,u1,l2,i,j,u2;
intl1=0;//第一个有序子数组下界为0
while(l1+k<=n-1){
l2=l1+k;//计算第二个有序子数组下界
u1=l2-1;//计算第一个有序子数组上界
u2=(l2+k-1<=n-1)?
l2+k-1:
n-1;//计算第二个有序子数组上界
for(i=l1,j=l2;i<=u1&&j<=u2;m++){
if(a[i]<=a[j]){
swap[m]=a[i];
i++;
}else{
swap[m]=a[j];
j++;
}
}
//子数组2已归并完,将子数组1中剩余的元素存放到数组swap中
while(i<=u1){
swap[m]=a[i];
m++;
i++;
}
//子数组1已归并完,将子数组2中剩余的元素存放到数组swap中
while(j<=u2){
swap[m]=a[j];
m++;
j++;
}
l1=u2+1;
}
//将原始数组中只够一组的数据元素顺序存放到数组swap中
for(i=l1;iswap[m]=a[i];
}
publicstaticvoidmergeSort(int[]a){
inti;
intn=a.length;
intk=1;//归并长度从1开始
int[]swap=newint[n];
while(kmerge(a,swap,k);//调用函数merge()
for(i=0;ia[i]=swap[i];//将元素从临时数组swap放回数组a中
k=2*k;//归并长度加倍
}
}
publicstaticvoidmain(String[]args){
int[]test={72,73,71,23,94,16,5,68,46};
;
intn=test.length;
mergeSort(test);
for(inti=0;iSystem.out.print(test[i]+"");
}
}
五、基数排序
排序方法最好时间平均时间最坏时间辅助空间稳定性
基数排序O(mn)O(mn)O(mn)O(n)稳定
基数排序算法的基本思想是:
设待排序的数据元素是m位d进制整数(不足m位的在高位补0),设置d个桶,令其编号分别为0,1,2,…,d-1。
首先按最低位(即个位)的数值依次把各数据元素放到相应的桶中,然后按照桶号从小到大和进入桶中数据元素的先后次序收集分配在各桶中的数据元素,这样就形成了数据元素集合的一个新的排列,我们称这样的一次排序过程为一次基数排序;再对一次基数排序得到的数据元素序列按次低位(即十位)的数值依次把各