Java之數組,循環


break和continue的使用范圍:

continue只能用於循環結構,也就是說只要有continue,肯定存在循環.

break用在switch語句和循環結構中.

break和continue單獨存在時,下面不可以有任何語句,因為執行不到(會報錯)

函數重載(overload)

同一個類中允許存在一個以上的同名函數,只要它們的 參數類型/參數個數/參數類型順序 不同,跟 返回類型 無關.

Java中的數組:

首先了解下:

在函數中定義的一些 基本類型的變量(short,int,char,long,double,byte,boolean,float),和 對象的引用變量(int[ ] x等) 都是在函數的棧內存中分配,

   當在一段代碼塊(也就是一堆花括號{ }之間)定義一個變量時,Java就在棧中為這個變量分配內存空間,當超過變量的作用域后,Java會自動釋放掉為該變量

   所分配的內存空間,該內存空間可以立即被另作他用.

          堆內存用來存放由 new創建的對象和數組  ,在堆中分配內存,由JVM的自動垃圾回收器來管理.在堆中產生了一個數組或對象后,還可以在棧中定義一個特殊

              的變量,讓棧中的這個變量的取值 等於 數組 或 對象在堆內存中的首地址,棧中的這個變量就成了數組或對象的引用變量,以后就可以在程序中使用棧中的引用

              變量來訪問堆中的數組或對象,引用變量相當於是為數組或對象起的一個名稱(叫代號也行).

          引用變量是普通的變量,定義時在棧中分配,引用變量在程序運行到其作用域之外后被釋放.

          而數組和對象本身在 堆 中 分配,即使程序運行到使用new產生數組和對象的語句所在的代碼塊之外,數組和對象本身占據的內存不會被釋放,數組和對象在沒有引用

              變量指向它時,才會變為垃圾,不能再被使用,但仍然占據內存空間不放,在隨后一個不確定的時間被 垃圾回收器 收走(釋放掉).這也是Java比較占內存的原因.

        以上摘自張孝祥老師的<Java就業培訓教程>

    

       舉例:

           int[ ]  x;//定義了一個數組x,這條語句的執行完后的內存狀態如下

           x=new int [3];//數組初始化,內存狀態如下

 

         堆內存_棧內存1

       堆內存_棧內存2

然后測試一下各種類型數組的默認值:

class ArrayTest
{
	public static void main(String[] args) 
	{
		//int,double,float,char型數組默認值
		 int[] n=new int[3];
		  System.out.println("int "+n[1]);//0
		 char[] c=new char[3];
		   System.out.println("char "+c[1]);//ASCII碼為0的空字符:'\0'
		 float[] f=new float[3];
		   System.out.println("float "+f[1]);//0.0f(加f為了說明是float型)
		 double[] d=new double[3];
		   System.out.println("double "+d[1]);//0.0
		 boolean[] b=new boolean[3];
		   System.out.println("boolean "+b[1]);//false
	}
}

   
運行結果:
    數組默認值
兩個經典的排序冒泡和選擇:
  示例:
