數據結構和算法(04)---數組,動態內存,vector(c++)

文章目錄

  • 目錄
    • 數組
      • 1.數組的申明
      • 2.數組的初始化
      • 3.二維數組
      • 4.指向數組的指針
      • 5.傳遞數組給函數
    • 動態內存
      • 1.new ,delete運算符
      • 2.數組的動態內存分配
    • vector
      • 1.vector基本操作
      • 2.vector使用
      • 3.vector動態二維數組 初始化和賦值

目錄

  • 數據結構:
    • 邏輯結構:數組,棧,隊列,字符串,樹,圖
    • 存儲結構:順序存儲,鏈式存儲
  • C++常用的數據結構有:string , stack , queue , deque , vector , list , map , iterators.

數組

1.數組的申明

在這里插入圖片描述
在這里插入圖片描述

#include <iostream>
using namespace std;#include <iomanip>
using std::setw;int main ()
{int n[ 10 ]; // n 是一個包含 10 個整數的數組// 初始化數組元素          for ( int i = 0; i < 10; i++ )n[ i ] = i + 100; // 設置元素 i 為 i + 100cout << "Element" << setw( 13 ) << "Value" << endl;// 輸出數組中每個元素的值                     for ( int j = 0; j < 10; j++ )cout << setw( 7 )<< j << setw( 13 ) << n[ j ] << endl;}

運行結果:

Element Value
0 100
1 101
2 102
3 103
4 104
5 105
6 106
7 107
8 108
9 109

2.數組的初始化

(1)Array 直接初始化 char 數組是特殊的,這種初始化要記得字符是以一個 null 結尾的

char a1[] = {'C', '+', '+'};          // 初始化,沒有 nullchar a2[] = {'C', '+', '+', '\0'};    // 初始化,明確有 nullchar a3[] = "C++";                    // null 終止符自動添加
const char a4[6] = "runoob";          // 報錯,沒有 null 的位置

a4 是錯誤的,雖然 a4 包括 6 個直接字符,但是 array 大小是 7:6個字符 + 一個null。正確的是:

const char a4[7] = "runoob";

(2)Array 是固定大小的,不能額外增加元素.當我們想定義不固定大小的字符時,可以使用 vector(向量) 標準庫

#include <iostream>
#include <vector>
using namespace std;int main() {// 創建向量用于存儲整型數據vector<int> vec; int i;// 顯示 vec 初始大小cout << "vector size = " << vec.size() << endl;// 向向量 vec 追加 5 個整數值for(i = 0; i < 5; i++)vec.push_back(i);// 顯示追加后 vec 的大小cout << "extended vector size = " << vec.size() << endl;
}

vec 的大小隨著 for 循環的輸入而增大。

執行以上代碼,輸出結果:
vector size = 0
extended vector size = 5

(3)動態數組

動態數組指的是在數組使用的時候才分配存儲空間,而不是像靜態數組那樣一開始就分配好存儲空間的。

靜態 int array[100];   定義了數組 array,并未對數組進行初始化靜態 int array[100] = {12};  定義并初始化了數組 array動態 int* array = new int[100]; delete []array;  分配了長度為 100 的數組 array動態 int* array = new int[100]{12};  delete []array; 為長度為100的數組array初始化前兩個元素

3.二維數組

多維數組最簡單的形式是二維數組。一個二維數組,在本質上,是一個一維數組的列表。聲明一個 x 行 y 列的二維整型數組,形式如下:

type arrayName [ x ][ y ];

其中,type 可以是任意有效的 C++ 數據類型,arrayName 是一個有效的 C++ 標識符。

一個二維數組可以被認為是一個帶有 x 行和 y 列的表格。下面是一個二維數組,包含 3 行和 4 列:
在這里插入圖片描述
初始化二維數組

int a[3][4] = {  {0, 1, 2, 3} ,   /*  初始化索引號為 0 的行 */{4, 5, 6, 7} ,   /*  初始化索引號為 1 的行 */{8, 9, 10, 11}   /*  初始化索引號為 2 的行 */
};

內部嵌套的括號是可選的

int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

訪問二維數組元素

#include <iostream>
using namespace std;int main ()
{// 一個帶有 5 行 2 列的數組int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};// 輸出數組中每個元素的值                      for ( int i = 0; i < 5; i++ ){ for ( int j = 0; j < 2; j++ ){cout << "a[" << i << "][" << j << "]: ";cout << a[i][j]<< endl;}} 
}

a[0][0]: 0
a[0][1]: 0
a[1][0]: 1
a[1][1]: 2
a[2][0]: 2
a[2][1]: 4
a[3][0]: 3
a[3][1]: 6
a[4][0]: 4
a[4][1]: 8

4.指向數組的指針

數組名是一個指向數組中第一個元素的常量指針(無法對數組名重新賦值)。因此,在下面的聲明中:

double balance[50];

balance 是一個指向 &balance[0] 的指針,即數組 balance 的第一個元素的地址。因此,下面把 p 賦值為 balance 的第一個元素的地址:

double *p;
double balance[10];p = balance;
  • 使用數組名作為常量指針是合法的,反之亦然。因此,*(balance + 4) 是一種訪問 balance[4] 數據的合法方式。
  • 一旦您把第一個元素的地址存儲在 p 中,您就可以使用 * p、* (p+1)、* (p+2) 等來訪問數組元素
#include <iostream>
using namespace std;int main ()
{// 帶有 5 個元素的雙精度浮點型數組double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};double *p;p = balance;// 輸出數組中每個元素的值cout << "使用指針的數組值 " << endl; for ( int i = 0; i < 5; i++ ){cout << "*(p + " << i << ") : ";cout << *(p + i) << endl;}cout << "使用 balance 作為地址的數組值 " << endl;for ( int i = 0; i < 5; i++ ){cout << "*(balance + " << i << ") : ";cout << *(balance + i) << endl;}return 0;
}

使用指針的數組值
*(p + 0) : 1000
*(p + 1) : 2
*(p + 2) : 3.4
*(p + 3) : 17
*(p + 4) : 50
使用 balance 作為地址的數組值
*(balance + 0) : 1000
*(balance + 1) : 2
*(balance + 2) : 3.4
*(balance + 3) : 17
*(balance + 4) : 50

5.傳遞數組給函數

  • C++ 不允許向函數傳遞一個完整的數組作為參數
  • 但是,您可以通過指定不帶索引的數組名來傳遞一個指向數組的指針。

如果您想要在函數中傳遞一個一維數組作為參數,您必須以下面三種方式來聲明函數形式參數,這三種聲明方式的結果是一樣的,因為每種方式都會告訴編譯器將要接收一個整型指針。同樣地,您也可以傳遞一個多維數組作為形式參數

方式1: 形式參數是一個指針

void myFunction(int *param){ }

方式2:形參為一個已經定義了大小的數組

void myFunction(int param[10]){ }

方式3: 形式參數是一個未定義大小的數組

void myFunction(int param[]){ }

實例:把數組作為參數,同時還傳遞了另一個參數,根據所傳的參數,會返回數組中各元素的平均值

#include <iostream>
using namespace std;// 函數聲明
double getAverage(int arr[], int size);int main ()
{int balance[5] = {1000, 2, 3, 17, 50};  // 帶有 5 個元素的整型數組double avg;avg = getAverage(balance, 5) ;          // 傳遞一個指向數組的指針作為參數   cout << "平均值是:" << avg << endl;    // 輸出返回值
}double getAverage(int arr[], int size)
{int    i, sum = 0;       double avg;          for (i = 0; i < size; ++i)sum += arr[i];avg = double(sum) / size;return avg;
}

平均值是:214.4

動態內存

了解動態內存在 C++ 中是如何工作的是成為一名合格的 C++ 程序員必不可少的。C++ 程序中的內存分為兩個部分:

  • 棧:在函數內部聲明的所有變量都將占用棧內存。
  • 堆:這是程序中未使用的內存,在程序運行時可用于動態分配內存。

很多時候,您無法提前預知需要多少內存來存儲某個定義變量中的特定信息,所需內存的大小需要在運行時才能確定。

  • 在 C++ 中,您可以使用特殊的運算符為給定類型的變量在運行時分配堆內的內存,這會返回所分配的空間地址。這種運算符即 new 運算符。
  • 如果您不需要動態分配內存,可以使用 delete 運算符,刪除之前由 new 運算符分配的內存。

1.new ,delete運算符

在這里插入圖片描述

#include <iostream>
using namespace std;int main ()
{double* pvalue  = NULL; // 初始化為 null 的指針pvalue  = new double;   // 為變量請求內存*pvalue = 29494.99;     // 在分配的地址存儲值cout << "Value of pvalue : " << *pvalue << endl;delete pvalue;         // 釋放內存
}

Value of pvalue : 29495

2.數組的動態內存分配

在這里插入圖片描述
二維數組

二維數組其實可以看成2個一維的數組,所以初始化也需要分成2步來初始化,先初始化行,然后初始化列。

int **array
// 假定數組第一維長度為 m, 第二維長度為 n// 動態分配空間
array = new int *[m];  //初始化行
//對每行初始化列
for( int i=0; i<m; i++ )
{array[i] = new int [n]  ;
}//釋放
for( int i=0; i<m; i++ )
{delete [] arrar[i];
}
delete [] array;

實例

#include <iostream>
using namespace std;int main()
{int **p;   int i,j;   //p[4][8] //開始分配4行8列的二維數據   p = new int *[4];for(i=0;i<4;i++)p[i]=new int [8];for(i=0; i<4; i++){for(j=0; j<8; j++)p[i][j] = j*i;}   //打印數據   for(i=0; i<4; i++){for(j=0; j<8; j++)     {   if(j==0) cout<<endl;   cout<<p[i][j]<<"\t";   }}   //開始釋放申請的堆   for(i=0; i<4; i++){delete [] p[i];   }delete [] p;   
}

運行結果:

0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7
0 2 4 6 8 10 12 14
0 3 6 9 12 15 18 21

vector

1.vector基本操作

在c++中,vector是一個十分有用的容器。

  • 作用:它能夠像容器一樣存放各種類型的對象,簡單地說,vector是一個能夠存放任意類型的動態數組,能夠增加和壓縮數據。
  • vector在C++標準模板庫中的部分內容,它是一個多功能的,能夠操作多種數據結構和算法的模板類和函數庫。
    在這里插入圖片描述

實例

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> vec;  // 創建一個向量存儲 intint i;cout << "vector size = " << vec.size() << endl; // 顯示 vec 的原始大小for(i = 0; i < 5; i++)  // 推入 5 個值到向量中vec.push_back(i);cout << "extended vector size = " << vec.size() << endl;  // 顯示 vec 擴展后的大小for(i = 0; i < 5; i++)cout << "value of vec [" << i << "] = " << vec[i] << endl; // 訪問向量中的 5 個值// 使用迭代器 iterator 訪問值vector<int>::iterator  v  = vec.begin();while( v != vec.end()) {cout << "value of v = " << *v << endl;v++;}
}

