數組深度剖析

 

這裏注意,上面我們說當[]裏的不是整數的時候,編譯器自動取整,可惜我們這裏使用的gcc不支持這個,在Windows下的TC是對此支持的。

一維數組的初始化
給數組賦值除了用賦值語句一個一個賦值以外,還可以採用初始化賦值和動態賦值,數組的初始化是說在數組定義的時候賦值,數組的初始化是在程序編譯階段進行的,這樣減少運行時間、提高效率。
初始化的一般形式:類型說明符 數組名[常量表達式] = {值,值,….值};
例如:
A[3] = {0,1,2};
注意:
1、 可以只給數組中的部分元素賦值,沒有的自動爲0
2、 只能逐個賦值,不可給整個數組賦值
3、 如給全部元素賦值,那麼[]裏的常量表達式可是缺省。

二維數組
二維數組的定義

前面介紹的數組只有一個下標,稱爲一維數組, 其數組元素也稱爲單下標變量。在實際問題中有很多量是二維的或多維的, 因此C語言允許構造多維數組。多維數組元素有多個下標, 以標識它在數組中的位置,所以也稱爲多下標變量。 本小節只介紹二維數組,多維數組可由二維數組類推而得到。二維數組類型說明二維數組類型說明的一般形式是:
  類型說明符 數組名[常量表達式1][常量表達式2]…;
  其中常量表達式1表示第一維下標的長度,常量表達式2 表示第二維下標的長度。例如:
  int a[3][4]; 說明了一個三行四列的數組,數組名爲a,其下標變量的類型爲整型。該數組的下標變量共有3×4個,即:
  a[0][0],a[0][1],a[0][2],a[0][3]
  a[1][0],a[1][1],a[1][2],a[1][3]
  a[2][0],a[2][1],a[2][2],a[2][3]
二維數組在概念上是二維的,即是說其下標在兩個方向上變化, 下標變量在數組中的位置也處於一個平面之中, 而不是象一維數組只是一個向量。但是,實際的硬件存儲器卻是連續編址的, 也就是說存儲器單元是按一維線性排列的。 如何在一維存儲器中存放二維數組,可有兩種方式:一種是按行排列, 即放完一行之後順次放入第二行。另一種是按列排列, 即放完一列之後再順次放入第二列。C語言中是按行排列的。
二維數組的表示方法
 二維數組的元素也稱爲雙下標變量,其表示的形式爲: 數組名[下標][下標]
  其中下標應爲整型常量或整型表達式。例如: a[3][4] 表示a數組三行四列的元素。
  下標變量和數組說明在形式中有些相似,但這兩者具有完全不同的含義。 數組說明的方括號中給出的是某一維的長度,即可取下標的最大值; 而數組元素中的下標是該元素在數組中的位置標識。前者只能是常量, 後者可以是常量,變量或表達式。
  一個學習小組有5個人,每個人有三門課的考試成績。求全組分科的平均成績和各科總平均成績。
  課程 成績姓名 Math C DBASE
  張 80 75 92
  王 61 65 71
  李 59 63 70
  趙 85 87 90
  周 76 77 85
  可設一個二維數組a[5][3]存放五個人三門課的成績。再設一個一維數組v[3]存放所求得各分科平均成績,設變量l爲全組各科總平均成績。編程如下:
  void main()
  {
  int i,j,s=0,l,v[3],a[5][3];
  printf("input score\n");
  for(i=0;i<3;i++){
  for(j=0;j<5;j++)
  { scanf("%d",&a[j]);
  s=s+a[j];}
  v=s/5;
  s=0;
  }
  l=(v[0]+v[1]+v[2])/3;
  printf("math:%d\nc languag:%d\ndbase:%d\n",v[0],v[1],v[2]);
  printf("total:%d\n",l);
  } for(i=0;j<3;i++)
  for(j=0;j<5;j++)
  { scanf("%d",&a[j]);
  s=s+a[j];}
  v=s/5;
  s=0;
  }
  l=(v[0]+v[1]+v[2])/3;
程序中首先用了一個雙重循環。 在內循環中依次讀入某一門課程的各個學生的成績,並把這些成績累加起來, 退出內循環後再把該累加成績除以5送入v之中,這就是該門課程的平均成績。外循環共循環三次,分別求出三門課各自的平均成績並存放在v數組之中。退出外循環之後,把v[0],v[1],v[2]相加除以3即得到各科總平均成績。最後按題意輸出各個成績。
 二維數組的初始化
二維數組初始化也是在類型說明時給各下標變量賦以初值。 二維數組可按行分段賦值,也可按行連續賦值。 例如對數組a[5][3]:
  1.按行分段賦值可寫爲static int a[5][3]={ {80,75,92},{61,65,71},{59,63,70},{85,87,90},{76,77,85} };
  2.按行連續賦值可寫爲static int a[5][3]={ 80,75,92,61,65,71,59,63,70,85,87,90,76,77,85 };
  這兩種賦初值的結果是完全相同的。
  void main()
  {
  int i,j,s=0,l,v[3];
  static int a[5][3]={ {80,75,92},{61,65,71},{59,63,70},
  {85,87,90},{76,77,85} };
  for(i=0;i<3;i++)
  { for(j=0;j<5;j++)
  s=s+a[j];
  v=s/5;
  s=0;
  }
  l=(v[0]+v[1]+v[2])/3;
  printf("math:%d\nc languag:%d\ndbase:%d\n",v[0],v[1],v[2]);
  printf("total:%d\n",l);
}
初始化的額外說明:
  對於二維數組初始化賦值還有以下說明:
  1.可以只對部分元素賦初值,未賦初值的元素自動取0值。
  例如: static int a[3][3]={,,}; 是對每一行的第一列元素賦值,未賦值的元素取0值。 賦值後各元素的值爲: 1 0 02 0 03 0 0
  static int a [3][3]={{0,1},{0,0,2},}; 賦值後的元素值爲 0 1 00 0 23 0 0
  2.如對全部元素賦初值,則第一維的長度可以不給出。
