快速排序一种易于理解的方式实现

看来网上的一些快速排序的例子,发现好多都是代码比较多且不好理解,所以想自己总结一遍这样的博文

来分析快速排序,贴出了java实现的代码,用其他语言实现只要稍作修改就行。

s[]={48,89,34,55,11,56,89,96,10};

以数组s[]为实例来剖析快速排序代码的原理:


数组的初始太:选48做基准数,对数组进行填坑挖数操作

X=s[0],i=0,j=8

488934551156899610



2.从最右边开始向左找一个小于48的数,并在此处挖一个坑(挖坑处用红色的00表示)
X=48,i=0, j=8
将a[j]的值填到a[i]处(a[i]=a[j]),并在i处挖一个坑(挖坑处用红色00表示)
108934551156899600


3.从最左边开始向右找一个大于48的数
X=48,i=1, j=8
将a[i]的值填到a[j]处(a[j]=a[i]),并在i处挖一个坑(挖坑处用红色00表示)
100034551156899689


类似的进行步骤2,后得
X=48,i=1, j=4

101134550056899689



类似的进行步骤3,后得
X=48,i=3, j=4
101134005556899689


再进行2步骤发现i=j=3,令a[3]=48;得数组

101134485556899689

此时对数组:使用分治法思想(观察数组知道,经过填坑挖数操作后的数组有以下特征:
以48为分界线,48左边的数都小于48,48右边的数都大于48)
将数组分为
101134

5556899689



,然后对两个子数组分而治之:就是对子数组分别做填坑挖数的操作,之后又会产生4个子数组,
直到子数组子只含有一个元素,停止划分。(很容易看出子数组和原数组都在调用填坑挖数的

操作,从而看出这里有一个递归的思想,所以想到递归的办法)


/**

 * @author 源泉之志
 * 快速排序:填坑挖数+分治法
 * 快速排序一种易于理解的方式实现
 * Divide-and-ConquerMethod
 *
 */
public class QuickSort {


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub


		int s[]={48,89,34,55,11,56,89,96,2};
		QuickSort qs = new QuickSort();
		qs.quick_sort(s, 0, s.length-1);
		System.out.println("输出数组");
		for(int i=0;i<s.length;i++){
			System.out.print(s[i]+" ");
		}
	}
	
	
	/**
	 * 填坑挖数的代码
	 * @param s
	 * @param l
	 * @param r
	 * int i=l,  j=r;
	 * 1.选一个基准量,X=s[i]
	 * 2.从s[j]处开始从右往左找,找到第一个小于X的值,找到后把s[j]的值赋给s[i]
	 * 3.从s[i]处开始从左往右找,找到第一个小于X的值,找到后把s[i]的值赋给s[j]
	 * @return
	 */
	int addjustArray(int s[],int l,int r){
		int i = l, j=r;
		int x = s[i];
		while(i<j){
			while(i<j&&s[j]>=x){
				j--;
			}
			if(i<j){
				s[i]=s[j];
				i++;
			}
			while(i<j&&s[i]<=x){
				i++;
				j--;
			}
			if(i<j){
				s[j]=s[i];
			}
		}
		s[i]=x;
		
		return i;
	}
	
	
	/**
	 * @param s
	 * @param l
	 * @param r
	 * 分治法:
	 * 把一个数组以某个基准数做为界线,然后把数组一分为二 ,在把两个子数组都一分为二
	 * 当每个子数组都为一个元素时,不能在分,递归结束
	 */
	void divide_and_conquer(int s[],int l,int r){
		if(l<r){
			int i = addjustArray(s, l, r);
			addjustArray(s,l,i-1);
			addjustArray(s, i+1, r);
		}
	}
	
	
	/**
	 * 快速排序正是应用这种:填坑挖数+分之法的思想
	 * 1.选一个基准量,X=s[i]
	 * 2.从s[j]处开始从右往左找,找到第一个小于X的值,找到后把s[j]的值赋给s[i]
	 * 3.从s[i]处开始从左往右找,找到第一个小于X的值,找到后把s[i]的值赋给s[j]
	 * 
	 * 然后循环调用2,3步骤
	 * @param s
	 * @param l
	 * @param r
	 */
	void quick_sort(int s[],int l,int r){
		if(l<r){
			int i=l;int j=r;
			int x = s[l];
			while(i<j){
				while(i<r&&s[j]>=x){
					j--;
				}
				if(i<j){
					s[i]=s[j];
					i++;
				}
				while(i<j&&s[i]<=x){
					i++;
				}
				if(i<j){
					s[j]=s[i];
					j--;
				}
			}
			s[i]=x;
			quick_sort(s, j, i-1);
			quick_sort(s, i+1, r);
		}
	}
}


这是直接插入排序算法,实现原理很简单,不用细讲


package com.my.lianxi;


public class InsertionSort {

	/**
	 * @param args
	 * 插入排序算法(又称直接插入排序)
	 * 插入排序原理:
	 * 插入排序有点像摸牌   ,桌子上有n张牌背面朝上, 每次拿一张牌到手中, 当手中只有一张牌时它肯定
	 * 是手上最小的牌,当摸起第二张牌,用第二张牌和第一张比较,如果比第一张小则交换第二张牌的位置,
	 * 如果大于第一张牌则不交换,直接插在第一张牌的右边,当摸起第三张牌时先和前两张排好序的牌中的
	 * 第二张比较,如果发现比第二张小则和第二张交换位置,并继续和第一张比较,如果比第一张也小则和
	 * 第一张在交换位置,依次类推,当摸到第n张牌时和手上已经排好序的n-1张牌比较,找到第n张牌的
	 * 所需插入的位置,这样一次插入排序完成!
	 * @author yuzhihua
	 */
	public static void main(String[] args){
		int a[] = {34,12,25,54,23,66,11,89,0,90};
		int j=1;
		while(j<10){
			for(int i=j-1;i>=0;i--){
				if(a[i+1]<=a[i]){
					int temp=a[i];
					a[i]=a[i+1];
					a[i+1]=temp;
				}else{
					break;
				}
			}
			j++;
		}
		System.out.println("输出插入排序后的数组:");
		for(int i=0;i<10;i++){
			System.out.print(a[i]+" ");
		}
	}
}





评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值