排序(一)

1、冒泡排序

最大的元素放到最后,第二个元素放到倒数第二个位置

时间复杂度O(n2)

例:6 3 5 7 0 4 1 2

步骤:

1)0-n-1(整体):第一个数和第二个数比较,哪个大哪个放到后面,第二个数和第三个数比较,依次比较后,最大的数放在最后的位置

6 3 5 7 0 4 1 2

3 6 5 7 0 4 1 2

3 5 6 7 0 4 1 2

3 5 6 0 7 4 1 2

3 5 6 0 4 7 1 2

3 5 6 0 4 1 7 2

3 5 6 0 4 1 2 7

2)0-n-2:第二大的数放在整个数组倒数第二个位置

3 5 0 4 1 2 6 7

……

3)缩小范围(0-n-1、0-2、……、1)到1时,数组有序

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

2、选择排序

最小的元素放到最前面,第二小的元素放到第二个位置

时间复杂度O(n2)

例:6 3 5 7 0 4 1 2

步骤:

1)从0-n-1,选出最小的元素放到位置0上

6 3 5 7 0 4 1 2

0 3 5 7 6 4 1 2

2)从1-n-1,选出最小的元素放到位置1上

0 1 3 5 7 6 4 2

……

3)范围缩小到只剩下n-1时,有序

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

3、插入排序

时间复杂度O(n2)

向一个排好序的数组中插入

例:6 5 3 1 8 7 2 4

步骤:
1)位置0上的数和位置1上的数比较,位置1上的数若小,则交换;

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

5 6 3 1 8 7 2 4

2)位置2上的数先和位置1上的数比较,位置2上的数若小,先和位置1上的数交换,交换后,再和位置0上的数比较,小则交换

3 5 6 1 8 7 2 4

……

 

 

———————————————————————————————————————————————————————

时间复杂度O(N*logN)

4、归并排序

https://www.cnblogs.com/chengxiao/p/6194356.html

eg: 6 5 1 2 4 3 8 7

让数组中每个数单独成为长度为1的有序区间

6、5、1、2、4、3、8、7

将相邻的有序区间进行有序合并

5 6、1 2、3 4、 7 8(长度为2)

1 2 5 6、3 4 7 8(长度为4)

1 2 3 4 5 6 7 8(长度为8)

public void MergeSort(int[] a,int low,int middle,int high)
	{
		int []temp=new int[high-low+1];
		int i=low;
		int j=middle+1;
		int index=0;
		
		while(i<=middle && j<=high)
		{
			if(a[i]<=a[j])
			{
				temp[index]=a[i];
				i++;
			}
			else
			{
				temp[index]=a[j];
				j++;
			}
		}
		index++;
		
		while(i<=middle)
		{
			temp[index]=a[i];
			i++;
			index++;
		}
		while(j<high){
			temp[index]=a[j];
			j++;
			index++;
		}
		for(int k=0;k<temp.length;i++)
		{
			a[k+low]=temp[k];
		}
		
	}
	
	public void Merge(int[] a,int low,int high)
	{
		int middle=(high+low)/2;
		if(low<high)
		{
			Merge(a,low,middle);
			Merge(a,middle+1,high);
			MergeSort(a,low,middle,high);
		}
	}
	

5、快速排序

在数组中随机选一个数,小于这个数的所有元素都放在这个数左边,大于这个数的所有元素都放在这个数右边,左右递归

划分过程:

小于等于区间,初始长度为0,从左到右遍历,当前元素如果大于划分值,继续遍历下一个元素;如果当前元素小于当前元素划分值,当前数和小于等于区间的下一个数交换,小于等于区间

4 5 3 0 1 7 2 6

划分值 3 把划分值移到最后

4 5 6 0 1 7 2 3

{小于等于区间}4 5 6 0 1 7 2 3

{0} 5  6 4 1 7 2 3

{0 1} 6 4 5 7 2 3

{0 1 2}4 5 7 6 3

划分值(最后一个数)与小于等于区间下一个数交换

{0 1 2}3 4 5 7 6   O(n)

public static void QuickSort(int[] a,int start,int end)
	{
		if(start<end)
		{
			int stard=a[start];
			int low=start;
			int high=end;
			
			while(low<high)
			{
				while(low<high && stard<=a[high])
					high--;
				int temp=a[low];
				a[low]=a[high];
				a[high]=temp;

				while(low<high && stard>=a[low])
					low++;
				int temp1=a[low];
				a[low]=a[high];
				a[high]=temp1;
			}

			a[low]=stard;

			QuickSort(a,start,low);
			QuickSort(a,low+1,end);
		}
		
		
		
		
	}

6、希尔排序

插入排序改良,步长递减

例:6 5 3 1 8 7 2 4 步长为3

步骤

1)步长为3:6 5 3 不考虑

1和6(向前跳三位)比较,交换  1 5 3 6 8 7 2 4

8和5(向前跳三位)比较,不交换 1 5 3 6 8 7 2 4

7和3(向前跳三位)比较,不交换

2和6(向前跳三位)比较,交换  1 5 3 2 8 7 6 4 

2 和1(向前跳三位)比较,不交换 

4 和8(向前跳三位)比较,交换 1 5 3 2 4 7 6 8

4 和5(向前跳三位)比较,交换 1 4 3 2 5 7 6 8

2)步长为2

3)步长为1(以步长为1结束)

public static void ShellSort(int[] a)
	{
		for(int d=a.length/2;d>0;d/=2)
		{
			//遍历所有元素
			for(int i=0;i<a.length;i++)
			{
				//遍历本组元素
				for(int j = i-d ;j>=0;j-=d)
				{
					if(a[j]>a[j+d])
					{
						int temp = a[j];
						a[j]=a[j+d];
						a[j+d]=temp;
					}
				}
				
			}
		}
	}

7、堆排序

我们假设有一棵完全二叉树,在满足作为完全二叉树的基础上,对于任意一个拥有父节点的子节点,其数值均不小于父节点的值;这样层层递推,就是根节点的值最小,这样的树,称为小根堆。

同理,又有一棵完全二叉树,对于任意一个子节点来说,均不大于其父节点的值,如此递推,就是根节点的值是最大的,这样的数,称为大根堆。

大根堆

步骤:

1)建立大根堆

2)根顶元素值最大,最后一个元素和根顶元素交换

将根顶元素脱离树结构,放在数组最后一个位置

3)重新调整大根堆

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值