排序算法:冒泡排序、选择排序、插入排序、快速排序、希尔排序,以及二分查找。

排序算法:

稳定排序:两个相等的元素不会交换位置 。

1、冒泡排序:时间复杂度 O(n2),相同元素的前后顺序不会改变,冒泡排序是一种稳定排序算法。

代码实现:

public static void bubbleSort(int []arr) {
        // int[] arr = {12,23,34,56,56,56,78}; // demo 数据
        for(int i =0;i<arr.length-1;i++) { 
            for(int j=0;j<arr.length-i-1;j++) {//-1为了防止溢出
                if(arr[j]>arr[j+1]) {
                    int temp = arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }    
        }
    }

2、选择排序:比较次数O(n^2),交换次数O(n),冒泡排序是一种不稳定排序算法。

代码实现:

public static void selectSort(int[]a)
{
    int minIndex=0;
    int temp=0;
    if((a==null)||(a.length==0))
        return;
    for(int i=0;i<a.length;i++)
    {
        minIndex=i;//无序区的最小数据数组下标
        for(int  j=i+1;j<a.length;j++)
        {
            //在无序区中找到最小数据并保存其数组下标
            if(a[j]<a[minIndex])
            {
                minIndex=j;
            }
        }
        //将最小元素放到本次循环的前端
        temp=a[i];
        a[i]=a[minIndex];
        a[minIndex]=temp;
    }
}

3、插入排序又可分为 直接插入排序,二分插入排序(又称折半插入排序),链表插入排序,希尔排序(又称缩小增量排序)

   时间复杂度:O(n^2),稳定排序

  1)、直接插入排序:

  代码实现:

public void zjinsert (Redtype r[],int n){
  int I,j;
  Redtype temp;
  for (i=1;i<n;i++){
    temp = r[i];
    j=i-1;
    while (j>-1 &&temp.key<r[j].key){
      r[j+1]=r[j];
      j--;
    }
    r[j+1]=temp;
  }
}

4、快速排序:是对冒泡排序的一种改进,快速排序不是稳定的排序算法

代码实现:

public void sort(int arr[],int low,int high){
   int l=low;
   int h=high;
   int povit=arr[low];

   while(l<h){
     while(l<h&&arr[h]>=povit)
     h--;
     if(l<h){
       int temp=arr[h];
       arr[h]=arr[l];
       arr[l]=temp;
       l++;
     }

     while(l<h&&arr[l]<=povit)
       l++;

     if(l<h){
       int temp=arr[h];
       arr[h]=arr[l];
       arr[l]=temp;
       h--;
     }
   }

   if(l>low)sort(arr,low,l-1);
   if(h<high)sort(arr,l+1,high);
  }

5、希尔排序:希尔排序是非稳定排序算法,是 插入排序 的一种又称“缩小增量排序”,是 直接插入排序算法 的一种更高效的改进版本。

代码实现:

void ShellPass(SeqList R,int d) {
  //希尔排序中的一趟排序,d为当前增量
  for(i=d+1;i<=n;i++) //将R[d+1..n]分别插入各组当前的有序区
    if(R[ i ].key<R[i-d].key){
      R[0]=R[i];j=i-d; //R[0]只是暂存单元,不是哨兵
      do {//查找R的插入位置
        R[j+d]=R[j]; //后移记录
          j=j-d; //查找前一记录
      }while(j>0&&R[0].key<R[j].key);
      R[j+d]=R[0]; //插入R到正确的位置上
    } //endif
  }
}

二分查找:

二分查找(折半查找),它是一种效率较高的查找方法。

但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

思想:

首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

代码实现:

public static int binarySearch(Integer[] srcArray, int des) {
    //定义初始最小、最大索引
    int low = 0;
    int high = srcArray.length - 1;
    //确保不会出现重复查找,越界
    while (low <= high) {
        //计算出中间索引值
        int middle = (high + low)>>>1 ;//防止溢出
        if (des == srcArray[middle]) {
            return middle;
        //判断下限
        } else if (des < srcArray[middle]) {
            high = middle - 1;
        //判断上限
        } else {
            low = middle + 1;
        }
    }
    //若没有,则返回-1
    return -1;
}
原文地址:https://www.cnblogs.com/mww-NOTCOPY/p/11673888.html