2016/1/10 三种排序方法 二分法排序 快速排序 冒泡排序
//排序和查找是数据结构与算法设计的重要内容
/*
排序主要包括
1.插入排序:又包括直接插入排序、二分法插入排序、表插入排序、Shell排序
2.选择排序:包括直接选择排序、堆排序
3.交换排序:冒泡排序、快速排序
4.分配排序:主要有基数排序
5.归并排序:主要有内排序、外排序
注:以下程序均在本人电脑上通过完整的数据测试
*/
/////////////////////////////////////////////////////////
/////////////1.冒泡排序//////////////////////////////////
/////////////////////////////////////////////////////////
/*算法分析:
依次比较相邻的两个数,将大数放在前面,小数放在后面。
即首先比较第1个和第2个数,将大数放前,小数放后。然
后比较第2个数和第3个数,将大数放前,小数放后,如此
继续,直至比较最后两个数,将大数放前,小数放后,此
时第一趟结束,在最后的数必是所有数中的最小数。重复
以上过程,仍从第一对数开始比较(因为可能由于第2个数
和第3个数的交换,使得第1个数不再大于第2个数),将大
数放前,小数放后,一直比较到最小数前的一对相邻数,
将大数放前,小数放后,第二趟结束,在倒数第二个数中得
到一个新的最小数。如此下去,直至最终完成排序。
*/
public class MaoPao {
public void BubbleSort(int a[]) {
int temp = 0;
for (int i = 0; i < a.length; i++) {
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;
}
}
}
for (int item : a) {
System.out.println(item);
}
}
public static void main(String[] args) {
MaoPao mp = new MaoPao();
int[] a = { 49, 38, 65, 97, 76, 13, 27 };
mp.BubbleSort(a);
}
}
/////////////////////////////////////////////////////////
/////////////2.快速排序//////////////////////////////////
/////////////////////////////////////////////////////////
/**算法分析:
*
* 快速排序对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的
* 两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分
* 数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
*
* 设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键
* 数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一
* 躺快速排序。一躺快速排序的算法是:
1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;
2)以第一个数组元素作为关键数据,赋值给X,即 X=A[0];
3)从J开始向前搜索,即由后开始向前搜索(J=J-1),找到第一个小于X的值,让该值与X交换;
4)从I开始向后搜索,即由前开始向后搜索(I=I+1),找到第一个大于X的值,让该值与X交换;
5)重复第3、4步,直到 I=J;
例如:待排序的数组A的值分别是:(初始关键数据:X=49)
A[0] 、 A[1]、 A[2]、 A[3]、 A[4]、 A[5]、 A[6]:
49 38 65 97 76 13 27
进行第一次交换后: 27 38 65 97 76 13 49
( 按照算法的第三步从后面开始找)
进行第二次交换后: 27 38 49 97 76 13 65
( 按照算法的第四步从前面开始找>X的值,65>49,两者交换,此时:I=3 )
进行第三次交换后: 27 38 13 97 76 49 65
( 按照算法的第五步将又一次执行算法的第三步从后开始找
进行第四次交换后: 27 38 13 49 76 97 65
( 按照算法的第四步从前面开始找大于X的值,97>49,两者交换,此时:J=4 )
此时再执行第三步的时候就发现I=J,从而结束一躺快速排序,那么经过一趟快速排序之后的结果是:
27 38 13 49 76 97 65,即所以大于49的数全部在49的后面,所以小于49的数全部在49的前面。
快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分
进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列变成一个有序的序列,
根据这种思想对于上述数组A的快速排序的全过程如图6所示:
初始状态 {49,38,65,97,76,13,27}
进行一次快速排序之后划分为 {27 38 13} 49 {76 97 65}
分别对前后两部分进行快速排序 {27 38 13} 经第三步和第四步交换后变成 {13 27 38} 完成排序。
{76 97 65} 经第三步和第四步交换后变成 {65 76 97} 完成排序。
*
*/
public class QuickSort {
public int partition(int[] a, int i, int j) {//分割排序
int key = a[i];
while(i < j) {
while(i < j && a[j] >= key) //找出第一个比key小,并记下j值
j--;
a[i] = a[j];//将a[j]移至a[i]处
while(i < j && a[i] <= key)//找出第一个比key大,并记下i值
i++;
a[j] = a[i];//将a[i]移至a[j]处
}
a[i] = key;//此时完成一趟排序
return i;//此时i=j,记下i的值
}
public void sort(int[] a, int i, int j) {//递归调用分割
if(i < j) {
int n = partition(a,i,j);//排一次序列,并获取关键值的位置
sort(a,i,n-1);//左递归
sort(a,n+1,j);//右递归
}
}
public static void main(String[] args) {
int[] a = {49,38,65,97,76,13,27};
new QuickSort().sort(a, 0, 6);
for(int item : a) {
System.out.println(item);
}
}
}
/////////////////////////////////////////////////////////
/////////////3.折半(二分)法查找////////////////////////
/////////////////////////////////////////////////////////
/**算法分析
*
* 将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,
* 即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中
* 点元素,则将待查序列缩小为左半部分,否则为右半部分。通过一次
* 比较,将查找区间缩小一半。
折半查找是一种高效的查找方法。它可以明显减少比较次数,提高查
找效率。但是,折半查找的先决条件是查找表中的数据元素必须有序。
* 虽然二分(折半)查找的效率高,但是要将表按关键字排序。而排序本身是一
* 种很费时的运算。即使采用高效率的排序方法也要花费 O(n lg n)
* 的时间。
二分查找只适用顺序存储结构。为保持表的有序性,在顺序结构里插
入和删除都必须移动大量的结点。因此,二分查找特别适用于那种一经建
立就很少改动、而又经常需要查找的线性表。
对那些查找少而又经常需要改动的线性表,可采用链表作存储结构,
进行顺序查找。链表上无法实现二分查找
*/
import java.util.Arrays;
public class Search{
public void HalfSearch(int[] a, int b) {
Arrays.sort(a);//系统排序
int low = 0;
int high = a.length - 1;
int mid = (low + high) / 2;
while ((mid != low) && (mid != high)) {
if (b <= a[mid]) {
high = mid;
mid = (low + high) / 2;
}
else {
low = mid;
mid = (low + high) / 2;
}
}
if ((b == a[low]) || (b == a[high])) {
System.out.println(b + "在数组a中");
}
else {
System.out.println(b + "不在数组a中");
}
}
public static void main(String[] args){
Search s=new Search();
int[] a={11,41,17,18,14,16,20,45};
s.HalfSearch(a,20);
}
}