Java与算法一.docx

上传人:b****5 文档编号:2775721 上传时间:2022-11-15 格式:DOCX 页数:21 大小:329.45KB
下载 相关 举报
Java与算法一.docx_第1页
第1页 / 共21页
Java与算法一.docx_第2页
第2页 / 共21页
Java与算法一.docx_第3页
第3页 / 共21页
Java与算法一.docx_第4页
第4页 / 共21页
Java与算法一.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

Java与算法一.docx

《Java与算法一.docx》由会员分享,可在线阅读,更多相关《Java与算法一.docx(21页珍藏版)》请在冰豆网上搜索。

Java与算法一.docx

Java与算法一

Java与算法

(一)

一冒泡排序

冒泡排序法的原理是,每次比较相邻的两个元素,如果它们的顺序错误就把它们交换过来。

例如对4362715这7个数字进行从小到大的排序,从最左侧开始,首先比较4和3

例如对4362715这7个数字进行从小到大的排序,从最左侧开始,首先比较4和3

因为是从小到大排序,4和3的顺序显然是错误的,交换他们,得到

接下来比较4和6

顺序是正确的,不需要任何操作。

接下来进行下一步,比较6和2

6显然应该排在2的后面,怎么办?

交换它们,得到

经过前面几步,已经可以总结出规律,那么接下来要做的比较依次是:

7>1?

得到3426175

7>5?

得到

到此,7的右边已经没有数可以比较,第一轮排队结束。

经过这一轮,已经成功的把最大的数,即7放在了最后。

但是前面6个数的顺序还是不对,但是按照上面的思路很容易想到,对前面6个数再来一遍,即可把6放到倒数第二的位置。

然后再对前面5个数重复逐个比较的步骤。

7个数字需要进行7-1=6次排队,每完成一轮排队,下一轮排队需要比较的数字个数减1,来看代码

[java]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

publicclassBubbleSort{

publicvoidsort(int...numbers){

//n个数执行n-1轮

//每一轮后完成一个数字归位,下一轮要比较的数字个数减1(所以内层循环是j

intn=numbers.length-1;

intt;

for(inti=0;i

for(intj=0;j

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

t=numbers[j];

numbers[j]=numbers[j+1];

numbers[j+1]=t;

}

}

}

}

}

测试

[java]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

publicstaticvoidmain(String[]args){

int[]numbers=newint[]{4,3,6,2,7,1,5};

System.out.print("before:

");

for(inti=0;i

System.out.print(numbers[i]+"");

}

System.out.println();

newBubbleSort().sort(numbers);

System.out.print("after:

");

for(inti=0;i

System.out.print(numbers[i]+"");

}

System.out.println();

}

输出

[java]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

before:

4362715

after:

1234567

冒泡排序的核心是两层嵌套的循环,时间复杂度是O(N^2),即对N个数排序,需要近似执行N的平方次。

因为效率较低,实际开发中基本不会使用,但是因为简单易懂通常做为学习算法的入门案例。

如果用上面的代码对1234567做从小到大排列,会发现虽然数字已经排列好,但是程序还是要忠实的执行完全部两层循环。

对这种情况,我们可以引入一个变量来记录一次内层循环中交换数字的个数,如果交换个数为0,则提前终止循环,在某些情况下可以提高效率。

[java]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

publicvoidbetterSort(booleandescend,int...numbers){

System.out.print("before:

");

for(inti=0;i

System.out.print(numbers[i]+"");

}

System.out.println();

//n个数执行n-1轮

//每一轮后完成一个数字归位,下一轮要比较的数字个数减1(所以内层循环是j

intn=numbers.length-1;

intt;

intflag=0;

for(inti=0;i

for(intj=0;j

if(descend){//从大到小

if(numbers[j]

t=numbers[j];

numbers[j]=numbers[j+1];

numbers[j+1]=t;

flag=1;

}

}else{

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

t=numbers[j];

numbers[j]=numbers[j+1];

numbers[j+1]=t;

flag=1;

}

}

}

if(flag==0){

break;

}else{

flag=0;

}

}

System.out.print("after:

");

for(inti=0;i

System.out.print(numbers[i]+"");

}

System.out.println();

}

增加一个变量需要额外占用内存空间,因此,这个方法是以空间换时间。

二快速排序

快速排序的基本思路是,每次选定数列中的一个基准数,将小于基准数的数字都放到基准数左边,大于基准数的数字都放到基准数右边。

然后再分别对基准数左右的两个数列分别重复以上过程。

仍以4362715为例。

选定最左侧数字4为基准数,首先从右开始向左找小于4的数,找到第一个数1后停止。

然后从左开始向右找到第一个大于4的数,即6。

交换这两个数的位置,得到

继续寻找,仍然从右边开始,从上一步找到1的位置向左寻找小于4的数,找到2停止。

然后从左边找到6的位置向右找大于4的数。

右移一格后,和右侧来的“探路者”相遇了,这意味着这一轮排序结束。

最后把结束位置的数和基准数交换

观察完成后的数列,可以看到以基准数4为分界线,左边的数全都比4小,右边的数全都比4大。

接下来分别对左边的231和右边的765重复上面的排序步骤。

231

以2为基准数->213->123

765

以7为基准数->567

我们例子中的数字较少,如果数列足够长,对第一次排序后得到的子数列排序,将再得到两个子数列,然后再一分为二、二分为四。

直到以基准数拆分后两边都只剩下一个数字。

首先来看递归形式的实现代码

[java]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

publicclassQuickSort{

publicvoidsort(intleft,intright,int...numbers){

if(left>=right){

return;

}

inttemp=numbers[left];

intt=0;

inti=left;

intj=right;

while(i!

=j){

//先从右往左找

while(numbers[j]>=temp&&i

j--;

//再从左往右找

while(numbers[i]<=temp&&i

i++;

//交换两个数在数组中的位置

if(i

t=numbers[i];

numbers[i]=numbers[j];

numbers[j]=t;

}

}

//将基准数归位

numbers[left]=numbers[i];

numbers[i]=temp;

sort(left,i-1,numbers);

sort(i+1,right,numbers);

}

}

测试代码

[java]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

publicstaticvoidmain(String[]args){

int[]numbers=newint[]{4,3,6,2,7,1,5};

newQuickSort().sort(0,numbers.length-1,numbers);

System.out.print("after:

");

for(inti=0;i

System.out.print(numbers[i]+"");

}

System.out.println();

}

输出

[java]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

after:

1234567

另一种实现方式是使用栈代替递归

[java]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

publicvoidsortWithoutRecursion(intleft,intright,int...numbers){

LinkedListstack=newLinkedList<>();

intindex;

stack.push(left);

stack.push(right);

while(!

stack.isEmpty()){

right=stack.pop();

left=stack.pop();

index=partition(left,right,numbers);

if(left

stack.push(left);

stack.push(index-1);

}

if(right>index+1){

stack.push(index+1);

stack.push(right);

}

}

}

publicintpartition(intleft,intright,int...numbers){

inttemp

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > IT认证

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1