DNA排序算法(一)

这是一个使用了斐波那契数列来完成排序的算法,由于使用了四条数组,我称它为DNA排序算法,
这个算法排序效率还是挺可以的,比Java 的arrays.sort()还快一些, 不过在内存占用率方面不及格;

public class DNA {
public static void main(String args[]) {
// 1,随机生成n个long范围的值,并将值存放到数组中
int n = 10000000;
long scope = 1000000000000000000L;

long[] arrA = new long[n];//0和1状态值
long[] arrT = new long[n];//锚点
long[] arrC = new long[n];//能量
long[] arrG = new long[n];//原始数据

for (int i = 0; i < n; i++) {
    long m = (long) (Math.random() * scope);
    arrG[i] = m;
}

// 4.找出数组arrM的最大值,循环之后,最大值跑到了数组的最后
long temp = 0;
for (int i = 0; i < n - 1; i++) {
    if (arrG[i] > arrG[i + 1]) {
        temp = arrG[i + 1];
        arrG[i + 1] = arrG[i];
        arrG[i] = temp;
    }
}

// 5.生成斐波那契数组,给数组arrG盖楼,long类型的数总共可以盖93层
long[] arrN = new long[93];
long a = 1, b = 1;
for (int i = 1 ; a > 0; i += 2, a += b, b += a) {
    arrN[i] = a;
    arrN[i + 1] = b;
}
//System.out.println(Arrays.toString(arrN));

// 6.确定从哪一层开始工作
int level = 0;
for (int i = 0; i < 93; i++) {
    if(arrN[92]<arrG[n-1]){
        level=92;
    }else if(arrN[i] >= arrG[n - 1]) {
        level = i-1;
        break;
    }
}

// 7.给数组arrT初始锚点,用它来分隔单元
arrT[n - 1] = 8;

// 8.复制数组
for (int i = 0; i < n; i++) {
    arrC[i] = arrG[i];
}

// 9.taget的作用是当数组arrT的状态值全部变为"8"的时候就结束楼层循环
int target=0;

// =====================开始历遍所有的楼层=======================
for (int i = level; i > 0; i--) {
    if(target==n-1){
        i=0;
        continue;
    }
    // 准备数组arrA和数组arrC的数据,与之相比,arrT的数据是渐渐积累的
    int aa = 0;
    for (int j = 0; j < n; j++) {
        arrA[j] = 0;
        if (arrC[j] >= arrN[i]) {
            arrC[j] -= arrN[i];
            arrA[j] = 1;
            aa++;
        }
    }
    if(aa == 0){//aa的作用是当arrA的值全部相同的时候,直接跳过这一层循环
        continue;
    }
    int begin = 0;
    int end = 0;
    int num = 0;
    // ------------------这是一个楼层的开始---------------------
    for (int j = 0; j < n; j++) {
        if (arrT[j] == 0) {
            num++;
            continue;
        } else if (num == 0) {
            continue;
        }
        end = j;
        begin = j - num;
        // --------------这是一个单元的开始------------------
        int mun1 = num;
        int mun2 = num;
        for (int z = begin; z <= end; z++) {
            if (arrA[z] == 0) {
                mun1--;
            }else if (arrA[z] == 1) {
                mun2--;
            }
        }
        // 如果这个单元全部是0,或全部是1,就没必要往下走了,直接跳过这个单元
        if (mun1 == -1 | mun2 == -1) {
            num=0;//重新开始循环下一个单元,num的值要恢复初始值
            continue;
        }
        /*
         * 这是一个单元中有0和1的情况,大部分情况是这样子,这是程序最繁忙的地方
         * 采用的方式是:从begin向右找"0",找到"0",就从end往左找"1",
         * "0"和"1"配对,配对成功,就调换数据,数组arrA,arrC,arrG都需要调换
         * 如此循环,直到配对失败,退出循环,然后再给数组arrT增加标记(即给下个楼层添加单元)
         */
        uu: while (begin < end) {
            if (arrA[begin] == 1) {
                while (begin < end) {
                    if (arrA[end] == 0) {
                        temp = arrG[begin];
                        arrG[begin] = arrG[end];
                        arrG[end] = temp;
                        temp = arrC[begin];
                        arrC[begin] = arrC[end];
                        arrC[end] = temp;
                        temp = arrA[begin];
                        arrA[begin] = arrA[end];
                        arrA[end] = temp;
                        begin++;
                        continue uu;
                    }
                    end--;
                }
                begin--;//配对失败,说明这个位置只能是1,而不是0,所以要减1;
            }
            begin++;
        }
        arrT[begin - 1] = 8;//添加锚点
        target++;
        num = 0;
        // ----------这是一个单元的结束--------------
    }
    // -----------------这是一个楼层的结束----------------
}
// =====================结束历遍所有的楼层=======================

//数据排序完成后,检查是否有错,有错就输出错误信息,没错就只输出数组
int dddd = 0;
for(int i=0; i<n-1; i++){
    if(arrG[i+1]<arrG[i]){
        dddd++;
        System.out.println(arrG[i]+"-------"+dddd);
        System.out.println(i);
        System.out.println(arrG[i+1]);
        System.out.println();
    }
}
for(int i=1001;i<2100;i++){
    if(i%10==0){
        System.out.println();
    }
    System.out.print(arrG[i]+" ");
}
//System.out.println(Arrays.toString(arrG));

}
}

    原文作者:排序算法
    原文地址: https://blog.csdn.net/tianyi_chen/article/details/63306937
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