一遍单向扫描法和双向扫描法

14 篇文章 0 订阅
	2020.2.20
	  17:00

在java中调用sort()方法的时候,会自动地排序好数组元素,而sort()中使用的排序是快速排序。
快速排序有两种实现的方式
①:单向扫描法
②:双向扫描法

单向扫描法

思路&过程

 思路:用两个指针将数组分成成三部分,左边的扫描指针,右边在数组末尾再定义一个指针,
 主元默认定义为数组的第一个元素,如果扫描指针指到的元素小于主元,那么元素的位置不
 动,将扫描指针继续往右边移动,如果扫到了比主元大的元素,先将此元素和右边指针指到的
 元素进行交换,再将右边的元素指针往左边移动,最终在循环结束后,右边的指针一定指向的
 是最后一个小于等于主元的元素,所以,将完成循环后的最右边的主元进行交换,再返回它,
 就得到了主元。

代码:

package LanQiaoKnowledge;

import java.util.Arrays;

public class 一遍单向扫描法快速排序 {
		//一次单向扫描法
		static void quick_sort(int arr[],int p,int r) {  //p为开始,r为末尾
					if(p<r) {
				int center=partion(arr,p,r);
				quick_sort(arr,p,center-1);
				quick_sort(arr,center+1,r);
			}
		}
		public static int partion(int arr[],int p,int r) {
		
			//头指针
			int sp=p;
			//尾指针
			int bigger=r;
			//设置头元素为主元
			int pivot=arr[p];
			while(sp<=bigger) {
				if(arr[sp]<=pivot) {		//当数组的元素小于主元的时候,sp指针往下移动,元素不动
					sp++;						//sp指针向右移动
				}else {
				swap(arr,sp,bigger);			
					//遇到数组中的元素比主元大的情况时,sp指针停止,将当前元素和末尾bigger指针指向的元素交换位置,并且bigger指针缩小,再去进行比较
					bigger--;
				}
			}
			swap(arr,p,bigger);
			return bigger;
		}
		public	static void swap(int[]arr,int a,int b) {
			
			int temp = arr[a];
			arr[a]=arr[b];
			arr[b]=temp;
								}
		
	public static void main(String[] args) {
				int []arr= {5,2,7,4,6,9,12,21};
				Arrays.sort(arr);
				System.out.println("工具类当中的快速排序:");
				for (int i = 0; i < arr.length; i++) {
				System.out.print(arr[i]+" ");
					}
				System.out.println();
				System.out.println("自己写的快速排序:");
				quick_sort(arr,0,arr.length-1);
				for (int i = 0; i < arr.length; i++) {
					System.out.print(arr[i]+" ");
				}
	}
	
	
}

双向扫描法

思路&过程

过程:在数组的开始定义一个主元,位置为p,左边定义一个扫描指针,位置为p+1,右边定义
一个指针,位置为r。				左边的指针往右边扫描,遇到比主元小的元素继续往右边扫描,
遇到比主元大的元素停止,右边的指针,从数组的末尾开始往左边扫描,扫到比主元大的元素
继续往左走,遇到小的停止。两个数调换位置   最终在最后一次交换的时候,左边的指针一定是
指向第一个大于主元的数,右边的指针指向的一定是最后一个小于等于主元的数。   所以,在最
外层的循环结束的时候,交换一下主元和右边指针指向的位置,并且,返回右边的指针,这就
是定下来的主元。

代码:

package LanQiaoKnowledge;

public class 双向扫描法快速排序 {
				//快速排序算法
		static void quicksort(int []arr,int p,int r) {
				if(p>=r) {
					return;
				}
				int pivot=partition(arr,p,r);
				quicksort(arr,p,pivot-1);
				quicksort(arr,pivot+1,r);
		} 
		//双向扫描法确定pivot
		public static int partition(int []arr,int p,int r) {
			int pivot=arr[p];
			int left=p+1;						//左边指针
			int right=r;						//右边指针
			while(left<right) {						//最外层循环的条件
				while(arr[pivot]>arr[left]&&left<right) {	//扫到比主元小的元素继续往右移动
					left++;
				}
				while(arr[right]>arr[pivot]&&left<right) {			//扫到比主元大的继续往左边扫
					right--;
				}
				if(left<right) {
					swap(arr,left,right);				//交换最终的两个左边和右边的数
					
				}
					}
			swap(arr,p,right);							//最终的右边的指针指向的是最后一个小于等于主元的数
			return arr[right];							//返回主元
		}
				//交换函数
		public static void swap(int []arr,int left,int right) {
			int temp=arr[left];
			arr[left]=arr[right];
			arr[right]=temp;
			
		}
				public static void main(String[] args) {
					int arr[]= {5,2,1,5,8,7,9,6,53};
					quicksort(arr,0,arr.length-1);
					for (int i = 0; i < arr.length; i++) {
						System.out.print(arr[i]+" ");
					}
				}
}

(这个双向扫描法在实现的时候好像出了点问题,思路就是这个思路,不知道代码哪里错了)

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值