A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

何雨

  • 黑马币:12

  • 帖子:15

  • 精华:0

© 何雨   /  2015-5-21 17:50  /  6778 人查看  /  23 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1.选择排序(直接排序) : 使用数组中的一个元素与其他位置的元素挨个比较一次,符合条件交换位置。


需求:  定义一个函数接收一个数组对象,然后把数组中最大值放在第一位。 其他元素不能丢失,顺序无所谓。       
                 
例子1:
class De{

        public static void main(String[] args)
        {
                int[] arr = {13,11,17,4,19};
                selectSort(arr);     调用
        }



        public static void selectSort(int[] arr)
        {
               
                for(int j = 0 ; j<arr.length-1 ; j++ ){

                       
                        for(int i = j+1 ; i<arr.length ; i++){
                                if(arr[j]<arr[i]){
                                        int temp = arr[j];
                                        arr[j] = arr[i];       
                                        arr[i] = temp;
                                }
                        }
                }
                //遍历数组的元素,查看效果
                for(int i  = 0 ; i<arr.length ; i++){
                        System.out.print(arr[i]+",");
                }

        }


}


2.冒泡排序: 相邻的两个元素比较一次,符合条件交换 位置。
                数组中的两个相邻元素:arr[i], arr[i+1]

需求: 把最大值放在倒数第一个位置。

例子2:
class  Demo3
{
        public static void main(String[] args)
        {
                int[] arr =  {11, 14 , 5 , 18, 3};
                bubbleSort(arr);
        }


        public static void bubbleSort(int[] arr){                相邻的两个数相比,只能用到最大所引值的前面一个
                for(int j = 0 ; j<arr.length-1; j++){                 // 疑问:arr.length-1。 因为五个数据只需要找出四个最大值即可排序

                        //把最大值放在倒数的第一个位置
                        for(int i = 0 ;  i < arr.length-1 - j ; i++){  //i=4  疑问: 因为for循环每执行完一次就 可以找出一个最大值,每找出一个最大值其实就可以少比较一次。
                                if(arr[i]>arr[i+1]){
                                        //交换位置
                                        int temp  = arr[i];
                                        arr[i] = arr[i+1];
                                        arr[i+1] = temp;
                                }
                        }
                }
       
                //遍历数组,查看效果
                for(int i = 0; i < arr.length ; i ++){
                        System.out.print(arr[i]+",");
                }

        }

}

3.二分法(折半查找法): 折半查找法只适用于有序的数组。
                     折半法:有一个范围,去找这个范围中间的值
                        最开始位置:min ;最后位置:max ; 中间位置:mid .

需求: 定义一个函数接收一个数组与一个要查找的元素,然后返回元素在数组中的索引值。如果不存在
返回-1表示。

例子3:
class De
{

方法一:
        public static void main(String[] args)
        {
                int[] arr = {12,15,18,19,34};
                int index  = halfSearch(arr,13);
                System.out.println("索引值:"+ index);
        }


        //折半查找法
        public static int halfSearch(int[] arr, int target)
        {

                //定义三个变量记录查找范围的最大、最小、中间索引值
                int max = arr.length-1;
                int min = 0;
                int mid = (max+min)/2;
       
                while(true){
                        if(target>arr[mid]){
                                min = mid+1;
                        }else if(target<arr[mid]){
                                max = mid-1;
                        }else{
                                //找到的情况
                                return mid;
                        }

                        //由于上面会改变最大、最小索引值,所以应该要重新计算中间值。
                        mid = (max+min)/2;
                       
                        //找不到的情况
                        if(min>max){
                                return  -1;
                        }
                }
        }





方法二:
        //遍历查找法:遍历数组中的每个元素与目标元素比较一次。
        public static int searchEle(int[] arr,int target){
                for(int i =  0 ; i<arr.length ; i++){
                        if(arr[i]==target){
                                return i;
                        }
                }

                return -1;
        }

}
例子4:
需求: 把一个数组的元素翻转. 元素位置的交换

class Demo5
{
        public static void main(String[] args)
        {
                // 值传递..
                char[] arr = {'传','智','播','客'};  //0x97

                reverse(arr);

                遍历查看结果
                for(int i = 0; i < arr.length  ; i++){
                        System.out.print(arr[i]+",");
                }
        }


