相关博客-排序算法2:http://blog.csdn.net/xanlv/article/details/51755718
冒泡排序算法描述:设待排序记录序列中的记录个数为n。一般地,第i趟起泡排序从1到n-i+1。依次比较相邻两个记录的关键字,如果发生逆序,则交换之。其结果是这n-i+1个记录中,关键字最大的记录被交换到第n-i+1的位置上,最多作n-1趟。
算法评价:
时间复杂度:最好情况(正序)
比较次数:n-1 (有优化时)
移动次数:0
最坏情况(逆序)
比较次数:
移动次数: T(n)=O(n²)
空间复杂度:S(n)=O(1)
选择排序算法描述:首先通过n-1次比较,从n个数中找出最小的, 将它与第一个数交换——第一趟选择排序,结果最小的数被安置在第一个元素位置上。再通过n-2次比较,从剩余的n-1个数中找出关键字次小的记录,将它与第二个数交换——第二趟选择排序。重复上述过程,共经过n-1趟排序后,排序结束。
算法评价:
时间复杂度:比较次数: T(n)=O(n²)
移动次数
最好情况:0
最坏情况:3(n-1)
空间复杂度:S(n)=O(1)
最坏情况的移动次数为 3(n-1) ,比冒泡算法更优!
public class SortMethods {
public static void main(String[] args) {
int a[]=new int[10];
for(int i=0;i<a.length;i++){
a[i]=(int)(Math.random()*100);
}
//1.1冒泡排序
// bubbleSort1(a);
//1.2优化
// bubbleSort2(a);
//2.1选择排序:类似思想,但性能不好
// selectSort1(a);
//2.2优化
// selectSort2(a);
//3.1插入排序
// insertSort1(a);
//3.2插入+二分
// binaryInsertSort2(a);
//4希尔排序
// shellSort(a);
//5快速排序
// quikSort(a,0,a.length-1);
//6归并排序
mergeSort(a,0,a.length-1);
print(a);
}
//6归并排序:将两个或两个以上的有序表组合成一个新的有序表。
private static void mergeSort(int[] a, int i, int j) {
if(j>i){
int mid=(i+j)/2;
mergeSort(a,i,mid);
mergeSort(a,mid+1,j);
int b[]=new int[a.length];
merge(a,b,i,mid,j);
copyArray(a,b,i,j);
}
}
private static void copyArray(int[] a, int[] b, int left, int right) {
for(int i=left;i<=right;i++){
a[i]=b[i];
}
}
private static void merge(int[] a, int[] b, int left, int mid, int right) {
int p=left;int r=mid+1;int k=left;
while(p<=mid && r<=right){
if(a[p]<a[r]){
b[k++]=a[p++];
}else{
b[k++]=a[r++];
}
}
if(p>mid){
for(int t=r;t<=right;t++){
b[k++]=a[t];
}
}else{
for(int t=p;t<=mid;t++){
b[k++]=a[t];
}
}
}
/*快速排序:
* 以某个记录为界(该记录称为支点或枢轴),将待排序列分成两部分:
* ①一部分: 所有记录的关键字大于等于支点记录的关键字
* ②另一部分: 所有记录的关键字小于支点记录的关键字
*/
private static void quikSort(int[] a,int left,int right) {
if(left<right){
int q=patition(a,left,right);
quikSort(a,left,q-1);
quikSort(a,q+1,right);
}
}
//找到枢轴
private static int patition(int[] a, int left, int right) {
int rand=(int)(Math.random()*(right-left))+left;
swap(a,rand,left);
int i=left;
int j=right+1;
int x=a[left];
while(true){
while(a[++i]<x&&i<=right);
while(a[--j]>x&&j>0);//while(a[--j]>x);
if(i>=j){
break;
}
swap(a,j,i);
}
swap(a,left,j);
return j;
}
//4希尔排序又称缩小增量排序,是1959年由D.L.Shell提出来的。
private static void shellSort(int[] a) {
int len=a.length;
int gap=len;
for(gap=(gap+1)/2;gap>0;){
for(int i=0;i<len-gap;i++){
for(int j=i;j<len-gap;j+=gap){
if(a[j]>a[j+gap]){
swap(a,j,j+gap);
}
}
}
if(gap>1){
gap=(gap+1)/2;
}else{
break;
}
}
}
//3.2二分插入排序
private static void binaryInsertSort2(int[] a) {
int len=a.length;
for(int i=0;i<len-1;i++){
int temp=a[i+1];//待插入的数
int low=0;
int high=i;
int mid;
while(high>=low){
mid=(high+low)/2;
if(a[mid]>temp){
high=mid-1;
}else{
low=mid+1;
}
//low=high+1
// for(int j=i+1;j>high+1;j--){
// a[j]=a[j-1];
// }
for(int j=i;j>high;j--){
a[j+1]=a[j];
}
a[high+1]=temp;// a[low]=temp;
}
}
//3.1直接插入排序
public static void insertSort1(int[] a) {
int len=a.length;
for(int i=0;i<len-1;i++){
int temp=a[i+1];
int j=i;
while(a[j]>temp){
a[j+1]=a[j];
j--;
if(j<0){
break;
}
}
a[j+1]=temp;
}
}
//2.2选择排序优化
private static void selectSort2(int[] a) {
int len=a.length;
for(int i=0;i<len-1;i++){
int k=i;
for(int j=i+1;j<len;j++){
if(a[k]>a[j]){//标记最大数的位置
k=j;
}
}
if(k!=i){
swap(a,k,i);//每轮只交换一次,节约时间
}
}
}
//2.1选择排序
private static void selectSort1(int[] a) {
int len=a.length;
for(int i=0;i<len-1;i++){
for(int j=i+1;j<len;j++){
if(a[i]>a[j]){
swap(a,i,j);
}
}
}
}
//1.2冒泡优化
private static void bubbleSort2(int[] a) {
int len=a.length;
for(int i=0;i<len-1;i++){
boolean isOk=true;
for(int j=0;j<len-i-1;j++){
if(a[j]>a[j+1]){//当一轮循环并没有交换,说明此序列已排好序,接下来不需要排序
swap(a,j,j+1);
isOk=false;
}
}
if(isOk){
break;
}
}
}
//1.1冒泡排序
private static void bubbleSort1(int[] a) {
int len=a.length;
for(int i=0;i<len-1;i++){
for(int j=0;j<len-i-1;j++){
if(a[j]>a[j+1]){
swap(a,j,j+1);
}
}
}
}
private static void swap(int[] a, int i, int j) {
int t=a[i];
a[i]=a[j];
a[j]=t;
}
private static void print(int[] a) {
for(int num:a){
System.out.print(num+" ");
}
}
}