Android NDK开发java调C 实现基础排序

12 篇文章 0 订阅
9 篇文章 0 订阅
作为一名Android高级工程师,会用NDK是必须的,大家都知道NDK是android的c和c++的工具集,
由于c和c++的运行速度远远高于java而且很难被反编译,所以当android需要实现高速算法而且算
法技术保密性比较高的时候,最佳方式就是通过android ndk用java调c来实现。

C  jni代码

#include <jni.h>
#include <string>
#include <math.h>
#include <android/log.h>

#ifdef __cplusplus
extern "C" {
#endif

//堆排序heapSort函数声明
void swap(jint* data, int i, int j);
void buildMaxHeap(jint* data, int lastIndex);

//快速排序quickSort函数声明
int getMiddle(jint* list, int low, int high);
void quickSort(jint* list, int low, int high);
void quick(jint* arr,int len);

void sort(JNIEnv *env,int len,jint * data, int left, int right);
void merge(JNIEnv *env,jint * data,int len, int left, int center, int right);

JNIEXPORT jstring JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_stringFromJNI(
        JNIEnv *env, jobject jobject) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

/*
 * Class:     myndk_frank_com_myndkdemo_MainActivity
 * Method:    insertSort
 * Signature: ([I)Ljava/lang/String;
 */
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_insertSort
        (JNIEnv *env, jobject jobject, jintArray jintarray){

    int temp=0;
    //获取Java传递下来数组的长度
    jsize len = env->GetArrayLength(jintarray);
    jint *array=env->GetIntArrayElements(jintarray,NULL);

    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");

    for(int i=1;i<len;i++){
        int j=i-1;
        temp=array[i];
        for(;j>=0&&temp<array[j];j--){
            array[j+1]=array[j];  //将大于temp的值整体后移一个单位
        }
        array[j+1]=temp;
    }

    //新建一个jintArray对象
    jintArray intArray=env->NewIntArray(len);
    //获取jint_arr_temp对象的指针
    jint* int_arr_temp = env->GetIntArrayElements(intArray,NULL);
     //将java数组区复制到C数组区
    // env->GetIntArrayRegion(intArray,0,len,array);
     env->SetIntArrayRegion(intArray,0,len,array);
    for(int i=0;i<len;i++){
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d",array[i]);
    }
    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");

    return intArray;
}

/*
 * Class:     myndk_frank_com_myndkdemo_MainActivity
 * Method:    shellSort
 * Signature: ([I)Ljava/lang/String;
 */
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_shellSort
        (JNIEnv *env, jobject jobject, jintArray jintarray){

          //获取Java传递下来数组的长度
          jsize len = env->GetArrayLength(jintarray);
          jint *array=env->GetIntArrayElements(jintarray,NULL);

          __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");

            double d1=len;
            int temp=0;

            while(true) {
                d1 = ceil(d1 / 2);
                int d = (int) d1;
                for (int x = 0; x < d; x++) {

                    for (int i = x + d; i < len; i += d) {
                        int j = i - d;
                        temp = array[i];
                        for (; j >= 0 && temp < array[j]; j -= d) {
                            array[j + d] = array[j];
                        }
                        array[j + d] = temp;
                    }
                }

                if (d == 1) {
                    break;
                }
            }
                //新建一个jintArray对象
                jintArray intArray = env->NewIntArray(len);
                //获取jint_arr_temp对象的指针
                jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
                //将java数组区复制到C数组区
                // env->GetIntArrayRegion(intArray,0,len,array);
                env->SetIntArrayRegion(intArray, 0, len, array);

                for (int i = 0; i < len; i++) {
                    __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
                }
                __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");

                return intArray;
}

/*
 * Class:     myndk_frank_com_myndkdemo_MainActivity
 * Method:    selectSort
 * Signature: ([I)Ljava/lang/String;
 */
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_selectSort
        (JNIEnv *env, jobject jobject, jintArray jintarray){

    //获取Java传递下来数组的长度
    jsize len = env->GetArrayLength(jintarray);
    jint *array=env->GetIntArrayElements(jintarray,NULL);

    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");

    int position=0;
    for(int i=0;i<len;i++){
        int j=i+1;
        position=i;
        int temp=array[i];
        for(;j<len;j++){
            if(array[j]<temp){
                temp=array[j];
                position=j;
            }
        }
        array[position]=array[i];
        array[i]=temp;
    }

    //新建一个jintArray对象
    jintArray intArray = env->NewIntArray(len);
    //获取jint_arr_temp对象的指针
    jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
    //将java数组区复制到C数组区
    // env->GetIntArrayRegion(intArray,0,len,array);
    env->SetIntArrayRegion(intArray, 0, len, array);


    for(int i=0;i<len;i++) {
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
    }
    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");

    return intArray;

}

/*
 * Class:     myndk_frank_com_myndkdemo_MainActivity
 * Method:    heapSort
 * Signature: ([I)Ljava/lang/String;
 */
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_heapSort
        (JNIEnv *env, jobject jobject, jintArray jintarray){

    //获取Java传递下来数组的长度
    jsize len = env->GetArrayLength(jintarray);
    jint *array=env->GetIntArrayElements(jintarray,NULL);

    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");

    int arrayLength=len;
    //循环建堆
    for(int i=0;i<arrayLength-1;i++){
        //建堆
        buildMaxHeap(array,arrayLength-1-i);
        //交换堆顶和最后一个元素
        swap(array,0,arrayLength-1-i);

    }
    //新建一个jintArray对象
    jintArray intArray = env->NewIntArray(len);
    //获取jint_arr_temp对象的指针
    jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
    //将java数组区复制到C数组区
    // env->GetIntArrayRegion(intArray,0,len,array);
    env->SetIntArrayRegion(intArray, 0, len, array);


    for(int i=0;i<len;i++) {
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
    }
    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");

    return intArray;
}

 void swap(jint* data, int i, int j) {
    int tmp=data[i];
    data[i]=data[j];
    data[j]=tmp;
}

//对data数组从0到lastIndex建大顶堆
 void buildMaxHeap(jint* data, int lastIndex) {
    //从lastIndex处节点(最后一个节点)的父节点开始

    for(int i=(lastIndex-1)/2;i>=0;i--){
        //k保存正在判断的节点
        int k=i;
        //如果当前k节点的子节点存在
        while(k*2+1<=lastIndex){
            //k节点的左子节点的索引
            int biggerIndex=2*k+1;
            //如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
            if(biggerIndex<lastIndex){
                //若果右子节点的值较大
                if(data[biggerIndex]<data[biggerIndex+1]){
                    //biggerIndex总是记录较大子节点的索引
                    biggerIndex++;
                }
            }

            //如果k节点的值小于其较大的子节点的值
            if(data[k]<data[biggerIndex]){
                //交换他们
                swap(data,k,biggerIndex);
                //将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
                k=biggerIndex;
            }else{
                break;
            }
        }
    }
}


/*
 * Class:     myndk_frank_com_myndkdemo_MainActivity
 * Method:    bubbleSort
 * Signature: ([I)Ljava/lang/String;
 */
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_bubbleSort
        (JNIEnv *env, jobject jobject, jintArray jintarray){

    //获取Java传递下来数组的长度
    jsize len = env->GetArrayLength(jintarray);
    jint *array=env->GetIntArrayElements(jintarray,NULL);

    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");

    int temp=0;
        for(int i=0;i<len;i++){
            for(int j=0;j<len-1-i;j++){
                if(array[j]>array[j+1]){
                    temp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=temp;
                }
            }
    }

    //新建一个jintArray对象
    jintArray intArray = env->NewIntArray(len);
    //获取jint_arr_temp对象的指针
    jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
    //将java数组区复制到C数组区
    // env->GetIntArrayRegion(intArray,0,len,array);
    env->SetIntArrayRegion(intArray, 0, len, array);

    for(int i=0;i<len;i++) {
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
    }
    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");


    return intArray;

}

/*
 * Class:     myndk_frank_com_myndkdemo_MainActivity
 * Method:    quickSort
 * Signature: ([I)Ljava/lang/String;
 */
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_quickSort
        (JNIEnv *env, jobject jobject, jintArray jintarray){

    //获取Java传递下来数组的长度
    jsize len = env->GetArrayLength(jintarray);
    jint *array=env->GetIntArrayElements(jintarray,NULL);

    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");

    quick(array,len);

    //新建一个jintArray对象
    jintArray intArray = env->NewIntArray(len);
    //获取jint_arr_temp对象的指针
    jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
    //将java数组区复制到C数组区
    // env->GetIntArrayRegion(intArray,0,len,array);
    env->SetIntArrayRegion(intArray, 0, len, array);

    for(int i=0;i<len;i++) {
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
    }
    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");


    return intArray;

}

int getMiddle(jint* list, int low, int high) {
    int tmp =list[low];    //数组的第一个作为中轴
    while (low < high){
        while (low < high&& list[high] >= tmp) {
            high--;
        }

        list[low] =list[high];   //比中轴小的记录移到低端
        while (low < high&& list[low] <= tmp) {
            low++;
        }

        list[high] =list[low];   //比中轴大的记录移到高端
    }
    list[low] = tmp;              //中轴记录到尾
    return low;                   //返回中轴的位置
}

void quickSort(jint* list, int low, int high) {
    if (low < high){
        int middle =getMiddle(list, low, high);  //将list数组进行一分为二
        quickSort(list, low, middle - 1);       //对低字表进行递归排序
        quickSort(list,middle + 1, high);       //对高字表进行递归排序
    }
}

void quick(jint* arr,int len) {
    if (len > 0) {    //查看数组是否为空
        quickSort(arr,0, len - 1);
    }
}

/*
 * Class:     myndk_frank_com_myndkdemo_MainActivity
 * Method:    mergingSort
 * Signature: ([I)Ljava/lang/String;
 */
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_mergingSort
        (JNIEnv *env, jobject jobject, jintArray jintarray){

    //获取Java传递下来数组的长度
    jsize len = env->GetArrayLength(jintarray);
    jint *array=env->GetIntArrayElements(jintarray,NULL);

    //sort(env,len,array,0,len-1);

    //新建一个jintArray对象
    jintArray intArray = env->NewIntArray(len);
    //获取jint_arr_temp对象的指针
    jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
    //将java数组区复制到C数组区
    // env->GetIntArrayRegion(intArray,0,len,array);
    env->SetIntArrayRegion(intArray, 0, len, array);

    for(int i=0;i<len;i++) {
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
    }
    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");


    return intArray;

}

/*
void sort(JNIEnv *env,int len,jint * data, int left, int right) {

    if(left<right){
        //找出中间索引
        int center=(left+right)/2;
        //对左边数组进行递归
        sort(env,len,data,left,center);
        //对右边数组进行递归
        sort(env,len,data,center+1,right);
        //合并
        merge(env,data,len,left,center,right);
    }

}

void merge(JNIEnv *env,jint * data,int len, int left, int center, int right) {

    //新建一个jintArray对象
    jintArray intArray = env->NewIntArray(len);
    //获取jint_arr_temp对象的指针
    jint *tmpArr = env->GetIntArrayElements(intArray, NULL);

    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");

    //int [] tmpArr=new int[len];
    int mid=center+1;
    //third记录中间数组的索引
    int third=left;
    int tmp=left;


    while(left<=center&&mid<=right){
        //从两个数组中取出最小的放入中间数组
        if(data[left]<=data[mid]){
            tmpArr[third++]=data[left++];
        }else{
            tmpArr[third++]=data[mid++];
        }

    }

    //剩余部分依次放入中间数组
    while(mid<=right){
        tmpArr[third++]=data[mid++];
    }

    while(left<=center){
        tmpArr[third++]=data[left++];
    }

    //将中间数组中的内容复制回原数组
    while(tmp<=right){
        data[tmp]=tmpArr[tmp++];
    }
}
*/

/*
 * Class:     myndk_frank_com_myndkdemo_MainActivity
 * Method:    radixSort
 * Signature: ([I)Ljava/lang/String;
 */
JNIEXPORT jintArray JNICALL Java_myndk_frank_com_myndkdemo_MainActivity_radixSort
        (JNIEnv *env, jobject jobject, jintArray jintarray){

    //获取Java传递下来数组的长度
    jsize len = env->GetArrayLength(jintarray);
    jint *array=env->GetIntArrayElements(jintarray,NULL);

    //sort(array);

    //新建一个jintArray对象
    jintArray intArray = env->NewIntArray(len);
    //获取jint_arr_temp对象的指针
    jint *int_arr_temp = env->GetIntArrayElements(intArray, NULL);
    //将java数组区复制到C数组区
    // env->GetIntArrayRegion(intArray,0,len,array);
    env->SetIntArrayRegion(intArray, 0, len, array);

    for(int i=0;i<len;i++) {
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "Java -- > C JNI : num = %d", array[i]);
    }
    __android_log_print(ANDROID_LOG_INFO, "ANDROID_LOG_INFO", "=======================ANDROID_LOG_INFO========================");


    return intArray;
}

