C/C++基礎

C/C++基礎node

轉自:http://blog.csdn.net/fangbaolei2088/article/details/7990519ios

1.編譯器g++
g++ -c 只編譯不鏈接,生成.o文件
g++ -o 修改編譯後生成的文件的名字(默認爲a.out)算法


2.C++優勢
Supporting data abstraction
Object-oriented
Contains all C features
Portable and efficient as C
Can be linked to existing C libraries and functions(!!)
...編程


3.變量名
第一個字母必須是字母或下劃線
只能使用字母或下劃線或數字
中間不能有空格
不能是保留字,不能與庫函數重名
區分大小寫windows

 


4.基本數據類型
char=> unsigned/signed char
int=> unsigned/signed long/short int
float=> double, long double
bool數組

 


5.四個類型轉換算子(詳細見後面)
static_cast: 
const_cast:
reinterpret_cast:
dynamic_cast:數據結構


6.運算符
優先級前三名:() .或-> 單目
優先級後三名: ?: = 逗號app


7.枚舉類型
enum color{RED, BLUE=10, GREEN}; // 默認數值爲0, 1, 2...這樣改變值後爲0, 10, 11...
color c = GREEN;函數


8.表達式(略)this


9.控制語句
if(){}else{}
while(){}
do{}while();
for(){}
switch(){case;}


10.函數
函數三要素:返回類型、函數名、參數表
聲明(無函數體;參數表參數可無參數名,但必須有類型)
定義(有函數體{})
調用函數實際是利用棧操做,執行完一個函數時候,棧釋放
使用默認參數(必須從右至左指定默認值)


11.內聯函數(inline)
編譯時,只是將內聯函數的代碼粘貼到調用處,不進行棧操做,因此速度快
必須聲明與定義放一塊兒
不支持控制語句(因此實際中inline函數不多使用)


12.遞歸函數
函數調用本身
必須有結束條件
棧操做


13.函數重載(overload)
重載函數至少在參數個數、類型、順序上有所不一樣
儘可能不要使用默認參數的函數,防止調用衝突


14.函數參數的const限定
能夠防止在函數中修改某個傳入參數的值


15.變量的做用域與可見性(☆)
局部變量:存於棧;函數調用完釋放;做用域本函數內部
全局變量:存於全局數據區;程序結束釋放;做用域本源文件、其餘源文件使用時加extern聲明
static局部變量:存於全局數據區;只在第一次調用函數時初始化一次;做用域本函數內部
static全局變量:存於全局數據區;程序結束釋放;可見範圍本源文件(其餘源文件不可見)


16.頭文件(.h)
聲明函數
struct
class
enum
extern聲明變量(使用其餘源文件的全局變量)


17.進程空間
Data
Heap
Code
Stack


18.數組
只聲明不初始化時,必須有元素個數
花括號初始化必須與聲明放一塊兒(花括號初始化時,元素個數能夠省去)
花括號後的分號注意
字符數組初始化可用雙引號
好習慣:memset(buf, 0x00, sizeof(buf)); //使用數組、結構時都可如此初始化內存


19.結構(struct)
用結構定義的結構名能夠當成一種新數據類型使用

如:
struct Person{...;};
Person p1; // It's correct
struct Person p2; // It's correct too

注意定義結構時候最後的分號!!
結構之間可賦值
佔用內存空間(Unix/windows下天然對界,結構大小必爲最大成員的整數倍;Linux下只需總體補齊爲int的整數倍)


20.指針
爲防止野指針,通常聲明指針時最好當即賦值(NULL)

注意*號的使用:
聲明時:int* pi = NULL; // 此處星號表示變量pi爲指針類型變量
賦值時:pi = &i; // 此處直接使用pi,pi變量存儲的是地址0x...
使用時:*pi = 5; // 此處星號表示指針所指向的變量i,此語句等同於 i = 5;


21.結構取成員
結構變量取成員:p.id
指向結構的指針取成員:pp->id 或 (*pp).id


22.數組名實際上是常量指針(不可進行自加減)