        public static void  reverse(char[] arr){ // 0x97

                for(int startIndex=0 ,endIndex=arr.length-1 ; startIndex<endIndex; startIndex++,endIndex--){
                        //交换位置
                        char temp = arr[startIndex];
                        arr[startIndex] = arr[endIndex];
                        arr[endIndex] = temp;
                }       
        }


}
4.
二维数组:数组的数组。
       
       

1).二维数组的定义格式:

                数据类型[][]  变量名 = new 数据类型[长度1][长度2];



l练习1.
1. 现在有如下的一个数组:int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} ,
要求清除数组中为0的元素,然后存储非零的数据存储到一个新数组中。而且要求新的数组不能浪费长度。
                分析:1.查找数组中0的元素
                      2.清除0
                      3.创建新数组录入旧数组非0的元素

import java.util.*;
class De
{
        public static void main(String[] args)
        {
                int oldArr[]={0,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5};

                int[] newArr = clearZero(oldArr);
                System.out.println("新数组的元素:"+ Arrays.toString(newArr));
        }

       


        public static int[] clearZero(int[] oldArr){
                //先统计0的个数
                int count = 0; //定义该变量用于记录0的个数
                for(int i = 0 ; i<oldArr.length ; i++){
                        if(oldArr[i]==0){
                                count++;
                        }
                }
                //创建新的数组
                int[] newArr = new int[oldArr.length-count];

               
                int index = 0; //新数组使用的索引值。

                //遍历旧的数组,把非0的数据存储到新数组中。
                for(int i = 0 ; i<oldArr.length ; i++){

                        if(oldArr[i]!=0){         //如果是非0的数据,就应该存储到新的数组中.
                                newArr[index++] = oldArr[i];
                        }
                }

                return newArr;
        }
}
练习2.
2. 清除重复元素。 int[]   oldArr =  {1,4,9,4,1,1,7}; 把非重复元素存储到一个新的数组中返回,而且也是不能浪费长度。
                        分析:1.查找重复元素
                              2.清除重复的元素
                              3.创建新数组录入非重复元素

import java.util.*;
class Demo9
{
        public static void main(String[] args)
        {
                int[]  oldArr =  {1,4,9,4,1,1,7};
                int[] newArr = clearRepeat(oldArr);
                System.out.println("清除重复元素的数组:"+ Arrays.toString(newArr));
        }


        public static int[] clearRepeat(int[] oldArr){
                int count = 0 ; //count变量 是用于记录重复元素的个数

                //计算出重复元素的个数
                for(int i  = 0 ; i<oldArr.length -1  ; i++ ){
                        for(int j = i+1 ; j<oldArr.length ; j++){
                                if(oldArr[i]==oldArr[j]){
                                        count++;
                                        break;
                                }
                        }
                }
               
                //创建一个新的数组
                int[] newArr = new int[oldArr.length-count];
               
               
                int index = 0;        //新数组使用的索引值。

                //遍历旧数组
                for(int i = 0 ; i<oldArr.length ; i++){
                        boolean flag = false;   //该标识是用于标识取出的元素是否存在新数组中。 false默认情况是不存在 的。

                        int temp = oldArr[i];        //从旧数组 中取出遍历的元素

                        //遍历新的数组是否存在该数据
                        for(int j = 0 ; j<newArr.length ; j++){
                                if(newArr[j]==temp){
                                        flag = true;
                                        break;
                                }       
                        }

                        //该元素不存在新数组中,这时候应该存储起来
                        if(flag==false){
                                newArr[index++] = temp;
                        }
                }

                return newArr;
        }
}
练习3.
2.用户输入班级的人数,然后依次输入每个同学的成绩.
输入完毕之后,如果及格率没有达到60%, 就为每一位没有及格的成绩加2分,直到及格率达到60%为止。
                分析:录入班级的人数和成绩
                      计算及格率
                      不及格的加上2分


import java.util.*;
class Demo10
{
        public static void main(String[] args)
        {
                int[] arr ={98,89,45,59};           //readyData();
               
                double rate = getRate(arr);        //得到本班 的及格率
       
                while(true){
                        if(rate<0.6){
                                for(int i = 0 ; i<arr.length ; i++){
                                        if(arr[i]<60){
                                                arr[i] = arr[i]+2;
                                        }
                                }       
                                rate = getRate(arr);//重新计算及格率
                        }else{
                                break;
                        }
                }

               
                System.out.println("及格率:"+ rate*100+"% ,数组的元素是:"+ Arrays.toString(arr));
        }
       
       
        //计算及格率
        public static double getRate(int[] arr){
                double count = 0 ; //定义一个变量记录及格的人数
                for(int i = 0 ; i<arr.length ; i++){
                        if(arr[i]>=60){
                                count++;
                        }
                }
       
                double rate = count/arr.length; // rate 记录及格率的

                return rate;
        }




