Java常见排序算法题:冒泡排序,选择排序,插入排序,快速排序,希尔排序,堆排序和合并排序)

在面试中经常会遇到机试,而机试中很有可能考到基本的排序算法题

排序算法:

  1. 冒泡排序
    特点:效率低,实现简单
    基本思想:
    对比相邻的元素值,如果满足条件就交换元素值,把比较小的元素移动到数组前面,把比较大的移动到数组后面。
public class Demo {
    public static void main(String[] args) {

        int[] arra = { 1, 9, 6, 8, 5, 65, 65, 84, 1, 2, 5, 23, 7, 889 };
        //使用两个for循环遍历
        for (int i = 0; i < arra.length - 1; i++) {
            for (int j = 0; j < arra.length - i - 1; j++) {	//减i是为了防止输出已经比较好的
                if (arra[j] > arra[j + 1]) {//如果前面的数大于后面的数,则进行前后相邻元素交换
                    int temp = arra[j];
                    arra[j] = arra[j + 1];
                    arra[j + 1] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(arra));

    }

}

  1. 选择排序
    特点:效率低,容易实现
    基本思想:
    将指定排序位置与其他数组元素分别对比,如果满足条件就交换元素值即把满足条件的元素与指定位置的排序位置交换.
    也可以这样理解:每一趟从待排序序列选择一个最小的元素放到已排好序的序列的末尾,剩下的为待排序序列,重复上述步骤,直到完成排序.
public static void main(String[] args) {
		int[] array = { 63, 4, 24, 1, 3, 15 };
        int index;
        for (int i = 1; i < array.length; i++) {
            index = 0;
            for (int j = 1; j < array.length-i; j++) {
                if (array[j]>array[index]){
                    index = j;
                }
            }
            int temp = array[array.length-i];
            array[array.length-i] = array[index];
            array[index] = temp;
        }
        System.out.println(Arrays.toString(array));
 }      
  1. 插入排序
    特点:效率低,容易实现
    基本思想:
    将数组分为两部分,将后部分的元素逐一与前部分元素比较,如果前部分元素比array[i]小,就将前部分的元素往后移动.当没有比array[i]小的元素,即是合理位置,在此位置插入array[i]
    还可以理解为:先从数组中取出前两个数据,比较。在依次取出一个,与前两个比较比某个数大的放右边,比其小的放左边
 public static void main(String[] args) {
		int[] array = { 56, 5, 185, 56, 8, 646, 589, 63, 846, 351656, 6516, 654465 };
        int i,j,t = 0;
        for ( i = 1; i < array.length; i++) {
            t = array[i];
            j = i - 1;
            while (j >= 0 && t < array[j]){
                array[j+1] = array[j];
                j--;
            }
            //插入array[i]
            array[j+1] = t;
        }
        for (int q = 0; q < array.length; q++) {
            System.out.println(array[q]+" ");
        }
 }      
  1. 快速排序
    特点:高效,时间复杂度为nlogn.
    采用分治法的思想:
    首先设置一个轴值pivot,然后以这个轴值为划分基准将待排序序列分成比pivot大和比pivot小的两部分,接下来对划分完的子序列进行快排直到子序列为一个元素为止.
    也可以这样理解:
    定一个分界值,通过该分界值将数组分成左右两部分,左边都小于分界值, 右边都大于分界值
    在递归左边,右边
 public static void quickSort(int[] s, int left, int right) {
        int f, t;
        int rtemp, ltemp;

        ltemp = left;
        rtemp = right;
        f = s[(left + right) / 2];
        while (ltemp < rtemp) {			//左边的指针小于右边的指针
            while (s[ltemp] < f) {		//从左边开始找到比中间值大的指针
                ++ltemp;
            }
            while (s[rtemp] > f) {		//从右边开始找到比中间值小的指针
                --rtemp;
            }
            if (ltemp <= rtemp) {		//如果右边开始的指针大于左边开始的指针,但左边的值大于右边,交换两处的值
                t = s[ltemp];
                s[ltemp] = s[rtemp];
                s[rtemp] = t;
                --rtemp;				//向左运动
                ++ltemp;				//向右运动
            }
        }
        if (ltemp == rtemp) {			//如果二者运动后在同一指针,左边指针后移
            ltemp++;
        }
        if (left < rtemp) {           	//如果右边指针没有遍历到最左边,递归
            quickSort(s, left, ltemp - 1);
        }
        if (ltemp < right) {			//如果左边指针没有遍历到右边,递归
            quickSort(s, rtemp + 1, right);
        }

    }
//在main方法中调用
public static void main(String[] args) {
   
        //快速排序
        int[] s = { 1, 5, 69, 5, 45, 1, 21, 23, 65, 9, 89, 87 };
        quickSort(s,0,s.length-1);
        System.out.println(Arrays.toString(s));

    }
  1. 堆排序
    堆排序思想:先将树分成两部分,左右,每一级由左到右,递增,(在同一节点下);其次在在整个树中,从下往上排序,每次取出最上面的树排在最后,递归下去,即可排序。
public static void main(String[] args) {
		int s[] = { 5, 45, 6, 5, 2, 3, 23, 6, 65, 56, 98, 9, 7, 45, 4, 52 };
		mergeSort(s, s.length);
		System.out.println(Arrays.toString(s));
	}
 
	static void mergeOne(int a[], int b[], int n, int len) {
		int i, j, k, s, e;
		s = 0;
		while (s + len < n) {			//循环
			e = s + 2 * len - 1;
			if (e >= n) {
				e = n - 1;
			}
			k = s;
			i = s;
			j = s + len;
			while (i < s + len && j <= e) {			//合并并排序
				if (a[i] <= a[j]) {			//两个数组第一位谁小谁先排,未排的元素等下次再次比较
					b[k++] = a[i++];
				} else {
					b[k++] = a[j++];
				}
			}
			while (i < s + len) {
				b[k++] = a[i++];
			}
			while (j <= e) {
				b[k++] = a[j++];
			}
			s = e + 1;
		}
		if (s < n) {
			for (; s < n; s++) {
				b[s] = a[s];
			}
		}
	}
 
	static void mergeSort(int a[], int n) {	 //开始排序
		int h, len, f;
		len = 1;
		f = 0;
		int p[] = new int[n];
		while (len < n) {					//排序次数
			if (f == 1) {					//互相交换排序
				mergeOne(p, a, n, len);
			} else {
				mergeOne(a, p, n, len);
			}
			len = len * 2;					//每次排序合并两个数组
			f = 1 - f;						//改变f的值
		}
		if (f == 1) {						//解决只有一个数的数组
			for (h = 0; h < n; h++) {
				a[h] = p[h];
			}
		}
	}

  1. 希尔排序(shell)
    Shell排序的基本思想:将n个元素分成n/2个数字序列,第1个和第n/2+1个数据为一对,每次循环使每个序列排号,再变成n/4个,再次排序。多次重复,直到序列减少到最后变成一个。
public static void main(String[] args) {
		int array[] = { 1, 5, 85, 416, 74, 123, 68, 46, 4, 68, 4, 61 };
		int j, temp;
		for (int r = array.length / 2; r >= 1; r /= 2) {
			for (int i = r; i < array.length; i++) {
				temp = array[i];
				j = i - r;
				while (j >= 0 && temp < array[j]) {
					array[j + r] = array[j];
					j -= r;
				}
				array[j + r] = temp;
			}
		}
 
		for (int i = 0; i < array.length; i++) {
			System.out.print(array[i] + " ");
		}
	}


  1. 合并排序
    合并排序思想:将1个数组分成n个元素,相邻两项比较并合并,依次2和2比较并合并

你可能感兴趣的:(算法)