import java.util.*;
class sort 
{
	/*
	 冒泡排序:(從小到大,從零趟開始為了操作方便)
	 算法思想:
	  相鄰兩個數比較,兩兩比較得到的較大數不斷后移,
	  最終每趟最大沉底.
	  示例:下標 0 1 2 3 4 
	       i   5 3 7 9 1 
	             
	            3 5 7 9 1 5>3交換 
	  第零趟:   3 5 7 9 1 5<7不動
                    3 5 7 9 1 7<9不動
	            3 5 7 1 9 9>1交換-->9為最大,arr[4]為9
	     共比較4(arr.length-0(趟數)-1)次
	  第一趟:   3 5 7 1   -->9不用在參與比較
	             3 5 7 1   3<5不動
		     3 5 7 1   5<7不動
		     3 5 1 7   7>1交換-->7為次大,arr[3]為7
	     共比較3(arr.length-1-1)次
	  第二趟:   3 5 1     -->7不用再參與比較
	             3 5 1     3<5不動
	             3 1 5     5>1交換-->arr[2]為5
	     共比較2(arr.length-2-1)次
	  第三趟:    3 1       -->5不用再參與比較
	             1 3       3>1交換-->arr[1]為3
				 共比較1(arr.length-3-1)次
	  共走了4(arr.length-1)趟
	  最后一定剩余一個數字1,不用再參與比較,肯定最小      
	*/
   //交換
   public static void swap(int[] b,int i,int j)
	{
         int temp=b[i];
         b[i]=b[j];
         b[j]=temp;
      }
   //冒泡排序
   public static void bubbleSort(int[] a)
   {
     for(int i=0;i<a.length-1;++i)//控制趟數
      for(int j=0;j<a.length-i-1;++j)//控制每趟比較的次數
	    if(a[j]>a[j+1])
	      swap(a,j,j+1);
   }
 /*
  選擇排序:(從小到大)
  算法思想:
    每一趟從待排序的數據元素中選出最小(或最大)的一個元素,
    順序放在已排好序的數列的最后,直到全部待排序的數據元素排完。
   示例:下標 0 1 2 3 4 
	     5 3 7 9 1 
       i      
            3 5 7 9 1  5>3交換
   第零趟:   3 5 7 9 1  3<7不動      
              3 5 7 9 1  3<9不動
              1 5 7 9 3  3>1交換-->此時arr[0]為1,並且最小
        共比較4(arr.length-0-1)次
  
                5 7 9 3  5<7不動
   第一趟:     5 7 9 3  5<9不動 
                3 7 9 5  3<5交換-->此時arr[1]為3,次小
        共比較3(arr.length-1-1)次
  
   第二趟:       7 9 5  7<9不動
                  5 9 7  5<7交換-->此時arr[2]為5.
       共比較2(arr.length-2-1)次
   
   第三趟:         7 9  9>7交換-->此時arr[3]為7.
      共比較1(arr.length-3-1)次
	 
    共走了4(arr.length-1)趟,最后剩余一個9,為最大,arr[4]為9                 
   */
   //選擇排序
    public static void selectSort(int[] b)
	{
	  for(int i=0;i<b.length-1;++i)//控制趟數
	     for(int j=i+1;j<b.length;++j)//共比較(arr.length-1)-(i+1)+1
	        if(b[i]>b[j])                //即arr.length-i-1
	          swap(b,i,j);
	}
   //選擇排序第二種寫法:
    public static void selectSort_2(int[] c)
    {
	   int k=0;
	   for(int i=0;i<c.length-1;++i)
		{
	        k=i;
	        for(int j=i+1;j<c.length;++j)
	         if(c[k]>c[j])
	        k=j; 
	       if(k!=i)
	       swap(c,k,i);
	      }
    }
	/*
	這種寫法和上面最大區別是:
	  k中每次存放較小元素的下標,直到一趟走完
	  此時k中存放這一趟最小元素下標
	  這時在和第i個位置的元素交換
	 */
  
   //打印數組
    public static void showArray(int[] arr)
	{
	 System.out.print("[");
	 for(int i=0;i<arr.length;++i)
	    if(i!=arr.length-1)
		  System.out.print(arr[i]+",");
         else
		System.out.println(arr[i]+"]");
    }
	//Test
    public static void main(String[] args)
	{
		int[] arr={7,3,9,11,1,6,5};
		int[] arr_2={6,2,3,1,11};
		int[] arr_3={9,8,10,2,11,3};
		bubbleSort(arr);
		System.out.println("bubbleSort: ");
		showArray(arr);
	    
		selectSort(arr_2);
		System.out.println("slectSort: ");
	       showArray(arr_2);
	   
	    selectSort(arr_3);
		System.out.println("selectSort_2: ");
	    showArray(arr_3);
		
		//Arrays.sort(arr_2);實際開發中使用
		//showArray(arr_2);
	}
  
}  
運行結果:
       排序結果

最大值與最小值:

class  MaxMin
{
 //相當於冒泡/選擇排序的一趟
 //可以一次遍歷同時找出最大值和最小值
   public static void main(String[] args)
   {
     int max,min;
     int[] arr={3,2,1,6,9,5};
	 max=min=arr[0];//max和min的初始值可以為數組中任何兩個值,但下面的循環必須從下標0(i=0)開始
     for(int i=1;i<arr.length;++i)
       if(arr[i]>max)
	       max=arr[i];
       else
            if(arr[i]<min)
	      min=arr[i];
	 System.out.println("max="+max+",min="+min);
   }
}
運行結果:

MaxMin

折半(二分查找):

舉例:

class BiSearch 
{
 	/*
	折半(二分)查找:
	算法思想:
	  要求序列必須有序(升序/降序),因為只有這樣才能確定
	  數據的范圍,通過不斷的折半來縮小查找數據的范圍
	  設查找數據為key
	  ①通過兩個變量min和max來指定數據的范圍,要求min<=max
         (min=max表示只有一個數據時)
	  ②首先與mid=(min+max)/2比較,如果key=mid查找成功,直接返回
	     mid,如果key<mid,則min=mid-1,縮短查找范圍,此時在讓key與
		 mid=(max+min)/2比較,若key>mid,則max=mid+1,之后再與新的mid
		 比較,依次類推找到則返回,未找到則min>max.
	*/
	public static int biSearch(int[] arr,int key)
	{
	  int max=arr.length-1,min=0,mid;
	  while(max>=min)
	  {
	   mid=(max+min)/2;
	   if(key==arr[mid])
		  return mid;//返回key在數組中的下標
	   else
		 if(key<arr[mid])
           max=mid-1;
	     else
		   min=mid+1;
	  }
       return -1;//表示未找到
	 }
  public static void main(String[] args)
  {
    int[] arr={3,5,7,9,10,11};
	System.out.println("keyIndex="+biSearch(arr,11));
  }
}
 
         

