Java學習第四篇:數組,排序,查找

一.數組

1.一維數組html

(1).數組的定義java

數據類型 數組名[]=new 數據類型[大小]算法

public class Demo1 {
    public static void main(String[] args) {
        //第一種定義方式
        int arr[];
        arr=new int[5];
        //第二種定義方式
        int arr2[]=new int[5];
        //第三種定義方式
        int[] arr3;
        arr3=new int[5];
        //第四種定義方式
        int arr4[]={1,2,3,4};
    }
}

(2).對象數組shell

假設一個養狗場有4只狗, 名字分別是花花, 白白, 黑黑, 紅紅, 體重分別爲4.5Kg, 5.6Kg, 7.8Kg, 9.0Kg, 計算出平均體重, 並找出體重最大的狗的名字.windows

import java.io.*;
public class Demo2 {
    public static void main(String[] args) {
        try {
            //輸入流
            InputStreamReader isr=new InputStreamReader(System.in);
            BufferedReader bReader=new BufferedReader(isr);
            
            //定義一個對象數組,能夠存放4只狗的對象數組
            Dog dogs[]=new Dog[4];
            //給對象賦值
            for(int i=0;i<dogs.length;i++){
                //這裏要建立dog[i]對象
                dogs[i]=new Dog();
                System.out.println("請輸入第"+(i+1)+"狗的名字:");
                String dogName=bReader.readLine();
                dogs[i].setName(dogName);
                
                System.out.println("請輸入第"+(i+1)+"狗的體重:");
                String dogWeight=bReader.readLine();
                float dWeight=Float.parseFloat(dogWeight);
                dogs[i].setWeight(dWeight);
            }
            
            //整體重
            float allWeight=0;
            //平均體重
            float averWeight=0;
            for(int i=0;i<dogs.length;i++){
                allWeight+=dogs[i].getWeight();
            }
            averWeight=allWeight/dogs.length;
            System.out.println("平均體重爲:"+averWeight);
            
            //體重最大的
            float maxWeight=dogs[0].getWeight();
            int maxWeightIndex=0;
            for(int i=1;i<dogs.length;i++){
                if(maxWeight<dogs[i].getWeight()){
                    maxWeight=dogs[i].getWeight();
                    maxWeightIndex=i;
                }
            }
            System.out.println("體重最大的狗是:"+dogs[maxWeightIndex].getName()+
                               " 體重爲:"+dogs[maxWeightIndex].getWeight());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Dog {
    private String name;
    private float weight;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getWeight() {
        return weight;
    }
    public void setWeight(float weight) {
        this.weight = weight;
    }
}

運行結果:數組

請輸入第1狗的名字:
花花
請輸入第1狗的體重:
4.5
請輸入第2狗的名字:
白白
請輸入第2狗的體重:
5.6
請輸入第3狗的名字:
黑黑
請輸入第3狗的體重:
7.8
請輸入第4狗的名字:
紅紅
請輸入第4狗的體重:
9.0
平均體重爲:6.7250004
體重最大的狗是:紅紅 體重爲:9.0數據結構

(3).數組小結dom

①數組可存放同一類型的數據;ui

②簡單數據類型(int, float...)數組可直接賦值, 對象數組在定義後,賦值時須要再次爲每一個對象分配空間;this

③數組大小必須事先指定;

④數組名可理解爲指向數組首地址的引用;

⑤數組的下標是從0開始編號的.

2.多維數組

二維數組的定義

數據類型 數組名[][]=new 數據類型[大小][大小]

二.排序

這裏主要介紹了七種經常使用的排序方法, 包括冒泡排序, 選擇排序, 直接插入排序, 希爾排序, 堆排序, 歸併排序和快速排序. 這裏主要參考了《大話數據結構》和《MoreWindows白話經典算法之七大排序第2版(高清)》", 下載連接爲http://download.csdn.net/detail/morewindows/4560056

1.冒泡排序

class BubbleSort {
    /**
     * 冒泡排序方法1,從小到大
     * 若是通過一趟排序以後沒有任何交換,說明已經排好序了,不須要再進行下去了
     * @param arr 待排序數組
     */
    public void bubbleSort1(int arr[]) {
        //標記位
        boolean Flag=true;
        int k=arr.length;
        while(Flag) {
            Flag=false;
            for(int j=1;j<k;j++) {
                //若是前面的數大於後面的數,則交換這兩個數
                if(arr[j-1]>arr[j]) {
                    arr[j-1]^=arr[j];
                    arr[j]^=arr[j-1];
                    arr[j-1]^=arr[j];
                    Flag=true;
                }
            }
            k--;
        }
    }
    
    
    /**
     * 冒泡排序方法2,從小到大
     * 若是有100個數的數組,僅前面10個無序,後面90個都已經排好序了且大於前面10個數字
     * 那麼在第一趟遍歷後,最後發生交換的位置一定小於10,且這個位置以後的數據一定已經
     * 有序了,記錄下這個位置,第二次只要從數組頭部遍歷到這個位置就能夠了
     * @param arr 待排序數組
     */
    public void bubbleSort2(int arr[]) {
        //標記位置的標記位
        int Flag=arr.length;
        int k;
        while(Flag>0) {
            k=Flag;
            Flag=0;
            for(int j=1;j<k;j++) {
                if(arr[j-1]>arr[j]) {
                    arr[j-1]^=arr[j];
                    arr[j]^=arr[j-1];
                    arr[j-1]^=arr[j];
                    //更新記錄交換位置的變量Flag
                    Flag=j;
                }
            }
        }
    }
    
}

2.選擇排序

class SelectSort {
    /**
     * 選擇排序,從小到大
     * @param arr 待排序數組
     */
    public void selectSort(int arr[]) {
        int length=arr.length;
        //最小值的下標索引
        int minIndex;
        for(int i=0;i<length;i++) {
            minIndex=i;
            for(int j=i+1;j<length;j++) {
                if(arr[j]<arr[minIndex]) {
                    minIndex=j;
                }
            }
            if(minIndex!=i) {
                if(arr[minIndex]!=arr[i]) {
                    arr[minIndex]^=arr[i];
                    arr[i]^=arr[minIndex];
                    arr[minIndex]^=arr[i];
                }
            }
        }
    }
    
}

3.插入排序

class InsertSort {
    /**
     * 插入排序,從小到大
     * 即每次arr[i]先和前面一個數據arr[i-1]比較,若是arr[i]>arr[i-1],說明arr[0...i]也是有序的,無須調整
     * 不然就令j=i-1,temp=arr[i],而後一邊將數據arr[j]向後移動一邊向前搜索,當有數據arr[j]<arr[i]時中止
     * 並將temp放到arr[j+1]處
     * @param arr 待排序數組
     */
    public void insertSort(int arr[]) {
        int length=arr.length;
        int temp=0,j=0;
        for(int i=1;i<length;i++) {
            //比前面的數小
            if(arr[i]<arr[i-1]) {
                temp=arr[i];
                //向後移動
                for(j=i-1;j>=0 && arr[j]>temp;j--) {
                    arr[j+1]=arr[j];
                }
                arr[j+1]=temp;
            }
        }
    }
    
}

4.希爾排序

class ShellSort {
    /**
     * 希爾排序,從小到大
     * 希爾排序的實質就是分組插入排序,又稱縮小增量排序
     * @param arr 待排序數組
     */
    public void shellSort(int arr[]) {
        //gap爲步長
        int i,j,gap;
        int length=arr.length;
        //步長
        for(gap=length/2;gap>0;gap/=2) {
            //分組
            for(i=0;i<gap;i++) {
                //每一組進行插入排序
                for(j=i+gap;j<length;j+=gap) {
                    if(arr[j]<arr[j-gap]) {
                        int temp=arr[j];
                        int k=j-gap;
                        while(k>=0 && arr[k]>temp) {
                            arr[k+gap]=arr[k];
                            k-=gap;
                        }
                        arr[k+gap]=temp;
                    }
                }
            }
        }
    }
    
}

5.堆排序

class HeapSort {
    /**
     * 堆排序,從大到小
     * @param arr 待排序數組
     */
    public void heapSort(int arr[]) {
        int length=arr.length;
        //創建最小堆
        for(int i=length/2-1;i>=0;i--) {
            heapAdjust(arr,i,length);
        }
        
        //堆排序
        //構建小頂堆,排序的結果是由大到小
        for(int i=length-1;i>=1;i--) {
            //將小頂堆的頂部arr[0]與arr[i]依次交換
            if(arr[i]!=arr[0]) {
                arr[i]^=arr[0];
                arr[0]^=arr[i];
                arr[i]^=arr[0];
            }
            //從新構建小頂堆
            heapAdjust(arr,0,i);
        }
    }
    
    /**
     * 堆調整
     * @param arr 待排序數組
     * @param i   從i節點開始調整,從0開始計算,第i節點的子節點爲2*i+1,2*i+2
      * @param n   節點總數
     */
    private void heapAdjust(int arr[],int i,int n) {
        //定義變量
        int j,temp;
        temp=arr[i];
        j=2*i+1;
        while(j<n) {
            //在左右節點中找最小的節點
            if(j+1<n && arr[j+1]<arr[j]) {
                j++;
            }
            //不須要調整
            if(arr[j]>=temp) {
                break;
            }
            //把較小的節點往上移動,替換它的父節點
            arr[i]=arr[j];
            i=j;
            j=2*i+1;
        }
        arr[i]=temp;
    }
    
}

6.歸併排序

class MergeSort {
    /**
     * 歸併排序,從小到大
     * @param arr 待排序數組
     */
    public void mergeSort(int arr[]) {
        int length=arr.length;
        //建立一個和待排序數組一樣大小臨時數組
        int temp[]=new int[length];
        //歸併排序
        merge_sort(arr, 0, length-1, temp);
    }
    
    /**
     * 歸併排序
     * @param arr    待排序數組
     * @param first  起始下標
     * @param last   終點下標
     * @param temp   臨時數組
     */
    private void merge_sort(int arr[],int first,int last,int temp[]) {
        if(first<last) {
            int mid=(first+last)/2;
            //左邊有序
            merge_sort(arr, 0, mid, temp);
            //右邊有序
            merge_sort(arr, mid+1, last, temp);
            //再將兩個有序數組合並
            merge_array(arr, first, mid, last, temp);
        }
    }
    
    /**
     * 合併兩個有序數組
     * @param arr    待排序數組
     * @param first  起始下標
     * @param mid    中間下標
     * @param last   終點下標
     * @param temp   臨時數組
     */
    private void merge_array(int arr[],int first,int mid,int last,int temp[]) {
        int i=first,j=mid+1;
        int m=mid,n=last;
        int k=0;
        while(i<=m && j<=n) {
            if(arr[i]<arr[j]) {
                temp[k++]=arr[i++];
            }else {
                temp[k++]=arr[j++];
            }
        }
        while(i<=m) {
            temp[k++]=arr[i++];
        }
        while(j<=n) {
            temp[k++]=arr[j++];
        }
        for(i=0;i<k;i++) {
            arr[first+i]=temp[i];
        }
    }
    
}

7.快速排序

import java.util.*;
public class Demo9 {
    public static void main(String[] args) {
        //關於Java中生成特定區間裏的隨機數見http://blog.sina.com.cn/s/blog_59aebaa10100ct47.html
        //生成8000000個[1,9000000]之間的隨機數
        Random random=new Random();
        int length=8000000;
        int arr[]=new int[length];
        for(int i=0;i<length;i++) {
            arr[i]=random.nextInt(9000000)+1;
        }
        
        //快速排序
        QuickSort qSort=new QuickSort();
        //關於統計程序運行時間見http://blog.csdn.net/uyu2yiyi/article/details/6267990
        //排序開始時間
        long startTime=System.currentTimeMillis();
        qSort.quickSort(arr);
        //排序結束時間
        long endTime=System.currentTimeMillis();
        System.out.println("快速排序時間爲:"+(endTime-startTime)+"毫秒");
    }
}

class QuickSort {
    /**
     * 快速排序,從小到大
     * @param arr 待排序數組
     */
    public void quickSort(int arr[]) {
        quick_sort(arr, 0, arr.length-1);
    }
    
    /**
     * 快速排序
     * @param arr    待排序數組
     * @param first  起點下標
     * @param last   終點下標
     */
    private void quick_sort(int arr[],int first,int last) {
        //樞軸
        int pivot;
        if(first<last) {
            //將子表一分爲二
            pivot=partition(arr, first, last);
            //對低子表進行排序
            quick_sort(arr, first, pivot-1);
            //對高子表進行排序
            quick_sort(arr, pivot+1, last);
        }
    }
    
    /**
     * 找到劃分子表的位置
     * @param arr    待排序數組
     * @param first  起點下標
     * @param last   終點下標
     * @return       劃分子表的位置
     */
    private int partition(int arr[],int first,int last) {
        int pivotkey=arr[first];
        while(first<last) {
            while(first<last && arr[last]>=pivotkey) {
                last--;
            }
            arr[first]=arr[last];
            while(first<last && arr[first]<=pivotkey) {
                first++;
            }
            arr[last]=arr[first];
        }
        arr[first]=pivotkey;
        return first;
    }
    
}

三.查找

查找有不少方法, 如二分查找, 插值查找, 斐波那契查找, 二叉樹查找, 哈希表查找等, 這裏僅給出二分查找.

public class Demo10 {
    public static void main(String[] args) {
        //待查找數組必須是從小到大有序的
        int arr[]={1,4,9,20,47,69};
        int pos=-1;
        int key=47;
        BinarySearch bSearch=new BinarySearch();
        if( (pos=bSearch.binarySearch(arr, key))!=-1 ) {
            System.out.println("找到了該關鍵字,其在數組中的下標爲: "+pos);
        }else {
            System.out.println("沒有找到該關鍵字");
        }
    }
}

class BinarySearch {
    /**
     * 二分查找,其前提是查找的數組是從小到大有序的
     * @param arr  待查找數組
     * @param key  待插值關鍵字
     * @return     若是找到,則返回該關鍵字在數組中的位;沒找到則返回-1
     */
    public int binarySearch(int arr[],int key) {
        int low,high,mid;
        low=0;
        high=arr.length-1;
        while(low<=high) {
            mid=low+(high-low)/2;
            if(key>arr[mid]) {
                low=mid+1;
            }else if(key<arr[mid]) {
                high=mid-1;
            }else {
                //找到,返回下標
                return mid;
            }
        }
        //沒找到
        return -1;
    }
    
}
相關文章
相關標籤/搜索