排序算法全解

排序算法基本知识点

数据结构:从操作角度,排序是线性结构的一种操作,待排序记录可以用顺序存储结构或链接存储结构。

排序算法的稳定性:具有相同值的记录,在排序后,相对顺序如果没有发生变化称排序算法稳定,反之,则称为不稳定。

排序的分类:内排序:在排序的整个过程中,待排序的所有记录全部被放置在内存中。

                     外排序:由于待排序记录太多,不能同时放置在内存,而需要将一部分放置在内存中,另一部分记录放置在外存中,                                      整个排序过程需要在内外存之间多次交换数据才能得到排序的结果。

排序算法的两种基本操作:比较和移动

性能评估:时间开销和辅助存储空间

插入排序

直接插入排序

基本思想:依次将待排序序列的每一个记录插入到一个已经排好序的序列中,直到所有记录全都排好。

理解起来就是:起初已排序序列为空,你从未排序的麻袋里拿一个数,就可以直接放入已排序麻袋,而第二数拿出来之后,就不能直接扔在已排序麻袋中了,要比较一下,如果比麻袋中的那个数小,就排在他的前面,反之,放在他的后面,对于第三个数,他就遍历已排序麻袋,找到合适他的位置。

说明:插入排序在原数组中原地排序,故空留索引0处做每次记录的暂存。

                  

public int[] insertSort(int []nums)
	{
		int temp;
		for(int i=1;i<nums.length;i++)//从未排序序列中取记录
		{
			temp=nums[i];
			int j=i-1;
			for(;temp<nums[j];j--)//在已排序中找位置
			{
				nums[j+1]=nums[j];
			}
			nums[j+1]=temp;
		}
		return nums;
	}

性能评估:

最好情况:待排序序列为正序,那么每个记录只要与与已排序序列的最后一个比较,然后temp再次赋值给nums[i],比较次数n-1,移动次数2(n-1),时间复杂度为O(n)

最坏情况:待排序序列为反序,那么第i个记录要与与已排序序列比较(i-1)次,每次比较已排序序列中的一条记录就要向后移动一次,移动次数(i-1),总比较次数:(1+2+..+n-1)=n(n-1)/2;移动次数:每次除比较移动外,还有赋值temp和temp赋值给数组(3+4+...+n+1)=(n+4)(n-1)/2时间复杂度为O(n^{^{}}^2).

希尔排序

基本思想:先将整个待排序记录分割成若干个子序列,在子子序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。

分段规则:d=nums.length/2;并依次处以2缩小,当d=1时,就是对整个序列直接插入排序

	public int[] shellSort(int []nums)
	{
		for(int d=nums.length/2;d>=1;d=d/2)
		{
			for(int i=d+1;i<nums.length;i++)
			{
				int temp=nums[i];
				int j=i-d;
				for(;j>=0&&nums[j]>temp;j=j-d){
					nums[j+d]=nums[j];
				}
				nums[j+d]=temp;
			}
		}
		return nums;
	}

时间性能在:O(n^2)和O(nlog2n)之间

交换排序

起泡排序

基本思想:两两比较相邻记录的关键码,反序则交换,反之,继续。

它每一趟走下来,都可以把未排好序列中最大的换到最后。

改进:设置变量exchange记载每次记录交换的位置,则一趟排序后,exchange记载的一定时这趟排序中记录的最后一次交换的位置,从此位置之后的所有记录均已经有序。

public int[]bubbleSort(int []nums)
	{
		int temp;
		int exchange=nums.length-1;
		int bound;
		while(exchange!=0)
		{
			bound=exchange;
			exchange=0;
			for(int i=0;i<bound;i++)
			{
				if(nums[i]>nums[i+1])
				{
					temp=nums[i];
					nums[i]=nums[i+1];
					nums[i+1]=temp;
					exchange=i;
				}
				
				System.out.println(exchange);
			}
		}
		return nums;
	}

时间复杂度:O(n^2);

快速排序

在起泡排序中,记录的比较和移动是在相邻位置进行的,记录每次只能前移或后移一个位置。

	public int[]quickSort(int []nums,int start,int end)
	{
		int p=0;
		if(start<end)
		{
			p=partition(nums,start,end);
			nums=quickSort(nums, start, p-1);
			nums=quickSort(nums, p+1, end);
		}
		
		return nums;
	}
public int partition(int nums[],int start,int end)
	{
		int temp;
		while(start<end)
		{
			while(start<end&&nums[start]<nums[end])
				end--;
			if(start<end)
			{
				temp=nums[start];
				nums[start]=nums[end];
				nums[end]=temp;
				start++;
			}
			while(start<end&&nums[start]<=nums[end])
				start++;
			if(start<end)
			{
				temp=nums[start];
				nums[start]=nums[end];
				nums[end]=temp;
				end--;
			}
		}
		return start;
	}

猜你喜欢

转载自blog.csdn.net/qq_33420835/article/details/81902966