折半查找過程(以上面為例)

    查找成功:

      折半_1

示例2:

   已知有序數組,要求在有序數組中插入一個元素,使之仍然有序.

class BiSearch_2
{
	//已知有序數組,要求在有序數組中插入一個元素,使之仍然有序
	/*
	 思想:
	   ①首先我們要找到該元素插入的位置,才能進行操作
	   ②由於數組有序,通過折半查找來確定其位置
	   ③把該位置(包括這個位置)的元素(從后向前)逐個后移,
	      為新插入的元素
	      空出一個位置
	*/
  public static int biSearch(int[] arr,int key)
	{
	  int max=arr.length-2,min=0,mid;
	  while(max>=min)
	  {
	   mid=(max+min)/2;
	   if(key==arr[mid])
		  return mid;//返回key在數組中的下標
	   else
		 if(key<arr[mid])
           max=mid-1;
	     else
		   min=mid+1;
	  }
      return min;//由圖可知min就是該元素的插入位置
    }
   //數組中的元素后移,即賦值過程
    public static void backWard(int[] arr,int site,int key)//site為插入位置
    {  
	   int i;
	   for(i=arr.length-2;i>=site;--i)//例子:site=3,arr.length=7   
	      arr[i+1]=arr[i];
	   arr[i+1]=key;//此時i=2,因此插入位置為i+1   
    }
  public static void main(String[] args)
  {
    int[] arr={3,5,7,9,10,11,0};//已知數組的元素為6個,最后一個0
	                           //為了讓數組多開辟一個空間,存放插入元素
	int index;
	index=biSearch(arr,8);
	System.out.println("keyIndex="+index);
	backWard(arr,index,8);
	//打印
	for(int i=0;i<arr.length;++i)
	  System.out.print(arr[i]+" ");
  }
}
運行結果:
插入元素
查找過程:
折半_2
注意:折半查找優點是比較次數少,查找速度快,平均性能好;
其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查找方法適用於不經常變動而查找頻繁的有序列表。
進制轉換:
   ①十進制轉二進制(除二取余法,僅適用於正數)
class ArrayTest_2
{
  //十進制轉二進制
  /*
   算法思想:
     ①利用乘2取余的方法
     ②考慮到是逆序輸出可以用順序棧(后進先出)方式輸出
  */ 
  public static void toBi(int number)
  {
    int[] stack=new int[32];
    int top=-1;//棧頂指針(類似指針功能)
	while(number!=0)
	{
	  stack[++top]=number%2;
	  number/=2;
	}
    while(top!=-1)//出棧
	 System.out.print(stack[top--]);
  }
  //法二,利用java中提供的方法
   public static void toBi_2(int number)
  {
     StringBuffer sb=new StringBuffer();//定義了一個存數據的容器
     while(number!=0)
	{
	  sb.append(number%2);//向容器中添加
	  number/=2;
	}
	System.out.print(sb.reverse());//通過StringBuffer中的reverse功能
					   //逆序輸出
  }
  
  public static void  main(String[] args)  
  {
    toBi(20);
    System.out.println();
    toBi_2(20);
  }
  /*
   該方法只能計算正數
  */
}
toBi
②十進制轉十六進制(利用移位和按位與)
     
class ToHex
{
 //十進制-->十六進制
 /*
   算法思想:
     ①首先該數與低四位為1,其余位為0(15)數相與(&)可得到該數低四位
	 ②使該數右移(>>>)四位,在與15相與又得到四位,依此類推
        知道原數變為0停止
	注意:這里用>>>而不用>>原因是考慮到負數會一直補1,
	      當然可以通過-1(補碼全為1)來決定結束,但無法輸出
		  符號位的十六進制,而>>>可以把負數的符號位也轉成
		  十六進制
 */
  public static void toHex(int number)
  {
     StringBuffer sb=new StringBuffer();//定義了一個存數據的容器
	 int Hex;
     while(number!=0)
	 //for(int i=0;i<8;++i)//強制把32位都轉換:200->0000C8
	{                    //而while則為:C8
	  Hex=number&15;
	  if(Hex>=10)
		sb.append((char)(Hex-10+'A')); 
	  else
		 sb.append(Hex);
	  number >>>= 4;
	}
	System.out.print(sb.reverse());
  }
  
  public static void  main(String[] args)  
  {
    toHex(-200); 
	System.out.println("\n"+Integer.toHexString(-200));
  }
}
ToHex
 
