java 排序算法

1.插入排序

      插入排序较为简单,时间复杂度为O(n^2) 

      对于数组的插入排序,只需要在待插入元素处向前遍历,通过比较判断是否可以插入即可

      对于实现链表的插入排序,不妨设置一个前驱节点(即在head节点前设置一个节点),方便在头结点之前进行统一

的插入操作,在每次插入一个元素时,从前驱节点开始向前遍历,待插入节点与遍历的下一个节点判断是否需要插入

 

     //插入排序
public void insertSort(int [] arr) {
           int tmp = 0;
		 for(int i = 0;i<arr.length-1;i++) {
            //从插入元素处向前遍历
			 for(int j = i+1;j>0;j--) {
                //交换
				 if(arr[j] < arr[j-1]) {
					 tmp = arr[j];
					 arr[j] = arr[j-1];
					 arr[j-1] = tmp;
				   }  else break;//跳出循环
				 }
			 }
		 }
	}
	//链表实现插入排序
	public ListNode insertSortList(ListNode head) {
		    ListNode p1 = head;
	        ListNode res = new ListNode(0);
	        ListNode p2 = res;//设置前驱节点
	        p2.next = head;
	        while (p1 != null && p1.next != null){
	            ListNode insert = p1.next;//插入的节点
	            boolean isInsert = false;//判断是否有插入
	            while (p2.next != insert){
	                //插入节点
	                if (insert.val <= p2.next.val){//保证插入节点在p2后面
	                    p1.next = insert.next;
	                    insert.next = p2.next;
	                    p2.next = insert;
	                    p2 = res;//p2重置
	                    isInsert = true;
	                    break;
	                }         
	                p2 = p2.next;
	            }
	            p2 = res;//p2重置
	            if (isInsert == false)//没有插入 节点p1 向前遍历
	            p1 = p1.next;
	        }
	        return res.next;
    }

2.希尔排序

希尔排序是在插入排序基础上进行改进的一种排序方法,又叫“缩小增量排序”

设置步长序列k,把间隔为k的元素分为一组,然后分别对其进行插入排序。当最后k为1时,也就是直接插入排序,排序完成

public static void shellSort(int [] arr, int k) {
      //k为步长序列	 
    	for(;k > 0;k = k/2) {
    		//插入排序
    		for (int i = k;i<arr.length;i++) {
    			for (int j = i;j-k >= 0;j-=k) {
    				 if (arr[j] < arr[j-k]) {
    					 int tmp = arr[j];
        				 arr[j] = arr[j-k];
        				 arr[j-k] = tmp;
    				 } else break;
    			}
    			
    		}
    	}
    }

 3.归并排序

归并排序采用分治法,时间复杂度为O(N*logN)

关键是合并两个有序数组

public void mergeSort(int [] arr, int bottom, int top) {
    	 if(bottom < top) {
    		 int middle = (bottom + top)/2;
             //将arr数组左右分开进行排序
    		 mergeSort(arr,bottom,middle);
    		 mergeSort(arr,middle+1,top);
            //合并左右有序数组
    		 merge(arr,bottom,middle,top);
    	 } else return;
     }

    //合并两个有序数组
    public static void merge(int [] arr,int bottom,int middle,int top) {
    	 int [] tmp = new int [top-bottom+1];//临时数组,用以储存合并数组
    	 int i = bottom;
    	 int j = middle+1;
    	 int k = 0;//tmp数组的下标
    	 while(i <= middle && j <= top ) {//两个数组都未遍历完
            //小的元素放入tmp中
    		 if(arr[i] <= arr[j]) {
    			 tmp[k++] = arr[i++];
    		 } else {
    			 tmp[k++] = arr[j++];
    		 }
    	 }
    	 while(i <= middle) {
    		 tmp[k++] = arr[i++];
    		  
    	 }
    	 while(j <= top) {
    		 tmp[k++] = arr[j++];
    	 }
             //将tmp中的元素复制到arr数组中
    	 for(int m = bottom;m <= top;m++)
    		 arr[m] = tmp[m-bottom];
     }

4.快速排序

与归并排序一样是采用分治法,时间复杂度为O(N*logN)

关键是每次排序设置一个枢轴元素,小于枢轴元素的元素放在其左边,大的放在右边,那么每次排序完成后枢轴元素都放在数组的正确位置

public void quickSort(int []arr,int bottom,int top) {
	if (bottom < top) {
		int partion = part(arr,bottom,top);
	    quickSort(arr,bottom,partion-1);
	    quickSort(arr, partion+1,top);
	}
	}
	public static int part(int []arr,int bottom,int top) {
		int pivot = arr[bottom];//枢轴元素,小的在左,大的在右
		while(bottom < top) {
			while (arr[top] > pivot && bottom < top)
				top--;
				arr[bottom] = arr[top];
			while (arr[bottom] <= pivot && bottom < top) 
				bottom++;
				arr[top] = arr[bottom];							
		}
		arr[bottom] = pivot;//枢轴元素在数组中排序后的正确位置
		return bottom;
	}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值