数据结构与算法-数组
數組是應用最廣泛的一種數據結構,常常被植入到編程語言中,作為基本的類型來使用,因此在一些介紹數據結構的文章中,數組沒有被當做一種數據結構單獨拿出來講解。鑒于大家對數組都不陌生,可以將其作為學習數據結構的敲門磚。
數組的優勢在于能夠進行快速的查找,如果知道下標,則可以瞬間將元素取出,但是對于元素的刪除和插入則非常慢。
所以,如果面臨的問題需要對數據進行快速的查找,且很容易獲得下標,此時就可以考慮使用數組對數據進行存儲,因為數組可以非常快速的對數據進行取出。
數組是一個固定大小的由相同類型元素組成的集合。數組可以分為一維數組、二維數組等。在此我們只介紹最常用的兩種一維數組和二維數組。
一維數組
一維數組的聲明:
type arryName[arrySize] type:數組中每個元素的數據類型 arrayName:數組的名字 arrySize:數組的大小例如進行如下聲明:
int array[10]; type:數組類型為整型 arrayName:數組名字為array arraySize:數組大小為10如果我們一開始就知道數組中每個元素的類型,并且知道數組的大小(或者數組的最大容量值)就可以按照如上的方式進行聲明,但是上述方式分配的數組不能改變,即一旦分配完成數組大小不可變,有時候會造成內存的浪費(即申請了比數組長度多的多的內存),所以有時候我們就會根據需要動態申請內存,生成數組。動態申請內存有如下兩種方式:
方式一:使用malloc/free標準庫函數。
方式二:使用new/delete關鍵字
int size; int* intBuffer = new int[size]; ... delete[] intBuffer; //new/delete關鍵字是C++語法特帶的,所以在C語言中不能夠使用new/delete關鍵字,只能使用malloc/free函數。此時使用上述兩種方法,我們申請了長度為size的數組,長度不多不少,并不會造成內存的浪費。但是切記一點一定要對申請的內存進行釋放,否則會造成內存泄漏的,同時如果程序需要頻繁的使用數組,建議不要使用動態分配,因為會產生內存碎片的。
不管我們是直接聲明數組還是進行動態內存分配,其最終我們都需要知道數組的大小,如果我們并不知道數組大小怎么辦呢?此時就需要使用C++ STL庫中的vector替代數組,該容器自身可以動態增長,我們只需要向其內部插入數據即可。
一維數組的初始化:
int array[10] = {};//對數組全部初始化為0 int array[10] = {1,2};//數組前兩個元素進行初始化1和2,其他全部初始化為0 int array[3] = {1,2,3,4};//錯誤,數組越界 int array[5] = {1,,2,3,4};//編譯報錯 int array[5] = {1,2,3,4,}//會報錯。有時候我們也可以不指定數組的大小,對其直接進行初始化 int array[] = {1,2,3,4,5};//在此初始化為一個大小為5的數組,這種方式只能在聲明的時候使用字符數組:
單獨對字符型數組進行說明,是因為字符型數組的最后一位固定是’\0’,所以在定義大小以及聲明的時候要特別注意,不能有越界行為。
一維數組作為函數參數進行傳遞有兩種傳遞方式:數組和指針。但是不論是數組還是指針,歸根結底傳遞的還是指針,因為數組作為函數參數會退化為指針。
1、數組傳遞
int sum(int array[],int size) {//函數體 }對于這種方式的聲明,int array[]是為了提醒用戶,傳遞進去的是一個數組,如果不加后面的大括號int array,我們會以為傳遞的是一個整形值。所以一定要加上這個大括號。此時傳入函數的只是數組的第一個數值,對于數組長度等信息,需要我們單獨使用一個參數進行傳遞。
當然使用數組作為函數參數時,我們也可以指定數組的大小,比如:
int sum(int array[10], int size) {//函數體 }在此我們雖然給出了數組的長度,但是并不代表array就是一個實際的數組,在此array仍然是一個指針。只不過指明傳進來的數組最多只能包含10個元素。
2、指針形式
int sum(int* array, int size) {//函數體 }對于使用指針形式,指針指向數組第一個元素,但是如果想在函數體使用數組長度等信息,我們也需要單獨傳輸。
二維數組
當數組具有兩個下標時,我們認為數組為二維數組,是一個平面結構:
type array[lineCount][rowCount] type:數組中所有元素的數據類型 array:二維數組的名字 lineCount:行數 rowCount:列數二維數組的聲明:
當我們知道二維數組的具體行數和列數時,我們可以進行如下的聲明:
int lineCount = 2; int rowCount = 3; int array[lineCount][rowCount]; //在此聲明一個2行3列的二維數組,數組中每個元素都是整數對于二維數組我們也可以進行動態內存的分配:
int **array; int lineCount = 2; int rowCount = 3; array = new int* [lineCount]; //在此array包含lineCount個整形指針元素,每個指針元素又都可以指向一個一維數組,所以就可以構成一個二維數組。 接下來可以對其進行如下的初始化: for(int i = 0;i < lineCount;i++) {array[i] = new int[rowCount]; }二維數組的初始化:
1、分行初始化:
2、不分行初始化:
int array[2][3] = {1,2,3,4,5,6} 因為數組是分為2行3列,所以在此初始化結果為: 數組第一行結果為:1,2,3。 數組第二行結果為:4,5,6。3、部分元素初始化:
int array[2][3] = {{1,2,3},{4}} 數組第一行結果為:1,2,3 數組第二行結果為:4,0,04、省略第一維的定義,但是不能省略第二維的定義
int array[][3] = {1,2,3,4,5,6} 因為數組列數為3個,所以初始化結果為: 數組第一行結果為:1,2,3 數組第二行結果為:4,5,6 當然在此我們也可以使用如下初始化方法: int array[][3] = {{1,2,3},{4}}字符型二維數組:
字符型二維數組其實可以看成每行都是一個一維的字符型數組,其使用方法和一維字符型數組是一樣的。
二維數組作為函數參數傳遞:二維數組做函數參數傳遞其實和一維數組差不多,也是只有兩種方式,數組和指針。無論數組以什么樣的形態進行傳遞,我們盡量都將其行數和列數作為函數的參數傳遞進去。
1、以數組形式進行傳遞
int out(int a[][3], int lineCount, int rowCount) {//在此其實數組a的列數要<=3。 }2、以全數組的形式進行傳遞、
int out(int a[2][3], int lineCount, int rowCount) { //在此數組a的行數 <= 2,列數 <= 3。 }絕對不允許用以下這種方式進行傳遞:
int out(int a[][],int lineCount,int rowCount) {//在此我們至少需要知道數組a的第二個參數 } int main() {int array[2][3] = {{1,2,3},{4,5,6}};out(array,2,3)//以數組的形式進行傳遞。 }2、以指針的形式進行傳遞:
1、這種方式可以使用下標對數組進行訪問,但是首先必須把數組拷貝進一個動態開辟的二維數組中,并且在使用完之后進行動態釋放。
2、通過二級指針進行訪問:這種方式在函數中不能使用下標訪問數據,但是此種方式可以傳遞任意類型的數組,然后在輸出的時候進行一下類型的強制轉換。(建議大家使用這種方式)
void out(void **a, int lineCount; int rowCount) {for(int i =0;i<lineCount;i++){for(int j=0;j<rowCount;j++){cout<<*((int*)a + i*rowCount + j)<<endl;}} } int main() {int array[2][3] = {{1,2,3},{4,5,6}}out((void**)array,2,3) }總結
以上是生活随笔為你收集整理的数据结构与算法-数组的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构-线性表(栈与队列的特殊性)
- 下一篇: 语言的进步与代码生成