第二章:排序算法 及其他 Java代码实现

第二章:排序算法 及其他 Java代码实现

——算法导论(Introduction to Algorithms, Third Edition)

插入排序

//打印输出数组模块
public class PrintArrays
{
	public static void printA(int []A)
	{
		for (int aInput : A)
		{
			System.out.print(aInput+ "	");
		}
	}
}
//产生随机数组模块
import java.util.*;

public class RandomArray
{
	public static int[] randomArray( int num)
	{
		Random rad =new Random(System.currentTimeMillis());
		int array[] = new int[num];
		for (int i= 0 ; i<num ; i++)
		{
			array[i] = rad.nextInt(100);
		}
		return array;
	}
}
//正常循环迭代实现
public class InsertSort02
{
	public static void main(String args[])
	{
		int A[] = {1,9,6,8,4,5,3,7,2,0};

		for (int j= 0; j<A.length-1 ; j++)
		{
			int key =A[j+1] ;

			int i= j;
			//关键性插入
			while ((i >= 0)&&(key< A[i]))
			{
				A[i+1] = A[i];
				i--;
			}
			A[i+1] = key;
		}

		PrintArrays.printA(A);
	}
}
//递归实现
public class InsertSort03
{
	public static void main(String srgs[])
	{
		//产生随机数组
		int A[] =RandomArray.randomArray(8);
		insertSort(A, 0, A.length);
		//输出数组
		PrintArrays.printA(A);
	}

	//插入排序最后一个参数 r 为数组长度,p 为数组起始位置。
	public static void insertSort(int []A,int p, int r)
	{
		// if 用于控制递归终止
		if (r >p)
		{
			r--;
			//递归拆解
			insertSort(A ,p , r);
			
			int i = r-1;
			int key = A[r];

			//位置插入关键
			//边查找合适的插入位置,边挪动数组的元素
			while (( i>=p) && (key <A[i]))
			{
				A[i+1] = A[i];
				i--;
			}
			A[i+1] = key;
		} 
	}
}

归并排序

//常规归并排序
public class MergeSort01
{
	public static void main(String args[])
	{
		int A[] = RandomArray.randomArray(8);
		mergeSort(A, 0, A.length-1);
        //打印输出模块同上
		PrintArrays.printA(A);
	}
	//归并排序(递归调用)
	public static void mergeSort(int A[], int p, int r)
	{
		if ( r>p)
		{
			int q= (p+r-1)/2;
			//方法形参传递 为值传递 ,数组形参传递的是引用地址
			mergeSort(A, p, q);
			mergeSort(A, q+1,r);
			mergeArray(A, p, q, r);
		}
	}
	//合并子问题的解 模块
	public static void mergeArray(int A[] , int p,int q,int r) 
	{
		int n1 = q - p + 1;
		int n2 = r - q ;
		int []L = new int[n1];
		int []R = new int[n2];

		for (int i =0; i< n1 ; i++)
		{
			L[i] = A[p+i];
		}

		for (int j =0; j< n1 ; j++)
		{
			R[j] = A[q+j+1];
		}

		for (int k= 0 ,i=0 ,j=0; ((i<n1) || (j<n2))&&(k< r-p+1) ; k++)
		{
			if (i>= n1)
			{
				A[p+k] = R[j];
				j++;
			} else if(j>= n2)
			{
				A[p+k] = L[i];
				i++;
				//以上是其中一个数组遍历完的处理
			} else if ( L[i]< R[j])
			{
				A[p+k] = L[i];
				i++;
			} else{
				A[p+k] = R[j];
				j++;
			}
		}
	}
}
//归并排序与插入排序结合
public class MergeSort02
{
	public static void main(String args[])
	{
		//随机数组的产生
		int A[] = RandomArray.randomArray(128);

		PrintArrays.printA(A);
		System.out.println();

		mergeSort(A, 0, A.length-1, 4);

		//输出
		PrintArrays.printA(A);

	}
	//归并排序 参数说明:
	// p 为数组起始位置	r 为数组末尾位置		nk 为子数组插入排序长度
	public static void mergeSort(int A[], int p, int r, int nk)
	{
		int q= (p+r-1)/2;
		if ((q-p+1) > nk)
		{
			//递归分解
			mergeSort(A, p, q, nk);
			mergeSort(A, q+1,r, nk);			
		}
		 else
		 {
		 	//分治算法 解决最小的子问题
			//插入排序最后一个参数为数组长度
			InsertSort03.insertSort(A,p ,q +1);
			InsertSort03.insertSort(A,q+1 ,r+1 );
		}
		MergeSort01.mergeArray(A, p, q, r);
		//方法形参传递 为值传递 ,数组形参传递的是引用地址
		//由于 数组传递引用地址的特性,解决了分治算法的合并子答案步骤
	}
}