vector size = 0
extended vector size = 5
value of vec [0] = 0
value of vec [1] = 1
value of vec [2] = 2
value of vec [3] = 3
value of vec [4] = 4
value of v = 0
value of v = 1
value of v = 2
value of v = 3
value of v = 4

2.vector使用

特別注意

  • 1、如果你要表示的向量長度較長(需要為向量內部保存很多數),容易導致內存泄漏,而且效率會很低;
  • 2、Vector作為函數的參數或者返回值時,需要注意它的寫法:
    double Distance(vector< int >&a, vector< int >&b) 其中的“&”絕對不能少!!!
  • 3.vector的元素不僅僅可以是int,double,string,還可以是結構體,但是要注意:結構體要定義為全局的,否則會出錯。

算法

1.使用reverse將元素翻轉,需要頭文件#include< algorithm >

reverse(vec.begin(),vec.end());  //將元素翻轉,即逆序排列!

在vector中,如果一個函數中需要兩個迭代器,一般后一個都不包含

2.使用sort排序:需要頭文件#include< algorithm >,

sort(vec.begin(),vec.end());  //默認是按升序排列,即從小到大

可以通過重寫排序比較函數按照降序比較,如下:

//定義排序比較函數:
bool Comp(const int &a,const int &b)
{return a>b;
}//調用時
sort(vec.begin(),vec.end(),Comp) //這樣就降序排序