        //准备数据
        public static int[] readyData(){
                Scanner scanner = new Scanner(System.in);
                System.out.println("请输入班级的人数:");
                int count = scanner.nextInt();
                //创建一个数组对象
                int[] arr = new int[count];

                //录入学生的成绩
                for(int i = 0 ; i<count ; i++){
                        System.out.println("请第"+(i+1)+"位同学的分数:");
                        arr[i] = scanner.nextInt();
                }
                return arr;
        }

}
回复 使用道具 举报
1.插入排序—直接插入排序
将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。

  1. <div><ol><li class="alt"><span><span class="keyword">void</span><span> print(</span><span class="datatypes">int</span><span> a[], </span><span class="datatypes">int</span><span> n ,</span><span class="datatypes">int</span><span> i){  </span></span></li><li><span>    cout<<i <<<span class="string">":"</span><span>;  </span></span></li><li class="alt"><span>    <span class="keyword">for</span><span>(</span><span class="datatypes">int</span><span> j= 0; j<8; j++){  </span></span></li><li><span>        cout<<a[j] <<<span class="string">" "</span><span>;  </span></span></li><li class="alt"><span>    }  </span></li><li><span>    cout<<endl;  </span></li><li class="alt"><span>}  </span></li><li><span>  </span></li><li class="alt"><span>  </span></li><li><span><span class="keyword">void</span><span> InsertSort(</span><span class="datatypes">int</span><span> a[], </span><span class="datatypes">int</span><span> n)  </span></span></li><li class="alt"><span>{  </span></li><li><span>    <span class="keyword">for</span><span>(</span><span class="datatypes">int</span><span> i= 1; i<n; i++){  </span></span></li><li class="alt"><span>        <span class="keyword">if</span><span>(a[i] < a[i-1]){               </span><span class="comment">//若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入</span><span>  </span></span></li><li><span>            <span class="datatypes">int</span><span> j= i-1;   </span></span></li><li class="alt"><span>            <span class="datatypes">int</span><span> x = a[i];        </span><span class="comment">//复制为哨兵,即存储待排序元素</span><span>  </span></span></li><li><span>            a[i] = a[i-1];           <span class="comment">//先后移一个元素</span><span>  </span></span></li><li class="alt"><span>            <span class="keyword">while</span><span>(x < a[j]){  </span><span class="comment">//查找在有序表的插入位置</span><span>  </span></span></li><li><span>                a[j+1] = a[j];  </span></li><li class="alt"><span>                j--;         <span class="comment">//元素后移</span><span>  </span></span></li><li><span>            }  </span></li><li class="alt"><span>            a[j+1] = x;      <span class="comment">//插入到正确位置</span><span>  </span></span></li><li><span>        }  </span></li><li class="alt"><span>        print(a,n,i);           <span class="comment">//打印每趟排序的结果</span><span>  </span></span></li><li><span>    }  </span></li><li class="alt"><span>      </span></li><li><span>}  </span></li><li class="alt"><span>  </span></li><li><span><span class="datatypes">int</span><span> main(){  </span></span></li><li class="alt"><span>    <span class="datatypes">int</span><span> a[8] = {3,1,5,7,2,4,9,6};  </span></span></li><li><span>    InsertSort(a,8);  </span></li><li class="alt"><span>    print(a,8,8);  </span></li><li><span>}  </span> </li></ol></div>
复制代码
2.交换排序—冒泡排序
在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
  1. <p>01.void bubbleSort(int a[], int n){  
  2. 02.    for(int i =0 ; i< n-1; ++i) {  
  3. 03.        for(int j = 0; j < n-i-1; ++j) {  
  4. 04.            if(a[j] > a[j+1])  
  5. 05.            {  
  6. 06.                int tmp = a[j] ; a[j] = a[j+1] ;  a[j+1] = tmp;  
  7. 07.            }  
  8. 08.        }  
  9. 09.    }  
  10. 10.}  </p><p> </p><p>改进后的冒泡排序</p><div><ol><li class="alt"><span><span class="keyword">void</span><span> Bubble_1 ( </span><span class="datatypes">int</span><span> r[], </span><span class="datatypes">int</span><span> n) {  </span></span></li><li><span>    <span class="datatypes">int</span><span> i= n -1;  </span><span class="comment">//初始时,最后位置保持不变</span><span>  </span></span></li><li class="alt"><span>    <span class="keyword">while</span><span> ( i> 0) {   </span></span></li><li><span>        <span class="datatypes">int</span><span> pos= 0; </span><span class="comment">//每趟开始时,无记录交换</span><span>  </span></span></li><li class="alt"><span>        <span class="keyword">for</span><span> (</span><span class="datatypes">int</span><span> j= 0; j< i; j++)  </span></span></li><li><span>            <span class="keyword">if</span><span> (r[j]> r[j+1]) {  </span></span></li><li class="alt"><span>                pos= j; <span class="comment">//记录交换的位置 </span><span>  </span></span></li><li><span>                <span class="datatypes">int</span><span> tmp = r[j]; r[j]=r[j+1];r[j+1]=tmp;  </span></span></li><li class="alt"><span>            }   </span></li><li><span>        i= pos; <span class="comment">//为下一趟排序作准备</span><span>  </span></span></li><li class="alt"><span>     }   </span></li><li><span>} </span>
  11. </li></ol></div>
复制代码
3.归并排序
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
两路归并的递归算法
  1. 1.void MSort(ElemType *r, ElemType *rf,int s, int t)  
  2. 2.{   
  3. 3.    ElemType *rf2;  
  4. 4.    if(s==t) r[s] = rf[s];  
  5. 5.    else  
  6. 6.    {   
  7. 7.        int m=(s+t)/2;          /*平分*p 表*/  
  8. 8.        MSort(r, rf2, s, m);        /*递归地将p[s…m]归并为有序的p2[s…m]*/  
  9. 9.        MSort(r, rf2, m+1, t);      /*递归地将p[m+1…t]归并为有序的p2[m+1…t]*/  
  10. 10.        Merge(rf2, rf, s, m+1,t);   /*将p2[s…m]和p2[m+1…t]归并到p1[s…t]*/  
  11. 11.    }  
  12. 12.}  
  13. 13.void MergeSort_recursive(ElemType *r, ElemType *rf, int n)  
  14. 14.{   /*对顺序表*p 作归并排序*/  
  15. 15.    MSort(r, rf,0, n-1);  
  16. 16.}  
复制代码
选择排序算法准则:
每种排序算法都各有优缺点。因此,在实用时需根据不同情况适当选用,甚至可以将多种方法结合起来使用。
选择排序算法的依据
影响排序的因素有很多,平均时间复杂度低的算法并不一定就是最优的。相反,有时平均时间复杂度高的算法可能更适合某些特殊情况。同时,选择算法时还得考虑它的可读性,以利于软件的维护。一般而言,需要考虑的因素有以下四点:
1.待排序的记录数目n的大小;
2.记录本身数据量的大小,也就是记录中除关键字外的其他信息量的大小;
3.关键字的结构及其分布情况;
4.对排序稳定性的要求。
设待排序元素的个数为n.
1)当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。
   快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;
       堆排序 :  如果内存空间允许且要求稳定性的,

       归并排序:它有一定数量的数据移动,所以我们可能过与插入排序组合,先获得一定长度的序列,然后再合并,在效率上将有所提高。
2)  当n较大,内存空间允许,且要求稳定性 =》归并排序
3)当n较小,可采用直接插入或直接选择排序。
    直接插入排序:当元素分布有序,直接插入排序将大大减少比较次数和移动记录的次数。
    直接选择排序 :元素分布有序,如果不要求稳定性,选择直接选择排序
5)一般不使用或不直接使用传统的冒泡排序。



回复 使用道具 举报
wgy 中级黑马 2015-6-23 07:47:34
23#
写一个方法就可以搞定了,如下:
    public void bubbleSort(arr)
     {
        for(int x=0;x<arr.length-1;x++)
          {
           for(int y = 0;y<arr.length-x-1)
        {   if(arr[y]>arr[y+1])
             {    int temp = arr[y];
                  arr[y]=arr[y+1];
                 arr[y+1]=temp;
                }
         }
    }
}

有这个方法就够了,这就是冒泡排序。
回复 使用道具 举报
发问题帖子可以获得技术分吗
回复 使用道具 举报
12
您需要登录后才可以回帖 登录 | 加入黑马