选择排序算法

//选择排序算法
public class SelectionAlgorithm01
{
	public static void main(String args[])
	{
		int A[] = {1,9,6,8,4,5,3,7,2,0};
		//选择算法
		//变量 min 依次提取最小值
		for ( int j=1 , k=0; j < A.length ; j++)
		{
			int min = A[j-1] ;
			int i = j;

			//变量 K 用于记录最小值的位置
			while( i < A.length)
			{
				if( min >A[i])
				{
					min = A[i];
					k = i;
				}
				i++;
			}
			A[k] = A[j-1];
			A[j-1] = min;

		}
		// 4 重复
		PrintArrays.printA(A);
	}
}

冒泡排序

public class BubbleSort
{
	//冒泡排序法
	public void maoPaoPX(int[] arryA)
	{
		//将最大的依次 冒泡到最右边
		for (var i=arryA.length; i>0;i--)
		{
			for (var j=0;j<i;j++)
			{

				if ((j+1)==arryA.length)
				{
					break;
				}
				if ( arryA[j] > arryA[j+1] )
				{
					int temp = arryA[j+1];
					arryA[j+1] =arryA[j];
					arryA[j] =temp;
				}
			}
		}
	}
}

查找算法

//查找算法
public class LinearSearch
{
	static final int  NIL = -1 ;

	public static void main(String args[])
	{
		int v = 8;
		int []A = {1,9,6,8,4,5,3,7,2,0};

		//排序
		A = InsertSort03.insertSort(A, A.length);
		PrintArrays.printA(A);
		System.out.println();
		//线性查找
		int j = linearSearch(A , v);
		System.out.println("j = "+ j);
		//二分法查找
		j= binarySearch02(A , v, 1 ,A.length ,1 ) ;
		System.out.println("j = "+ j);

		/*
		j= binarySearch(A , v , true , 0, A.length-1);
		System.out.println("j = "+ j);
		*/
	}

	//二分法查找
	public static int binarySearch02(int []A,int v , int left,int right ,int mid)
	{
		mid = (left+ right)/2;
		int aMid= mid -1;
		if (A[aMid] ==  v)
		{
			return mid;
		} else if( A[aMid] > v){
			right = mid;
		}else {
			left = mid;
		}
		return binarySearch02(A , v ,left ,right ,mid);
	}
    //线性查找
	public static int linearSearch(int []A, int v)
	{
		int i=1;
		int j=NIL;

		for (int atemp : A)
		{
			if( atemp == v)
			{
				j=i ;
			}
			i++;
		}
		return j;
	}
}

习题 2.3.7


public class BookTest2o3o7
{
	public static void main(String args[])
	{
		int A[] = {2 , 4, 5,6, 8, 10};
		int x= 17;

		System.out.println(bookTest2o3o7(A, x));
	}

	/*
		描述一个运行时间为@(nlgn) 的算法,给定n 个整数的集合S 和另一个整数X , 该算法能
	确定S 中是否存在两个元素其和刚好为x的元素。
	*/
	public static boolean bookTest2o3o7(int []A, int x)
	{
		if (A.length <=1)
		{
			return false;
		}

		int i=0;
		int j= A.length-1;
		while(i<j)
		{
			//x 与 A[i]+A[j] 比较。
			//若 x 较大,则 i 增大 ,否则 j 减小,直到 i >= j 结束循环。
			if (x ==(A[i] + A[j]) )
			{
				return true;
			} else if( x > A[i] + A[j]){
				i++;
			} else {
				j--;
			}
		}
		return false;
	}
}
posted @ 2019-11-13 17:54  房梁上的猫  阅读(141)  评论(0)    收藏  举报