/*
void sort(jint * array){
    //首先确定排序的趟数;
    int max=array[0];
    for(inti=1;i<array.length;i++){
        if(array[i]>max){
            max=array[i];
        }
    }
    int time=0;
    //判断位数;
    while(max>0){
        max/=10;
        time++;
    }

    //建立10个队列;
    List<ArrayList> queue=newArrayList<ArrayList>();
    for(int i=0;i<10;i++){
        ArrayList<Integer>queue1=new ArrayList<Integer>();
        queue.add(queue1);
    }

    //进行time次分配和收集;
    for(int i=0;i<time;i++){
        //分配数组元素;
        for(intj=0;j<array.length;j++){
            //得到数字的第time+1位数;
            int x=array[j]%(int)Math.pow(10,i+1)/(int)Math.pow(10, i);
            ArrayList<Integer>queue2=queue.get(x);
            queue2.add(array[j]);
            queue.set(x, queue2);
        }
        int count=0;//元素计数器;
        //收集队列元素;
        for(int k=0;k<10;k++){
            while(queue.get(k).size()>0){
                ArrayList<Integer>queue3=queue.get(k);
                array[count]=queue3.get(0);
                queue3.remove(0);
                count++;
            }
        }
    }
}
*/
#ifdef __cplusplus
}
#endif