例如: static int a[3][3]={1,2,3,4,5,6,7,8,9}; 可以寫爲:static int a[][3]={1,2,3,4,5,6,7,8,9};

 


 數組的操作
我們這裏主要介紹一維數組的基本操作,至於二位數組的操作與一維數組基本一致,而且二維數組的操作用的很少,所以在這裏我們不會做很詳細的介紹。
 數組中的排序算法
交換排序
交換排序包含冒泡排序(bubble sort)和快速排序(quicksort)。選擇排序包含shaker排序和堆排序(heapsort)。在這裏我們只介紹冒泡排序這也是我們數組排序運用最多最爲廣泛的排序方法。
冒泡排序的基本思想:

冒泡排序(BubbleSort)的基本概念是:依次比較相鄰的兩個數,將小數放在前面,大數放在後面。即在第一趟:首先比較第1個和第2個數,將小數放前,大數放後。然後比較第2個數和第3個數,將小數放前,大數放後,如此繼續,直至比較最後兩個數,將小數放前,大數放後。至此第一趟結束,將最大的數放到了最後。在第二趟:仍從第一對數開始比較(因爲可能由於第2個數和第3個數的交換,使得第1個數不再小於第2個數),將小數放前,大數放後,一直比較到倒數第二個數(倒數第一的位置上已經是最大的),第二趟結束,在倒數第二的位置上得到一個新的最大數(其實在整個數列中是第二大的數)。如此下去,重複以上過程,直至最終完成排序。
由於在排序過程中總是小數往前放,大數往後放,相當於氣泡往上升,所以稱作冒泡排序。

這裏我們不做過多的文字描述了,我們來看一個程序實例:bubble_sort.c
 
 

 

運行結果:

 

選擇排序
基本思想:
每一趟從待排序的數據元素中選出最小(或最大)的一個元素,順序放在已排好序的數列的最後,直到全部待排序的數據元素排完。 選擇排序是不穩定的排序方法。
這裏我們還是來看實例,注意一下,下面我們這個程序來用ubuntu下安裝的eclipse來開發這個程序,下面我們來看:switch_sort.c
我們打開eclipse,在新建工程裏選擇其他:
 

 

選擇C工程:

 

 

注意這裏你必須事先安裝了eclipse的CDT插件,當然你也可以直接下載安裝eclipse的C/C++開發包,
創建項目:
 

 

編輯代碼:

 

 

運行結果:

 

 

數組中的排序算法還有很多,這裏我們不可能都去介紹,上面我們已經給大家介紹了兩種較爲常用的數組的排序算法。

 數組中的查找算法
 遍歷查找
這種查找算法是最普通的查找算法,也是實現最爲簡單的,同時也是相當實用的,在我們不知道待查找的數組是否有序的情況下,用此算法相當常見,雖然此算法顯得有些笨拙,但是很容易使用。
基本思想:思想也很簡單,就是遍歷所有,尋找與之符合的元素即可。該算法一般用於本來無序的序列。
查找一般有幾種情況,查找特定元素、查找最大元素、查找最小元素等。而且查找一般情況下我們需要的結果都有兩種,是否存在?在什麼位置?
這樣我們來舉兩個例子:
查找一個數組中的特定元素,返回該元素的位置,我們設定返回-1時,說明不存在。
我們創建find_ele.c文件:
 

 

我們輸入:669 運行結果爲

 

 

 

下面我們來看查找一個數組中的最大元素,返回這個最大元素,創建find_max.c

 

 

運行結果爲:

 

 折半查找
基本思想:
折半查找的算法思想是將數列按有序化(遞增或遞減)排列,查找過程中採用跳躍式方式查找,即先以有序數列的中點位置爲比較對象,如果要找的元素值小於該中點元素,則將待查序列縮小爲左半部分,否則爲右半部分。通過一次比較,將查找區間縮小一半。 折半查找是一種高效的查找方法。它可以明顯減少比較次數,提高查找效率。但是,折半查找的先決條件是查找表中的數據元素必須有序。


算法描述:
step1. 首先確定整個查找區間的中間位置
  mid = ( left + right )/ 2
  step2. 用待查關鍵字值與中間位置的關鍵字值進行比較;
  若相等,則查找成功
  若大於,則在後(右)半個區域繼續進行折半查找
  若小於,則在前(左)半個區域繼續進行折半查找
  Step3. 對確定的縮小區域再按折半公式,重複上述步驟。最後,得到結果:要麼查找成功, 要麼查找失敗。
折半查找的存儲結構採用一維數組存放。

下面我們還是來看實例,創建binsearch.c
 

 

 

運行結果爲:

 

 

 


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章