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);
}
}

posted on 2016-01-10 21:09  一棵树2016  阅读(2602)  评论(0编辑  收藏  举报