java中的各种排序案例

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、插入排序

1、基本思想

插入排序(以升序为例)的基本操作是将一个数插入到一个已经排好序的数据序列中,插入后的数据序列是有序的并且元素个数加一。插入排序的主要思想是:

假设要排序的数组为A[]元素个数为n,将这个数组分为两个部分前n-1个元素和最后一个元素,将最后一个元素插入到已经排好序的n-1个元素中的合适的位置。

InsertSort(A[n]) //对A[n]进行插入排序

{

for i=1 to n

divide(A[i-1],a[i]) //将A[i]分为两部分,前i-1个元素和最后一个元素

Insert(a[i],A[i-1])//将最后一个元素插入到排好序的前i-1个元素中

}

2、算法复杂度分析

插入排序存在着最好情况和最坏情况,最好的情况是已经是排好序的了,这时只需比较n-1次即可;最坏的情况是序列是降序的需要排成升序的,那么此时就需要比较n(n-1)/2。插入排序的赋值操作是比较操作的次数加上n-1次。平均来说插入排序的算法复杂度为O(n2)。

3、编程实现

public static void InsertSort(int[] A){

for(int i=1;i

int temp=A[i];//存储要插入的元素

int j=i;

//将temp与A[j-1]中的数进行比较,插入到合适的位置

while(j>0&&A[j-1]>=temp){

A[j]=A[j-1];

j--;

}

A[j]=temp;

}

}

二、冒泡排序

1、基本思想

冒泡排序(以升序为例)的基本思想是:依次比较相邻的两个数,将小数放在前面,大数放在后面,第一轮比较后,最大的数便被放到了最后;第二轮操作前n-1个数据(假设有n个数据),依然是依次比较相邻的两个数,将小数放在前面,大数放在后面,倒数第二个数便是第二大的数;同理第i轮操作前n-i+1的数据(假设i取值是从1开始的),则n-i+i位置上的数据为第i大的数据。一共有n-1轮,第i轮比较中共比较n-i次比较。

BubbleSort(A[n])

{

for(i=1;i

for(j=0;j

if(A[j]>A[j+1]) A[j]?A[j+1];//交换次序

}

2、算法复杂度分析

一共有次比较,最好情况下没有赋值运算,而最坏的情况下有3次赋值运算,因此该算法复杂度为O(n2)。

3、编程实现

排序后的结果为升序

public static void BubbleSort(int[] A){

int temp=0;

for (int i = 1; i < A.length ; i++) {

for (int j = 0; j < A.length - i ; j++){

//将大数往后放

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

temp=A[j];

A[j]=A[j + 1];

A[j + 1]=temp;

}

}

}

}

4、改进的冒泡排序算法

若冒泡排序在某轮循环中已经排好了序,此时就不需要进行下一轮的循环。因此改进的方法是对在比较中是否发生数据交换进行标识。如设置一个布尔量flag,进行比较前将其值设置为true,若发生了数据交换则将flag设置为false,一轮比较完成后,判断flag的值为true 则结束排序,否则进行下一轮的比较。

改进后的冒泡排序时间复杂度为O(n2)。

public static void BubbleSort(int[] A){

int temp=0;

for (int i = 1; i < A.length &&flag=false; i++) {

boolean flag=true;

for (int j = 0; j < A.length - i +1; j++){

//将大数往后放

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

temp=A[j];

A[j]=A[j + 1];

A[j + 1]=temp;

flag=false;

}

}

}

}

三、堆排序

1、基本思想

堆排序的基本思想是:首先将待排序的记录序列构造成一个堆,这时堆的头结点既是最大元素,将其和最后一个记录交换;然后将除了最后一个记录的记录序列再调整成堆,这样就找出了次大的元素,以此类推,直到堆中只有一个记录为止。

调整堆的思想是将待调整的结点的左右孩子进行比较选出较大的一个和待调整结点进行比

较,若待调整结点小则交换,否则调整结束。

创建堆得思想是从第n个结点的父结点开始到第1个结点逐个扫描,每一次扫描将以当前结点为根的子树转换成堆。

HeapSort(A)

{

MakeHeap(A)//构造出一个堆

for j←n down to 2 do

Swap(A[1],A[j])//交换头结点和最后一个记录

Siftdown(A[1,……,int((j-1)/2)] ,1)//调整堆

end for

}

Siftdown(H,i)

{

if 2i>n then exit //若下到了叶子结点则退出

repeat i←2i

//寻找待下移结点的左右孩子中较大的一个

if i+1<=n and H[i+1]>H[i] then

i←i+1

end if

//若待下移结点比左右孩子中较大的一个小则交换

if H[int(i/2)]

Swap(H[int(i/2)],H[i])

else break //若待下移结点比左右孩子大则调整结束

end if

}

MakeHeap(A)

{ i←n //总共有n个元素

m←int(i/2)

for j←m down to 1 //从第n个元素的父结点开始到第1个元素

do Sift-down(A[m,m+1,……,n],i) //即父结点小于孩子结点则进行交换

end for

}

2、算法复杂度分析

堆排序的时间复杂度主要有构造堆和调整堆这两部分的时间复杂度构成,构造堆的时间复杂度在最坏的情况下是O(n),调整堆的时间复杂度为O(log2n)。因此堆排序的大致时间复杂度可以写成O(n)+(n-1)(1+O(log2n)),即时间复杂度为O(nlog2n)。

3、编程实现

public static void HeapSort(int[] A){

//MakeHeap(A)将数组A构建成堆

for(int i=A.length/2;i>0;i--)

Siftdown(A,i,A.length);//数组A,要下移的元素为A[i]

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

//交换头结点和最后一个元素

int temp=A[1];

相关文档
最新文档