交换排序:冒泡排序与快速排序
冒泡排序:废话不多说,直接上代码,注意2中冒泡方法的不同。
package com.sqtds.algorithm.sort;
/**
* User: sqtds
* Date: 13-1-15
* Time: 下午3:03
*/
public class Bubble {
public static void sort(int[] array){
int i ,j ;
for (i =0 ; i< array.length ; i++){
for(j=i ; j<array.length ; j++){
if(array[i]>array[j]){
swap(array,i,j);
}
}
}
}
public static void swap(int[] array , int left , int right){
int temp = array[left];
array[left] = array[right];
array[right] = temp;
}
public static void BubbleSort(int[] array)
{ //R(l..n)是待排序的文件,采用自下向上扫描,对R做冒泡排序
int i,j,t;
Boolean exchange; //交换标志
for(i=0;i<array.length;i++){ //最多做n-1趟排序
exchange=false; //本趟排序开始前,交换标志应为假
for(j=array.length-2;j>=i;j--) //对当前无序区R[i..n]自下向上扫描
if(array[j+1]<array[j]){//交换记录
t=array[j+1]; //R[0]不是哨兵,仅做暂存单元
array[j+1]=array[j];
array[j]=t;
exchange=true; //发生了交换,故将交换标志置为真
}
if(!exchange) //本趟排序未发生交换,提前终止算法
return;
} //endfor(外循环)
} //BubbleSort
public static void main(String args[]){
int[] array = {3,5,3,6,6,8,2,9,0};
//sort(array);
BubbleSort(array);
for(int i: array){
System.out.print(i + " ");
}
}
}
(1)初始
R[1..n]为无序区。
(2)第一趟扫描
从无序区底部向上依次比较相邻的两个气泡的重量,若发现轻者在下、重者在上,则交换二者的位置。即依次比较(R[n],R[n-1]),(R[n-1],R[n-2]),…,(R[2],R[1]);对于每对气泡(R[j+1],R[j]),若R[j+1].key<R[j].key,则交换R[j+1]和R[j]的内容。
第一趟扫描完毕时,"最轻"的气泡就飘浮到该区间的顶部,即关键字最小的记录被放在最高位置R[1]上。
(3)第二趟扫描
扫描R[2..n]。扫描完毕时,"次轻"的气泡飘浮到R[2]的位置上……
最后,经过n-1 趟扫描可得到有序区R[1..n]
快速排序:
(1) 分治法的基本思想
分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。
(2)快速排序的基本思想
设当前待排序的无序区为R[low..high],利用分治法可将快速排序的基本思想描述为:
①分解:
在R[low..high]中任选一个记录作为基准(Pivot),以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。
注意:
划分的关键是要求出基准记录所在的位置pivotpos。划分的结果可以简单地表示为(注意pivot=R[pivotpos]):
R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys
其中low≤pivotpos≤high。
②求解:
通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。
③组合:
因为当"求解"步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,"组合"步骤无须做什么,可看作是空操作。
package com.sqtds.algorithm.sort;
/**
* User: sqtds
* Date: 13-1-14
* Time: 上午10:38
*/
public class QuickSort {
/**
*
* @param array
* @param left
* @param right
*/
public static void qucikSort(int[] array,int left ,int right){
//get a number from array
//foreach array ,if the number < the last number , put the last number in the font of the number
//then sort the two array spilt by the number.
if(left<right){
int temp = array[left];
int point = left;
int j=right,i=left+1;
while(i<j){
while(j>=i&&point !=j+1){
if(array[j]<temp){
swap(array,j,point);
point = j;
}
j--;
}
while(i<=j&& point !=i-1){
if(array[i]>temp){
swap(array,i,point);
point = i;
}
i++;
}
}
for(int a:array){
System.out.print(a+" ");
}
System.out.println("");
qucikSort(array, point+1 ,right);
qucikSort(array, left ,point-1);
}
}
public static void swap(int[] array,int x, int y){
int temp = array[x];
array[x] = array[y];
array[y] = temp;
}
public static int partition(int array[],int left, int right)
{
//p <- Get a number from array
int p=array[left];
//Put elements < p to the left side
//Put elements >= p to the right side
int i=left,j;
for(j=left+1;j<=right;j++)
{
if(array[j]<p)
{
i++;
swap(array,i,j);
}
}
//Put p in the middle slot which index is pivot
swap(array,i,left);
return i;
}
public static void quicksort(int array[], int left, int right)
{
//Do nothing if left <= right
if(left<right)
{
int pivot=partition(array,left,right);
//Recursive quicksort the left parts and right parts
quicksort(array,left,pivot-1);
quicksort(array,pivot+1,right);
}
}
public static void main(String args[]){
int[] array = {4,6,2,5,1,7,5,4,3,2};
/**
* 4,6,2,5,1,7,5,4,3,2 ,i=1,j=1,p=0
* 4,6,2,5,1,7,5,4,3,2,i=1,j=2,p=0
* 2,6,4,5,1,7,5,4,3,2,i=2,j=3,p=0
* 2,6,4,5,1,7,5,4,3,2,i=2,j=4,p=0
* ...
*交换i和p
*/
qucikSort(array,0,array.length-1);
//quicksort(array,0,array.length-1);
for(int a:array){
System.out.print(a+" ");
}
}
}int Partition(SeqList R,int i,int j)
{//调用Partition(R,low,high)时,对R[low..high]做划分,
//并返回基准记录的位置
ReceType pivot=R[i]; //用区间的第1个记录作为基准 '
while(i<j){ //从区间两端交替向中间扫描,直至i=j为止
while(i<j&&R[j].key>=pivot.key) //pivot相当于在位置i上
j--; //从右向左扫描,查找第1个关键字小于pivot.key的记录R[j]
if(i<j) //表示找到的R[j]的关键字<pivot.key
R[i++]=R[j]; //相当于交换R[i]和R[j],交换后i指针加1
while(i<j&&R[i].key<=pivot.key) //pivot相当于在位置j上
i++; //从左向右扫描,查找第1个关键字大于pivot.key的记录R[i]
if(i<j) //表示找到了R[i],使R[i].key>pivot.key
R[j--]=R[i]; //相当于交换R[i]和R[j],交换后j指针减1
} //endwhile
R[i]=pivot; //基准记录已被最后定位
return i;
} //partition