③十進制轉R進制(查表法)
class Convert
{
 //查表法將十進制轉換成R(二,八,十六)進制
 /*
 數組下標:    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
             0 1 2 3 4 5 6 7 8 9  A  B  C  D  E  F  
 包括二進制,八進制,十六進制值恰好對應了數組的下標.
 */
  //二進制
  public static void toOct(int number)
   {
      trans(number,1,1);
   }
 //八進制
   public static void toBi(int number)
   {
      trans(number,7,3);
   }
   //十六進制
   public static void toHex(int number)
   {
      trans(number,15,4);
   }
  public static void trans(int number,int and,int offset)//分別接收原數,需要與的值,
								//需要移位的值
	{
      if(number==0)//為0下面不在執行
	  {
	    System.out.println(0);
		return;
	  }
	  char[] table={'0','1','2','3',
			  '4','5','6','7',
			  '8','9','A','B', 
			  'C','D','E','F'};
	  char[] stack=new char[32];
	  int top=-1;
	  while(number!=0)
		{
	      stack[++top]=table[number & and];
	      number >>>= offset;
	    }
	  while(top!=-1)
	    System.out.print(stack[top--]);
	  System.out.println();
	}                                                         
   public static void main(String[] args)
   {
      toBi(-80);
      toHex(-80);
      toOct(-80);
   }
}
   
ToR
二維數組:
在Java中並沒有真正的多維數組,只有數組的數組,雖然在應用上很像
 C語言中的多維數組,但還是有區別的.在C語言中定義一個二維數組,必須
 是一個x*y的二維矩陣塊.
 而Java中的多維數組並不一定是規則的矩陣形式
定義一個多維數組:
 int[][] xx;//int xx[][],int[] xx[];
 它表示 一個數組引用變量xx,第一個元素變量為xx[0],第n個元素變量為xx[n-1].
 xx中的每個元素變量(xx[0]~xx[n-1])正好又是一個整數類型的數組引用變量.

   int[ ][ ] xx;  
   xx=new int[3][ ];      
   解析:這兩句代碼表示數組xx有三個元素,每個元素都是int[ ]類型的一維數組.相當於定義了三個數組

            引用變量,分別為:int[ ] xx[0],int[ ] xx[1],int[ ] xx[2]. 

  由於xx[0],xx[1],xx[2]都是數組引用變量,必須對它們賦值,指向真正的數組對象.才可以引用這些數組中的

  元素.

xx[0]=new int[3];

xx[1]=new int[2];

另:

二維數組的靜態初始化:

int[ ][ ]  xx={{3,2,7},{1,5},{6}};

另附上 陳吉斯汗同學的關於java數組的總結,個人認為很不錯:http://bdcwl.blog.163.com/blog/static/7652226520091024067604/

示例1: 

復制代碼
class ArrayDemo1 
{
    public static void main(String[] args) 
    {
        int[] arr = new int[2];//建議這種方式,定義一個int型數組的引用變量 arr
        
        int arr[] = new int[2];

        //靜態初始化
        int[] arr = new int[]{3,1};//new int[]中不能指定長度,編譯不能通過
                                       //可能出現元素個數和指定長度不同
    
        int[] arr = {3,1};//靜態初始化簡化形式

        System.out.println(arr[3]);//編譯可以通過,編譯時期沒有創建數組也就是說在運行時期才在堆內存中為數組開辟空間.
                                   //在運行時期發生數組角標越界異常
        arr=null;

        System.out.println(arr.length);//編譯依然可以通過,原因同上.
                                //運行時期發生錯誤,arr不再引用數組,無法操作數組中的元素
                               //發出空指針異常  
      
       //二維數組靜態初始化   
         int[][]a=new int[][]{{4,2},{5,6,7}};//①
        //int[][]a={{4,2},{5,6,7}};//等價於①
    
  }
}
復制代碼
示例2:
復制代碼
class  DoubleArray
{
    public static void main(String[] args) 
    {
        int[][] xx=new int[3][2];//二維數組中的三個元素,每個元素指向一個長度為2的一維數組
        System.out.println("x\t"+xx);//[[代表二維數組,I->Integer(整形),數組中的元素類型
                         //@后面由哈希函數算出哈希址
        System.out.println("x[0]\t"+xx[0]);
        
        
        int[][] y=new int[4][];          
               System.out.println("y\t"+y);
        System.out.println("y[0]\t"+y[0]);
      
           int[][] x=new int[3][];//每個引用數組的長度可以不一樣
                x[0]=new int[3];      //在內存中的情況如下圖:
        x[1]=new int[1];
        x[2]=new int[2];
        
    }
}
復制代碼

二維數組示例

二維數組在內存中:

二維數組

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM