排序

排序(校招准备)

  • 一、 插入排序
  • 二、选择排序
  • 三、希尔排序
  • 四、冒泡排序
  • 五、快速排序
  • 六、归并排序
  • 时间复杂度和稳定性

一、 插入排序

原理:在每次迭代过程中从输入序列中取出一个元素插入到一个有序序列中,形成新的有序序列。重复该过程,直到序列中所有元素都被取出。

优点:当需要排序的序列已经有部分排序好了,则比较适合

代码:

public static void insertionSort(int[] a) {
		 int j = 0,i = 0;
		 int n = a.length;
	     for(i = 1;i < n;i++){
	         int temp = a[i];
	         for( j = i-1 ; j >= 0 ; j--){
	             if(temp < a[j]){//只要比temp大都后移以为
	                 a[j+1] = a[j];
	             }else{
	                  break;
	             }
	         }
	         a[j+1] = temp; //此时J位置这个数是第一个比temp小的,所以J+1这个位置插入temp
	      }		
	}

二、选择排序

原理:首先找到数组中最小的那个元素,与第一个元素交换位置。再次,剩下的元素找到最小的元素,和第二个交换位置。以此类推,直到最后一个。

代码:

public static void selectionSort(int[] a) {
		int N = a.length;
		for (int i = 0; i < N; i++) {
			int min = a[i];
			for (int j = i+1;  j < N; j++) {
				if (a[j] < min) {
					min = a[j];
					int tmp = a[i];
					a[i] = a[j];
					a[j] = tmp;					
				}
			}
		}
	}

三、希尔排序

原理:插入排序外面套一个大循环

代码:

public static void shellSort(int[] a) {
		int n= a.length;	
		//嵌套一个大循环
		for (int gap = n/2; gap > 0; gap/=2) {
			//共gap个组,对每一组都执行直接插入排序
			for (int k = 0; k < gap; k++) {
				for(int i = k+gap;i < n;i+=gap){
			         int temp = a[i];
			         int j;
			         for( j = i-gap ; j >= 0 ; j-=gap){
			             if(temp < a[j]){
			                 a[j+gap] = a[j];
			             }else{
			                  break;
			             }
			         }
			         a[j+gap] = temp;
			      }
			}
		} 

四、冒泡排序

原理:依次把前length个的最大值往后放

代码:

static void bubbleSort(int[] a) {
		int temp = 0;
		for (int i = 0; i < a.length-1; i++) {
			for (int j = i+1; j < a.length-1-i; j++) {
				if(a[j]>a[j+1]) {
					temp = a[j];
					a[j] = a[j+1];
					a[j+1] = temp;
				}				
			}			
		}
	}


五、快速排序

原理
选择第一个数为p,小于p的数放在左边,大于p的数放在右边。
递归的将p左边和右边的数都按照第一步进行,直到不能递归

代码:

public class QuickSort {
    public static void quickSort(int[] arr,int low,int high){
        int i,j,temp,t;
        if(low>high){
            return;
        }
        i=low;
        j=high;
        //temp就是基准位
        temp = arr[low];
        while (i<j) {
            //先看右边,依次往左递减
            while (temp<=arr[j]&&i<j) {
                j--;
            }
            //再看左边,依次往右递增
            while (temp>=arr[i]&&i<j) {
                i++;
            }
            //如果满足条件则交换
            if (i<j) {
                t = arr[j];
                arr[j] = arr[i];
                arr[i] = t;
            }
        }
        //最后将基准为与i和j相等位置的数字交换
         arr[low] = arr[i];
         arr[i] = temp;
        //递归调用左半数组
        quickSort(arr, low, j-1);
        //递归调用右半数组
        quickSort(arr, j+1, high);
}

六、归并排序

代码:

public static void mergeSort(int[]a,int low,int high ){
		if(low<high){//递归结束条件
			int mid=(low+high)/2;
			mergeSort(a, low, mid);//左子表递归排列有序
			mergeSort(a,mid+1,high);//右子表递归排列有序
			merge(a,low,mid,high);//将两有序子表合并
		}
	}
	
	public static void merge(int []a,int low,int mid,int high){//两有序子表合并方法
		int N = a.length;
		//这里把要排序数组copy一份,用来比较,原来的数组用来保存比较后的信息
		int [] temp=new int[N];
		//注意这里copy时,下标是从low开始的,要是为了保证copy的数组下标与目标数组下标一致,这样是为了方便后面的比较的下标操作
		for(int i=low;i<=high;i++){
			//当然copy的数组保存时也可以从0开始保存,但是这样就要注意后面的比较操作时,i就不是小于mid了,而是小于mid-low,j也不是小于high,j是小于high-low
			temp[i]=a[i];
		}
		//把数组分为前后相同的两端进行比较。i指向前半段,j指向后半段,k指向要保存的位置
		int i=low,j=mid+1,k=low;
		for(;i<=mid&&j<=high;k++){//比较
			if(temp[i]<temp[j])a[k]=temp[i++];
			else a[k]=temp[j++];
		}
		while(j<=high)//若第一个表没检测完,复制
			a[k++]=temp[j++];
		while(i<=mid)//若第二个表没检测完,复制
			a[k++]=temp[i++];	
	}

时间复杂度和稳定性

时间不早了, 快些归队 o(nlog2n):快速排序、希尔排序、归并排序、堆排序
**秋招心情 不稳定,快些选堆朋友一起 **:快速排序、希尔排序、选择排序、堆排序。

你可能感兴趣的:(排序)