23.字符串操做(#i nclude )
strcpy(target, source);
strlen();
strcmp(target, source); //相同返回0
strncmp(target, source, n); //比較n個字符
strcat(target, source);


24.C風格字符串與C++風格字符串
C style string: char* or char []
C++ style string: string
(!!!注意:Unix C中,大部分庫函數和系統函數仍是使用C風格字符串)
這兩種字符串能夠相互轉化:
C style to C++ style: string a = b;
C++ style to C style: char* b = a.c_str(); // 使用了c_str()函數,或使用data()函數


25.使用堆空間(heap)進行動態內存分配
int* p = new int[10];
delete[] p; // 只是釋放p指向的內存,釋放後的內存其餘程序可使用,不然內存泄漏
p = NULL; //將p指針賦爲空,防止野指針


26.函數指針
!!!注意:函數指針是一個變量,不是一個函數

如:
void (*pf)(int, int); //pf是一個指針變量,只能指向void f(int, int)類的函數!!!
void f(int a, int b){...}
pf = f; //將f的首地址存入pf變量中!!!

函數指針通常只是用來聲明函數的參數時使用
(即函數fa須要調用另外一個函數fb時,將fb的函數指針放入聲明fa的參數列表中)

如:
int fa(int a, void (*pf)(int, int)){...} //調用函數fa時,只能在第二個參數中傳入一個類型爲指向void f(int, int)函數的指針
void fb(int a, int b){...}
void (*pf)(int, int) = fb;
fa(5, pf);


27.void指針
通常做爲函數聲明時的函數參數,可增長函數通用性
不可進行自加減運算


28.常量指針指針常量
常量指針:const int* p; //p指向的數據不可變(p指向常量)
指針常量:int* const p; //p不可變(必須初始化)


29.引用
引用是一個變量的別名
聲明:int& ri = i;
使用:ri = 5; //至關於使用i自己(i=5)
經常使用來作函數參數傳遞


30.typedef給類型起別名
步驟:
聲明一個變量或函數
把名字改成別名
前加typedef

★C++面向對象特性


1.類
封裝了函數成員的struct
(其實在C++中,struct內部也能夠封裝函數,但習慣上struct只封裝數據,class能夠封裝數據和函數)
增長成員訪問權限(public, private, protected)
類默認的是private(struct默認爲public)
private=> 只能被本類或者友元訪問
protected=> 只能被本類或者友元或者子類訪問
public=>所有公開
外部定義類的成員函數用域做用符(::)
注意分號!!


2.構造函數(constructor)
建立對象時起初始化對象的做用
名字與類同
只能爲public!!
無返回類型!!
可重載!!
沒有時系統自動添加(一旦本身定義,系統再也不添加)
可用冒號(:)引出初始化列表,如:
Person::Person(int a, int b):id(a), age(b){} //將成員id賦值爲a, 將成員age賦值爲b
struct也可使用構造函數


3.拷貝構造函數(copy constructor)
系統默認存在一個拷貝構造函數,對成員依次拷貝(淺拷貝),有指針成員時危險
用一個已有對象對同類其餘對象進行初始化
Person(const Person& pa);
使用:Person p2(p1); //至關於將p1全部成員賦值給p2


4.析構函數(destructor)
~類名(){}
無返回類型!!
不可重載!!
無參數!!
系統自動調用
作清理工做


5.繼承
繼承方式public, protected, private
class Derived:public Base{};
子類繼承父類的全部成員,可是不能訪問父類的private成員
public繼承來的成員屬性不變
protected繼承來的成員public變爲protected,其餘不變
private繼承來的所有變爲private

繼承中的構造函數,系統先調用父類再調用子類
子類
的構造函數能夠給父類的構造函數傳遞參數,如:
Person::Person(int a, int b):id(a), age(b){}
Student::Student(int a, int b, int c):Person(a, b), grade(c){} //給父類的構造函數傳遞參數a, b

繼承中的析構函數,系統先調用子類再調用父類

覆蓋:子類中的函數會覆蓋父類中的同名函數


6.多態與虛函數
爲解決覆蓋問題,將父類的函數聲明爲virtual型(虛函數),子類中再定義同名的函數
則使用指向父類指針指向子類對象時,調用該函數時,可自動識別對象類型,調用相應的子類中的函數
如:
virtual void Person::display(){cout << "Person" << endl;} //聲明爲virtual函數
void Student::display(){cout << "Student" << endl;}
Person* p = new Student;
p->display(); //調用子類的display
顯示爲「Student」


7.純虛函數
若要父類的函數爲空,只爲了使用多態時,能夠聲明爲純虛函數
virtual void display() = 0;


8.多重繼承與虛繼承(菱形繼承)(不經常使用)


9.類型轉換算子詳解
static_cast:void指針與其餘類型指針間轉換
const_cast:常量與變量之間轉換
reinterpret_cast:指針與整型數據之間轉換;任意類型指針之間轉換
dynamic_cast:用於有繼承關係且有虛函數的類之間的轉換,子轉父才能成功
格式:xxxx_cast(data)


10.抽象數據類型ADT
抽象類不能建立對象


11.友元(friend)
受權本類外部的函數或其餘類可使用本類的全部成員(包括private成員),使用時要用「對象.xxxx」


12.常量成員函數
類的成員函數參數列表後加上const,表示本函數爲常量成員函數,不能修改本類的成員,如:
void display()const{} //display中不能修改本類的成員數據


13.靜態成員
靜態數據成員:全部對象使用一份數據;初始化放類外邊(::);訪問也用(::)
靜態函數成員:至關於全局函數;只能訪問靜態數據成員;定義放類外邊(::);訪問用(::)


14.運算符重載
將「operator...」當作函數名,進行定義
返回類型不能爲空!!
方法:成員或友元(儘可能成員)
不能改變運算符的操做數(括號例外,括號的操做數特殊)
不能重載的運算符: . .* :: ?: sizeof # ##
操做基本類型的運算符不能重載(即運算符的操做數中至少應該有一個是自定義類型,如類)

只能用成員函數重載的:operator= operator[] operator() operator-> operator->*
成員函數重載時,默認的第一個操做數老是對象自己!!!因此參數列表的第一個操做數能夠省去!!!

只能用友元函數重載的:operator<< operator>>
當第一個操做數非對象自己時,應使用友元!!!

下面詳細介紹幾個運算符的重載:

▲operator=
當類沒有自定義operator=時,編譯器自動生成一個,有指針成員時候危險
只能成員函數重載
經常使用格式:
A& operator=(const A& ao)
{
if (this == &ao) return *this; //判斷this指針是否指向ao對象的地址
...=...;
*..=*..; //指針成員賦值其指向的變量
return *this;
}

▲operator++() and operator++(int) 前加與後加
定義這兩個函數後,使用++a時調用前者,使用a++時調用後者
啞元區分
前加加的格式:
A& operator++() //使用引用
{
...++;
...++;
return *this;
}
後加加的格式:
A operator++(int dummy) //不能使用引用
{
A temp = *this;
...++;
...++;
return temp; //返回自加以前的值
}

▲雙目運算符
做爲成員函數重載時,第一個操做數必須是對象自己,且在參數列表中能夠省去!!
當第一個操做數非對象自己時,應用友元法!!

▲operator()
特殊,操做數的個數不肯定
使用時候相似函數,稱爲functor(仿函數),實際功能比函數還要強大

▲operator new/delete
較特殊,格式固定
static void* operator new(size_t sz){} //必須是static,返回void*
static void operator delete(void*){}
new和delete可同時帶上[]

▲轉換運算符
用於將一個對象轉換爲其餘的數據類型
格式較特殊,不寫返回類型(其類型名即爲返回類型)
如:
operator double(){} //將返回double類型變量
使用:
double(ao);

▲operator<< and operator>>
這兩個流操做符必須做爲友元重載
格式較固定:
ostream& operator<< (ostream& o, A& ao)
{
o << .... << .... << ....;
return o;
}

istream& operator>> (istream& i, A& ao)
{
i >> .... >> .... >> ....;
return i;
}

15.main命令行參數模式
int main(int argc, char* argv[])
//argc指命令行參數的個數,包括命令自己
//argv存儲了每一個參數,包括命令自己即argv[0]
//argv爲char*[]型,即char**型,或char[][]型,至關於二維字符數組或一維字符串數組

16.I/O標準流
(cin, cout, cerr, clog)
cin和cout支持緩衝,支持重定向
cerr爲錯誤信息輸出,不支持緩衝,不支持重定向
clog爲日誌輸出,不支持重定向

cin詳解:
cin >> //可連續使用;以空白(包括空格、回車、TAB)爲分隔符
cin.get(char c) //可連續使用;獲取任意單個字符,包括空白
cin.getline(char* buf, sizeof(buf), '\n') //可連續使用;獲取一行,到最後指定的字符結束,可包括空白,默認回車
cin.gcount() //計數
cin.read(char* buf, sizeof(buf)) //可連續使用;讀取指定大小的內容,包括空白;第一個參數必須爲char*,可用強制轉換
cin.ignore(1000, '\n') //忽略指定大小的內容,到制定字符結束忽略;經常使用來清空緩衝區
cin.clear() //清楚錯誤狀態;常後跟ignore
if(!cin) //判斷是否出錯;cin爲false則出錯
cin.peek() //查看緩衝區下一個字符,可是不讀取,即用get時候還能夠讀到
cin.putback() //將上一個讀回的字符返回緩衝區,不經常使用

cout詳解:
cout <<
控制符:endl, flush ....
cout.put(char)
cout.width(int) //一次性命令
cout.fill(char)
cout.precision(int)
cout.setf(ios::...)
cout.unsetf(ios::...)
(cout這些命令不經常使用,經常使用頭文件中的函數代替)

:
setw(int) //設置寬度
setfill(char) //設置填充字符
setprecision(int) //設置精度,單用時表示總位數;與fixed連用時表示小數點後的位數

17.I/O文件流
(需包含頭文件)

ifstream類:
使用:ifstream fin; //建立一個對象fin
cin中可使用的函數在fin中一樣可使用
對cin的擴展:
構造函數能夠制定文件名及打開方式
fin.open(...)
fin.read(...) //較多的使用此函數讀取
fin.is_open() //檢查是否打開成功,事實上常常用 if (!fin) 代替此函數
fin.eof() //判斷是否超過文件末尾;超過末尾才返回true
fin.close() //關閉文件

ofstream類:
使用:ofstream fout;
經常使用打開方式有:ios::binary ios::app ios::out
(其他同上)


經常使用寫/讀格式:
fout.write((char*)&a, sizeof(a)); //將a對象的數據寫入文件;注意強制類型轉換(char*)
fin.read((char*)&b, sizeof(b)); //將文件中的內容讀入到b對象的空間

18.異常(exception)
(#i nclude )
try
{
....;
if (....)
{
throw ....;
....; //不會執行此句
}
}
catch(....)
{
....;
}

注意:
catch捕獲的異常爲與throw同類型的數據
捕獲異常後,程序在catch處理完異常後的地方繼續執行,不會返回throw處
產生異常後,程序當即跳轉,不會執行throw下的語句
若是沒有catch捕獲已經拋出的異常,最終內核捕捉到異常會將程序強制不正常關閉
catch(...)(括號中三個點)能夠捕捉任何類型異常
異常的類型常使用內部類(inner class)來定義

19.內部類
內部類屬於它所在的類的類成員(即類的靜態成員),不屬於某個對象
內部類的數據和它所在的類的數據互不相通

★數據結構


1.鏈表(LinkList)
由節點(node)構成,每一個節點能夠爲一個struct,且該struct裏能夠封裝進構造、析構等函數(並且經常如此)
每一個節點能夠以下定義:
struct Node
{
DATA data; // ADT
Node* next; //指向下一個節點的指針
Node(const DATA d) //構造函數初始化節點
{
data = d;
next = NULL;
}
};

每一個鏈表由一個頭指針head(Node* head;)進行訪問

基本操做:增、刪、查、改

▲插入節點(增):
Node* p = new Node; //分配新節點的空間
p->data = 0; p->next = NULL; //初始化新節點(此兩句能夠封裝到Node的構造函數中)
//尋找要插入位置(即前一個Node的next指向的地址,假設爲lp)
p->next = lp; //把新節點的next指向要插入位置的下一個節點
lp = p; //插入位置的前一個Node的next指向新節點
//插入成功

▲刪除節點(刪):
Node* temp = p->next; //將要刪除節點的next指針(即p的下一個節點的地址)保存
delete p; //刪除p的空間
lp = temp; //p節點的前一個節點的next指向p的下一個節點
//刪除成功

▲查找節點(查):
Node* p = head; //從頭指針開始遍歷
while (p) //p不爲NULL,就繼續遍歷
{
if (p->data == finddata) break;
p = p->next;
}
//缺點:如此查找到的p,只是在值上等於p前一個節點的next的值,而並不是其前一個節點的next自己!!!
//想要獲得前一個節點的next自己也很簡單,只須要再定義一個指針,遍歷時使該指針滯後一步
//如:
Node* p = head;
Node* lp = NULL; //老是滯後p一步
while (p)
{
if (p->data == finddata) break;
lp = p;
p = p->next;
}
//這樣獲得的lp就是p前一個節點的指針,lp->next和p的值應該相等,且lp->next是鏈表中的數據自己!!

▲修改節點(改):略

▲刪除所有節點:
老是刪除頭節點的方法
Node* p = head;
while (p)
{
p = head->next; //將頭節點的下一個節點的地址保存起來
delete head;
head = p;
}
//刪除完成

▲operator[]:略


2.棧(stack)
LIFO(last in first out)
經常使用操做:push(), pop(), isempty(), clear()
(實際使用時,彈棧操做老是分離pop的功能爲top和pop兩個,top只管訪問,pop只管刪除)
能夠用數組或鏈表實現
數組:下標
鏈表:前插前取


3.隊列(queue)
FIFO(first in first out)
能夠用數組或鏈表實現
數組:下標
鏈表:後插前取
優先隊列(priority queue):插入時自動排序


4.二叉樹(binary tree)
集數組和鏈表的優勢:能夠快速查找(數組);能夠方便插入數據(鏈表)
每一個節點最多有兩個子節點
因此每一個節點包含兩個節點指針left和right
struct bNode
{
DATA data;
bNode* left;
bNode* right;
bNode(const DATA d) //constructor
{
data = d;
left = NULL;
right = NULL;
}
};

經過一個指向根節點root的指針(bNode* root;)訪問
通常經過遞歸實現操做!!


5.二叉查找樹(binary search tree)
左子節點(包括子節點的子節點)必定小於父節點
右子節點(包括子節點的子節點)一點大於或等於父節點

經常使用操做:增、遍歷、刪、查、改
通常均用遞歸法實現!!

▲插入節點(增):
void insert(bNode*& ptr, bNode* pnew) //ptr爲樹的待插入位置(必須使用指針的引用!!),pnew爲待插入節點
{
if (ptr == NULL) //當樹爲空時;實爲遞歸出口!!
{
ptr = pnew;
}
else if (pnew->data < ptr->data) //插入數據比該位置的數據小的時候,往左側插入
{
insert(ptr->left); //遞歸調用
}
else //插入數據比該位置的數據大於或等於的時候,往右側插入
{
insert(ptr->right); //遞歸調用
}
}
//插入成功


▲遍歷:
void visit(bNode* ptr) //待遍歷節點的指針,第一次調用時傳入root指針
{
if (ptr == NULL) return; //遞歸出口
visit(ptr->left); //遞歸調用,遍歷左側
cout << ptr->data << endl; //輸出本節點的內容
visit(ptr->right); //遞歸調用,遍歷右側
}
//遍歷完成


▲清空二叉樹:
void clear(bNode*& ptr) //待清空的節點的指針(必須使用指針的引用!!),第一次調用時傳入root指針
{
if (ptr == NULL) return;
clear(ptr->left);
clear(ptr->right);
delete ptr;
ptr = NULL;
}
//清空成功


▲刪除一個節點(刪):
刪除二叉查找樹的一個節點較麻煩,經常使用方法有兩種:降級法和替換法

降級法:將刪除的節點的左子樹掛入其右子樹下邊
替換法:將刪除的機電的左子樹下面最大的節點替換掉刪除的節點

降級法實現代碼:
void deleteNode(bNode*& ptr) //待刪除的節點的指針的引用!!
{
bNode* p = ptr; //先將該節點的地址保存,以備後用
insert(ptr->left, ptr->right); //將左子樹掛到右子樹下面(參考insert函數)
ptr = ptr->right;
delete p; //刪除節點的空間,用到剛纔保存地址的p,由於此時ptr已經改變
}
//刪除完成

替換法實現代碼:
先寫查找左子樹下邊最大節點的函數:
bNode*& findmax(bNode*& ptr) //返回類型必須爲引用!!!
{
if (ptr->right == NULL) return ptr; //遞歸出口
findmax(ptr->right);
}
void deleteNode(bNode*& ptr)
{
bNode* p = ptr;
bNode*& pmaxref = findmax(ptr->left); //此處也必須使用引用!!!
bNode* pmax = pmaxref; //將pmaxref指向的節點的地址保存到pmax
pmaxref = NULL; //將左子樹最大節點從樹上摘下!!注意,操做的是引用!!!
ptr = pmax; //將要刪除的節點的位置改成左子樹最大節點;注意,操做的ptr爲引用!!!
pmax->left = p->left;
pmax->right = p->right;
}
//刪除完成

▲修改一個節點(改):先刪除再插入

6.算法(algorithm)
算法分析、效率、時間複雜度、空間複雜度
大O表示法(Big O Notation):最多多少次
算法設計策略:蠻力法、遞歸法、貪心法等
查找:線性查找、二分法查找、索引查找
排序:選擇排序、插入排序、冒泡排序、快速排序、希爾排序

排序方法詳解:(按降序爲例)

▲選擇排序:
思路:第一輪排序將全部元素中最大的放在第一個,而後下一輪排序將剩餘元素中最大的放到剩餘元素的第一個,而後......
方法:雙循環或遞歸

▲插入排序:
思路:認爲第一個元素已經排好序,而後看下一個元素,若是比第一個大則排到其前邊,不然排後邊,依次下去......
實現起來較複雜

▲冒泡排序:
思路:每輪只比較相鄰元素大小,前小後大則交換位置,這樣比較多輪之後,直到再也不發生任何交換時,排序結束
最慢的排序方法

▲快速排序:
思路:選出一個分界值(pivot),將大於分界值的移到左側,小於分界值的移到右側,通常可使用遞歸
具體實現方法多種

▲庫函數中的快速排序:(#i nclude ) (qsort)
qsort(int*, length, sizeof(int), (*compare));
//參數表依次爲待排序的數組首地址、數組長度、數組的元素大小、比較函數的首地址
//比較函數須要本身定義

★自定義模板與標準模板庫

1.自定義模板
使用模板是爲了泛型編程
分爲函數模板和類模板
定義模板時:
template //模板頭;typename關鍵字可用class代替
...{} //函數體或類體中,能夠將符號T當成一種數據類型

使用模板時:

函數模板能夠根據傳入參數的類型,自動識別類型
類模板須要將參數用尖括號傳遞:vector vi;

2.標準模板庫(STL)
標準模板庫包含如下內容:
container(容器)
algorithm(算法)
iterator(迭代器)
functor(仿函數)
adapter(容器配接器)
allocator(分配器)


3.container(容器)
用於存放一系列數據
分爲Sequence Container和Associative Container兩種
(序列式容器和關聯式容器)

全部容器的共性:

都有三種構造函數(無參、拷貝、區間)
支持運算符:賦值(=)、比較(< <= > >= == !=)
支持交換函數swap(),對兩個容器進行交換(s1.swap(s2);)
支持的操做:insert, erase, clear, empty(判斷非空), size
都有四種迭代器:iterator, reverse_iterator, const_iterator, const_reverse_iterator
迭代器相關函數:begin, end, rbegin, rend


4.iterator(迭代器)
迭代器是一個容器的內部類,只封裝了一個指針
外部訪問容器的元素時,能夠經過迭代器訪問,因此迭代器的做用就是智能指針
迭代器內部重載的運算符通常有星號(*)、不等於(!=)、自加(++)、自減(--)四個運算符

迭代器與其所在的類的橋樑是一些迭代器相關函數(begin,end,rbegin,rend)等,帶r的是反向

使用方法:

類名::iterator it; //聲明一個迭代器對象
for (it=對象.begin; it!=對象.end; it++) {...} //以此來遍歷一個容器


5.Sequence Container(序列式容器)
包括三種:vector, deque, list

▲序列式容器的共性:
構造函數能夠指定個數及初始值
增長了resize(len)或resize(len, fillVal)
增長了insert(position, num, data)
增長了assign(num, data)
增長了取首尾函數:front(), back() (返回引用)
增長了後增刪函數:push_back(data), pop_back()


▲vector:(#i nclude )
vector其實就是一個動態數組
支持[] (不檢查越界)
支持at() (越界拋異常)
增長了capacity()函數 (容量)(有時!=size())
增長了reserve(len)函數 (調整容量)
用後插後取時效率較高


▲deque:(#i nclude )
deque實際上是vector的加強版
增長了前增刪函數:push_front(data), pop_front()
比vector減小了capacity和reserve函數


▲list:(#i nclude)
list實際上是一個雙向鏈表
不支持 [] 和 at()
只支持雙向迭代器(++ --),不支持隨機迭代器(+n -n)
增長了remove(data)(刪除全部data節點)
增長了sort()(升序排序)
增長了reverse()(顛倒順序)
增長了unique()(去掉相鄰的重複元素,變爲一個)
增長了merge(list2)(將list2保序合併到當前的list,list2變空,合併後排好序)
增長了splice(it, list2, list2.it1, list2.it2)(將list2中的區間轉移到當前list的指定位置)
list適用於元素頻繁插入刪除的時候使用


6.Associative Container(關聯式容器)
包括兩種:map/multimap, set/multiset

▲關聯式容器的共性:
實質爲二叉查找樹
可自動排序(要求容器元素的類型必須支持小於運算符)
每一個元素都有一個key值
增長了insert(data)(不需指定位置)
增長了find(key)(返回第一個;若查不到,返回end())
增長了erase(key)(刪除全部關鍵字爲key的元素)
增長了count(key)
增長了lower_bound(key), upper_bound(key)
增長了equal_range(key)


▲map/multimap:(#i nclude


▲map/multimap插入元素方法:
插入對有四種方法:
insert(map::value_type("ABC", 100));
insert(pair("ABC", 100));
insert(make_pair("ABC", 100));
["ABC"] = 100;
(上述"ABC"爲key, 100爲value)
(注意:value_type爲map類內部的函數)
(注意:pair爲標準模板庫中的一個類模板,其元素爲first, second)
(注意:make_pair爲標準庫函數中的函數)
(注意:方括號運算符當心使用:若"ABC"不存在,則插入新的;若"ABC"已存在,在map中修改,在multimap中仍然插入新的)


▲set/multiset:(#i nclude )
每一個元素只由一個key組成
set與multiset區別:同上

7.adapter(容器配接器)
#i nclude ==> stack
#i nclude ==> queue pqueue

使用:push(), pop, size(), empty()

8.algorithm(算法)#i nclude ==> for_each find sort copy replace#i nclude ==> min max accumulate swap

相關文章
相關標籤/搜索