基本排序总结(Java 版)

快速排序

快速排序的基本思想

通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则分别对这两部分继续进行排序,直到整个序列有序。

一趟排序的过程:

用例  test:{49,38,65,97,76,13,27}

在首位定两个指针  int l=0 , int r=7

选择一个 值作为枢纽。比枢纽小的放左边,大于等于枢纽的放右边

  

   i                                     r          temp

   49  38  65  97  76  13  27            49

   从r指针开始找到比枢纽temp小的 27放左边

 

   i                                     r          temp

 27   38  65  97  76  13     27            49

   从l指针开始找到比枢纽temp大的  65放右边

               i                            r          temp

 27   38  65  97  76  13     65           49

   从r指针开始找到比枢纽temp小的  13放左边

               i                  r                 temp

 27   38  13  97  76  13     65           49

   从l指针开始找到比枢纽temp大的  97放右边

                        i             r                   temp

  27    38  13    97   76  97  65            49

   从r指针开始找到比枢纽temp小的放左边 此次并不能找到符合条件的值

                        i  r                            temp

  27    38  13    97   76  97  65            49

一趟结束 左指针等于枢纽值返回枢纽坐在位置 i

                        i  r                            temp

  27    38  13    49   76  97  65            49

此时就达到了一部分记录的关键字均比另一部分关键字小的目的

快速排序代码

	public void quick(int []array){ 
		quickSort(array,0,array.length-1);
	}



/**将整个数组排序相当于先把整个数组用quicksort排一遍
	 * 然后把数组的各个部分排一遍先是粒度大的然后粒度越来越细直到排序成功
	 * 
	 * @param res
	 * @param s
	 * @param e
	 */
	private void quickSort(int [] res,int s,int e)
	{
		if(s>=e)//如果排序部分个数在2个以下就直接返回没必要排了
		{
			return;
		}
		int mid=getMiddle(res,s,e);//先排整个
		quickSort(res,s,mid);//排左边
		quickSort(res,mid+1,e);//排右边
	}
	
private int getMiddle(int[] res, int s, int e) {
	int temp=res[s];//枢纽
	int left=s;//左指针
	int right=e;//右指针
	while(left<right)
	{
		while(left<right&&res[right]>=temp)//移动右指针找到一个比枢纽小的值
		{
			right--;
		}
		res[left]=res[right];//比枢纽小的移动到左边
		while(left<right&&res[left]<temp)//移动左指针找到比枢纽大的值
		{
			left++;
		}
		res[right]=res[left];//比枢纽大的移动到右边
	}
		res[left]=temp;//把枢纽值放回去
	return left;//返回枢纽位置
	}

插入排序

原理假定前面n个元素有序将第n+1个元素在前n个元素中找到他的位置 这样从 1重复执行到n-1就能是数组有序

我们用数组arr来模拟这一趟的过程

  index   0     1      2      3      4           5      

  value   38   49    65     97   100       50

 现在要把这个数组用插入排序的思想排好

前5个值是有序的显然我们先用一个 变量记录 要插入前面有序数组的值  temp=50

从后往前遍历


指针                                                 i 

index   0     1      2      3      4           5             temp

  value   38   49    65     97   100       70          70

arr[i-1]>temp  即arr[4]>temp 则将arr[4]后移 

指针                                                i

index   0     1      2      3      4           5             temp

  value   38   49    65     97   100      100            70

指针后移一位 arr[i-1]>temp  即arr[3]>temp 则将arr[3]后移 

指针                                     i           

index   0     1      2      3      4           5             temp

  value   38   49    65     97   97     100            70



指针后移一位 arr[i-1]<temp  此时arr[2]<temp此时找到temp插入位置 则将temp移动到arr[3]位置

指针                                  i                  

index   0        1      2         3      4           5             temp

  value   38   49    65        70     97       100            70

具体代码实现

public void directInsertSort(int []array){  
		int temp;
		for(int i=1;i<array.length;i++)//从第1个位置开始往前插入数字
		{
			temp=array[i];//当前待插入数字
			for(int j=i;j>0;j-- )//从后往前遍历有序数组找到插入位置
			{
				
				if(array[j-1]>=temp)//如果先一个数字比待插入数字大则把前一个数字移动到当前位置
				{
					array[j]=array[j-1];
				}
				else//如果前一个数字小于待插入数字则该位置为可插入位置
				{
					array[j]=temp;
					break;
				}
			}
		}
选择排序

基本思想:

    第一趟比较找出1-n最小数字排第一位;

    第二趟比较找出2-n最小数字排第二位;

    重复执行最后数组排序完成

public void simpleSelectSort(int []array)
	{
		
		int min;
		int index=0;
		for(int i=0;i<array.length-1;i++)
		{
			min=array[i];
			for(int j=i;j<array.length;j++)
			{
				if(array[j]<min)
				{
					min=array[j];
					index=j;
				}
			}
			swap(array,i,index);
		}
	}

冒泡排序:

public void bubSwapSort(int []array)
	{ 
		
	
		for(int i=0;i<array.length;i++)
		{
			
			for(int j=i;j<array.length-i-1;j++)
			{
				if(array[j]>array[j+1])
				{
					swap(array,j,j+1);
				}
			}
			
		}
	}	

堆排序 这个直接看资料吧 堆排序  图解堆排序

归并 归并

桶排序 桶排

基数排序

原理     测试数字  test{12,13,32,2,100}

创建 0,1,2,3四个桶   最大数字100的位数为3 所以要排三次

第一次比较个位 个位数字的值即为应放入桶的编号

            桶0             桶1             桶2      桶3

             100                                12        13

                                                    32

                                                     2

把桶中的数字依次拿出来放回test

test{100,12,32,2,13}

第二次比较十位 十位数字的值即为应放入桶的编号

            桶0             桶1             桶2      桶3

             100               12                        32

               2                13                                           

                                                    

把桶中的数字依次拿出来放回test

test{100,2,12,13,32}

第三次比较百位 百位数字的值即为应放入桶的编号

            桶0             桶1             桶2      桶3

             2               100                        

             12                                                         

             13

             32                                    

把桶中的数字依次拿出来放回test

test{2,12,13,32,100} 排序完毕

代码实现

	public void BasicSort(int[] array)
	{
		ArrayList<ArrayList<Integer>> bult = new ArrayList<>();
		//初始化10个桶0-9
		for(int i=0;i<=9;i++)
		{
			bult.add(new ArrayList<Integer>());
		}
		int max=array[0];//找到最大值 
		for(int i=0;i<array.length;i++)
		{
			if(array[i]>max)
			{
				max=array[i];
			}
		}
		
		int times=0;//因为是从低位排到高位最大值位数决定了要排几次
		while(max>0)
		{
			max/=10;
			times++;
	
		}
		
		for(int i=0;i<times;i++)//最大数字的位数决定了要排几次
		{
			for(int j=0;j<array.length;j++)
			{
				int index= (array[j]%(int)Math.pow(10, i+1))/(int)Math.pow(10, i);//娶得对应位数的数字即为此时排序的桶位置
				bult.get(index).add(array[j]);//把数字加到此次排序对应的桶中
				
			}
			//把桶中排好的数字放回数组
			int count=0;
			for(ArrayList<Integer> list:bult)
			{
				
					while(!list.isEmpty())
					{
						array[count++]=list.remove(0);
					}
				
			}
			
			
		}//for
		
	}

参考资料:https://www.cnblogs.com/Kevin-mao/p/5903234.html

                https://www.cnblogs.com/hapjin/p/5517667.html

                https://www.jianshu.com/p/8c915179fd02






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值