3.vector動態二維數組 初始化和賦值

一維數組

#include <iostream> 
#include <vector>     
using namespace std;int main()  
{  vector<int> v={1,2,3};cout<<v[2]<<endl;v.push_back(3);cout<<v[3]<<endl;
}

3
3

二維數組
(1)第1種方法:通過 resize( ) 的形式改變行列數

#include <iostream>
#include <vector>
using namespace std;int main()
{int array_temp[4][4]={1,2,8,9,2,4,9,12,4,7,10,13,6,8,11,15};int i,j;//得到一個 4行4列的數組,通過resize()的形式改變行列數vector<vector<int> > array(4);for(i=0;i<array.size();i++)array[i].resize(4);for(i = 0; i < array.size(); i++){for (j = 0; j < array[0].size();j++)array[i][j] = array_temp[i][j];}cout<<array[2][3]<<endl;
}

(2)第2種方法:通過 push_back( )

#include <iostream>
#include <vector>
using namespace std;int main()
{int array_temp[4][4]={1,2,8,9,2,4,9,12,};int i,j;vector<vector<int> > array;vector<int> a;vector<int> b;for(i=0;i<4;i++)a.push_back(array_temp[0][i]);for(i=0;i<4;i++)b.push_back(array_temp[1][i]);cout<<"a[1]="<<a[1]<<endl;cout<<"b[2]="<<b[2]<<endl;array.push_back(a);array.push_back(b);cout<<array.size()<<endl;cout<<array[0].size()<<endl;cout<<array[1][2]<<endl;}