Android java代码


package myndk.frank.com.myndkdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    int numbers[]={49,38,65,97,76,13,27};

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tv0 = (TextView) findViewById(R.id.sample_text0);

        TextView tv1 = (TextView) findViewById(R.id.sample_text1);
        TextView tv2 = (TextView) findViewById(R.id.sample_text2);
        TextView tv3 = (TextView) findViewById(R.id.sample_text3);
        TextView tv4 = (TextView) findViewById(R.id.sample_text4);
        TextView tv5 = (TextView) findViewById(R.id.sample_text5);
        TextView tv6 = (TextView) findViewById(R.id.sample_text6);
        TextView tv7 = (TextView) findViewById(R.id.sample_text7);
        TextView tv8 = (TextView) findViewById(R.id.sample_text8);


        String numStr0="";
        for(int i=0;i<numbers.length;i++){
            numStr0=numStr0+numbers[i]+",";
        }
        tv0.setText("原数列   :"+numStr0);

        int nums1[]=insertSort(numbers);
        String numStr1="";
        for(int i=0;i<nums1.length;i++){
            numStr1=numStr1+nums1[i]+",";
        }
        tv1.setText("直接插入:"+numStr1);

        int nums2[]=shellSort(numbers);
        String numStr2="";
        for(int i=0;i<nums2.length;i++){
            numStr2=numStr2+nums2[i]+",";
        }
        tv2.setText("希尔排序:"+numStr2);

        int nums3[]=selectSort(numbers);
        String numStr3="";
        for(int i=0;i<nums3.length;i++){
            numStr3=numStr3+nums3[i]+",";
        }
        tv3.setText("选择排序:"+numStr3);

        int nums4[]=heapSort(numbers);
        String numStr4="";
        for(int i=0;i<nums4.length;i++){
            numStr4=numStr4+nums4[i]+",";
        }
        tv4.setText("堆排序   :"+numStr4);

        int nums5[]=bubbleSort(numbers);
        String numStr5="";
        for(int i=0;i<nums5.length;i++){
            numStr5=numStr5+nums5[i]+",";
        }
        tv5.setText("冒泡排序:"+numStr5);

        int nums6[]=quickSort(numbers);
        String numStr6="";
        for(int i=0;i<nums6.length;i++){
            numStr6=numStr6+nums6[i]+",";
        }
        tv6.setText("快速排序:"+numStr6);

        int nums7[]=mergingSort(numbers);
        String numStr7="";
        for(int i=0;i<nums7.length;i++){
            numStr7=numStr7+nums7[i]+",";
        }
        //tv7.setText("归并排序:"+numStr7);

        int nums8[]=radixSort(numbers);
        String numStr8="";
        for(int i=0;i<nums8.length;i++){
            numStr8=numStr8+nums8[i]+",";
        }
        //tv8.setText("基数排序:"+numStr8);

    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();

    /**
     * 直接插入排序
     */
    public native int [] insertSort(int sortNumber[]);
    /**
     * 希尔排序(最小增量排序)
     */
    public native int [] shellSort(int sortNumber[]);
    /**
     * 简单选择排序
     */
    public native int [] selectSort(int sortNumber[]);
    /**
     * 堆排序
     */
    public native int [] heapSort(int sortNumber[]);
    /**
     * 冒泡排序
     */
    public native int [] bubbleSort(int sortNumber[]);
    /**
     * 快速排序
     */
    public native int [] quickSort(int sortNumber[]);
    /**
     * 归并排序
     */
    public native int [] mergingSort(int sortNumber[]);
    /**
     * 基数排序
     */
    public native int [] radixSort(int sortNumber[]);
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Frank浩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值