java 排序算法总结

一:插入排序。

      思想:第一个为一个有序数组,之后每一个都向该数组中插入,从后往前,大于待插入数字的后移。

     复杂度:插入排序是稳定的。时间复杂度O(N^2),空间负责度O(1);

public static void  sort(int[] x)
	{
		int n = x.length;
		for( int i=1; i<n; i++)
		{
			//待插入元素
			int tmp = x[i];
			int j;
			for(j=i-1; j>=0 && x[j]>tmp; j--)
				x[j+1] = x[j];
			x[j+1] = tmp;
		}
	}

 二:选择排序

     思想:第一次选择一个最小的跟第一个元素交换,第二次选择剩下里面的最小的跟第二个交换,直到都比完。

    复杂度:O(N^2),O(1)

   

public static void  sort(int[] x)
	{
		//选择排序
		int n = x.length;
		for(int i=0; i<n; i++)
		{
			int min = i;//最小的
			for(int j=i+1; j<n; j++) 
				if(x[min]>x[j])
					min = j;//下标最小的
			int tmp = x[i];
			x[i] = x[min];
			x[min] = tmp;
			
		}
	}

二元选择排序,每趟不仅选出最大的还要选出最小的,这样比较次数就少一半。

三:堆排序:初始时,把要排序的数的序列看作是一颗顺序存储的二叉树,调整它们的顺序,使之成为一个大根堆,此时根节点的值最大,把根节点和最后一个元素交换,把前面n-1个数又重排,重复第一次的操作。直到最后剩下两个,交换它们的顺序就得到了有序数组。

       时间复杂度O(nlogn)

       这个过程分为两部分。一个是建堆,一个是堆顶与最后一个元素交换。   

       参考博客: 堆排序 - 如果天空不死 - 博客园

//堆排序
	public static void maxHeap(int[] a, int start, int end)//start是开始的父亲,end是最后一个要排序的元素
	{
		//我们建的是大根堆,每次跟左右孩子里面最大的一个交换
		int left = start*2+1;
		int right = left+1;
		int tmp = a[start];
		int cur = start;
		for(; left<=end; cur=left, left=cur*2+1, right=left+1)//左节点为上一次循环中用来交换的位置,所以本次循环中将检查left为父亲的节点树是否符合大根堆
		{
			if(left<end && a[left]<a[right])
				left++;
			if(tmp>=a[left])//tmp是需要调整的数,
				break;
			else //tmp<a[left],要换位置。tmp实际上就是a[cur]的位置
			{
				a[cur] = a[left];
				a[left] = tmp;
			}
		}
	}
	
	public static void sort(int a[],int end)
	{
		int tmp;
		for(int i=end/2-1; i>=0; i--)
			maxHeap(a, i, end-1);//初始化大根堆
		
		for(int i=end-1; i>=1; i--)
		{
			//交换根节点与最后一个节点
			tmp = a[0];
			a[0] = a[i];
			a[i] = tmp;
			maxHeap(a, 0, i-1);
		}
	}

     四:交换排序之--冒泡排序:每次都把最大的冒泡到最后面。可以加个判断,如果一趟中没有交换,说明该数组已经有序,就不需要再继续扫描了。

public static void Sort(int[] x)
	{
		if(x.length==0) 
			System.exit(0);
		int n = x.length,max=0;
		for(int i=0; i<n; i++)
		{ 
			for(int j=0; j<n; j++) 
				if(x[i]<x[j])
				{
					int tmp = x[j];
					x[j] = x[i];
					x[i] = tmp;
				}
		}
	}
public static void Sort(int[] x)
	{
		if(x.length==0) 
			System.exit(0);
		boolean a=false;
		int n = x.length,max=0;
		for(int i=0; i<n; i++)
		{ 
			for(int j=0; j<n; j++) 
				if(x[i]<x[j])
				{
					int tmp = x[j];
					x[j] = x[i];
					x[i] = tmp;
					a = true;
				}
			if(!true)
				System.exit(0);
		}
	}

五:交换排序之--快速排序。借用图:选择一个基准(第一个或最后一个)每次比较之后判断放在基准的哪一边,。

    快速排序是不稳定的。复杂度O(nlog2n)

è¿éåå¾çæè¿°

    public static void quickSort(int[] nums, int left, int right){
        if(left>=right)
            return;
        int i=left, j=right;
        int temp = nums[left];
        while(i<j) {
            while(i<j && nums[j]>=temp)//必须是>=,否则相等的时候不会移动,会卡在这里
                j--;
            nums[i] = nums[j];
            while(i<j && nums[i]<=temp)
                i++;
            nums[j] = nums[i];
        }
        nums[i] = temp;
        System.out.println(Arrays.toString(nums));
        quickSort(nums, left,i-1);
        quickSort(nums,i+1,right);//i+1,不能是i,中间不能排
    }

 六:归并排序:把两个或者两个以上元素排好序,再把两个有序段排序,以此类推,直到排完。

 è¿éåå¾çæè¿°

复杂度和快排一样

	//归并排序
	public static void Sort(int a[], int begin, int end)
	{
		int mid = (begin+end)/2;
		if(begin<end)//少了这句会堆栈溢出
		{
			Sort(a, begin, mid);
			Sort(a, mid+1, end);
			Merge(a, begin, mid, end);
		}
		
	}
	public static void Merge(int a[], int begin, int mid, int end)
	{ 
		int tmp[] = new int[end-begin+1];//新的数组
		int l = begin, r = mid+1;//左右指针
		int k = 0;//新数组的指针
		while(l<=mid && r<=end)
		{
			if(a[l] > a[r])
				tmp[k++] = a[r++];
			else
				tmp[k++] = a[l++]; 
		}
		while(l<=mid) 
			tmp[k++] = a[l++]; 
		
		while(r<=end)
			tmp[k++] = a[r++];

		//把已合并的列入原数组
		for(int i=0; i<end-begin+1; i++)
			a[begin+i] = tmp[i];
		
	}

七:基数排序。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值