(3)第3種方法: 使用vector < int* > v1;

#include <iostream> 
#include <vector>     
using namespace std;int main()  
{  int out[3][2] = { 1, 2,   3, 4,  5, 6 };  vector <int*> v1;   //相當于每一行是一個一維的數組,每個元素保存的是該數組的第一個元素地址// vector <vector<int>> v1;  //這樣是錯誤的v1.push_back(out[0]);  //壓入第一行元素  v1.push_back(out[1]);  v1.push_back(out[2]);  cout << v1[0][0] << endl; //1  cout << v1[0][1] << endl; //2  cout << v1[1][0] << endl; //3  cout << v1[1][1] << endl; //4  cout << v1[2][0] << endl; //5  cout << v1[2][1] << endl; //6  }  

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/445443.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445443.shtml
英文地址,請注明出處:http://en.pswp.cn/news/445443.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構和算法(05)---鏈表(c++)

文章目錄目錄鏈表的基本概念1.數組和鏈表鏈表的使用1.鏈表的簡單使用2.鏈表的進階使用3.鏈表的高階使用4.鏈表的其他操作鏈表容器list1.list介紹2. list使用3. list與vector之間的區別4.list例子代碼目錄 數據結構&#xff1a; 邏輯結構&#xff1a;數組&#xff0c;棧&#xf…

論文閱讀 狀態壓縮

狀態壓縮 Abstract 信息學發展勢頭迅猛&#xff0c;信息學奧賽的題目來源遍及各行各業&#xff0c;經常有一些在實際應用中很有價值的問題被引入信息學并得到有效解決。然而有一些問題卻被認為很可能不存在有效的(多項式級的)算法&#xff0c;本文以對幾個例題的剖析&#xf…

數據結構和算法(06)---二叉樹(c++)

文章目錄目錄二叉樹1.二叉樹的基本概念2.二叉樹的應用和時間復雜度3.二叉樹的插入4.二叉樹的查找5. 二叉樹的遍歷6.二叉樹的刪除二叉樹的基本操作1.二叉樹的基礎操作2.代碼實現創建二叉樹和三種遍歷二叉樹的方法目錄 數據結構&#xff1a; 邏輯結構&#xff1a;數組&#xff0c…

如何轉載CSDN博客

前言 對于喜歡逛CSDN的人來說&#xff0c;看別人的博客確實能夠對自己有不小的提高&#xff0c;有時候看到特別好的博客想轉載下載&#xff0c;但是不能一個字一個字的敲了&#xff0c;這時候我們就想快速轉載別人的博客&#xff0c;把別人的博客移到自己的空間里面&#xff0c…

程序員歌曲推薦

更多的時候&#xff0c;不光是電腦和鍵盤陪著我們度過一天&#xff0c;耳機和音樂也成了IT人生活中必不可少的一部分 上班和下班的路上&#xff0c;心情失落時&#xff0c;失眠時&#xff0c;甚至是工作時都可能會聽音樂&#xff0c;讓音樂為我們療傷&#xff0c;讓精神得以放…

如何在博客內添加音樂

<center> <iframe border"0" width"480" height"640" src"//music.163.com/outchain/player?type0&amp;id448977181;auto1&amp;height430"> </iframe> </center> 將代碼復制到markdown編輯器里&am…

CSDN寫博客(字體顏色、大小)

markdown里面的標記語言可以使用標簽對來實現對文本文字顏色大小信息的控制。下面給出幾個實例&#xff1a; 黑體字示例 微軟雅黑示例 華文彩云示例 color#00ffff size可以根據實際大小進行設置&#xff0c;一般不超過7。 紅色字體CSDN 紅色字體CSDN 使用十六進制顏色值 …

bose qc30 安靜的城市是什么樣子

使用感受 網友1&#xff08;20歲&#xff09;&#xff1a; 當你帶著這個耳機聽音樂的時候&#xff0c;有一種感覺&#xff0c;感覺這個世界都是你歌曲里的MV&#xff0c;這個枯燥乏味的世界都被賦予了你心中的那份情感&#xff0c;這種感覺&#xff0c;真的很棒 網友2&#…

DeepLearning.ai 提煉筆記(5-1)-- 循環神經網絡

參考博客 Class 5: 序列模型Sequence Models Week 1: 循環神經網絡RNN (Recurrent) 文章目錄Class 5: 序列模型Sequence ModelsWeek 1: 循環神經網絡RNN (Recurrent)目錄序列模型-循環神經網絡1.序列模型的應用2.數學符號3.循環神經網絡模型傳統標準的神經網絡循環神經網絡的…

常見人工智能比賽平臺總結

目錄1.kaggle比賽1.1 kaggle比賽是什么&#xff1f;1.2 為什么舉辦kaggle比賽&#xff1f;1.3 kaggle比賽形式是什么&#xff1f;1.4 kaggle比賽的獎勵制度是什么&#xff1f;2.阿里天池比賽2.1 阿里天池比賽是什么&#xff1f;2.2 為什么舉辦阿里天池比賽&#xff1f;2.3 阿里…

機器學習模型評分總結(sklearn)

文章目錄目錄模型評估評價指標1.分類評價指標acc、recall、F1、混淆矩陣、分類綜合報告1.準確率方式一&#xff1a;accuracy_score方式二&#xff1a;metrics2.召回率3.F1分數4.混淆矩陣5.分類報告6.kappa scoreROC1.ROC計算2.ROC曲線3.具體實例2.回歸評價指標3.聚類評價指標1.…

kaggle (02) - 房價預測案例(進階版)

房價預測案例&#xff08;進階版&#xff09; 這是進階版的notebook。主要是為了比較幾種模型框架。所以前面的特征工程部分內容&#xff0c;我也并沒有做任何改動&#xff0c;重點都在后面的模型建造section Step 1: 檢視源數據集 import numpy as np import pandas as pd讀…

《Head First設計模式》第二章筆記 觀察者模式

背景 客戶有一個WeatherData對象&#xff0c;負責追蹤溫度、濕度和氣壓等數據。現在客戶給我們提了個需求&#xff0c;讓我們利用WeatherData對象取得數據&#xff0c;并更新三個布告板&#xff1a;目前狀況、氣象統計和天氣預報。 WeatherData對象提供了4個接口&#xff1a; …

libsvm總結

1. 訓練 格式&#xff1a;model libsvmtrain(training_label_vector, training_instance_matrix [, libsvm_options]); 這個函數有三個參數&#xff0c;其中 -training_label_vector:訓練樣本的類標&#xff0c;如果有m個樣本&#xff0c;就是m x 1的矩陣&#xff08;類型必須…

《Head First設計模式》第三章筆記 裝飾者模式

裝飾者模式&#xff08;Decorator Pattern) *利用組合&#xff08;composition&#xff09;和委托&#xff08;delegation&#xff09;可以在運行時實現繼承行為的效果&#xff0c;動態地給對象加上新的行為。 *利用繼承擴展子類的行為&#xff0c;是在編譯時靜態決定的&#x…

機器學習中如何解決數據不平衡問題?

文章目錄目錄什么是數據不平衡問題&#xff1f;數據不平衡會造成什么影響&#xff1f;如何處理數據不平衡問題&#xff1f;1、重新采樣訓練集1.1隨機欠抽樣1.2.基于聚類的過采樣2.使用K-fold交叉驗證3.轉化為一分類問題4.組合不同的重采樣數據集5.用不同比例重新采樣6.多模型Ba…

《Head First設計模式》第四章筆記 工廠模式

之前我們一直在使用new操作符&#xff0c;但是實例化這種行為并不應該總是公開的進行&#xff0c;而且初始化經常會造成耦合問題&#xff0c;工廠模式將擺脫這種復雜的依賴&#xff0c;本次內容包括簡單工廠&#xff0c;工廠方法和抽象工廠三種情況。 1 2 3 4 5 6 Duck duck&a…

《Head First設計模式》第五章筆記-單件模式

單件模式 定義&#xff1a;確保一個類只有一個實例&#xff0c;并提供全局訪問點。 編寫格式&#xff1a; 1 2 3 4 5 6 public class MyClass{ private MyClass(){}//構造方法私有化 public static MyClass getInstance(){ //提供全局訪問點 return new My…

處理機器學習大數據的7種方法

文章目錄目錄1.分配更多的內存2.使用較小的樣本3.將數據提交至服務器上4.更改數據格式5.使用數據流方式或者逐行讀入的方法6.使用關系數據庫7.使用大數據平臺目錄 在實際的生產過程中&#xff0c;我們經常會遇到數據文件太大&#xff0c;而無法直接讀入到計算機中進行處理&…

《Head First設計模式》第六章筆記-命令模式

封裝調用-命令模式 命令模式可將“動作的請求者”從“動作的執行者”對象中解耦。 本篇中將不再描述書中所引入的“巴斯特家電自動化公司”的遙控器控制案例&#xff0c;而使用簡單易懂的餐廳案例。 在開始之前&#xff0c;讓我們通過一個現實中的例子來了解命令模式。 理解…