2023年程序員面試精選_第1頁
2023年程序員面試精選_第2頁
2023年程序員面試精選_第3頁
2023年程序員面試精選_第4頁
2023年程序員面試精選_第5頁
已閱讀5頁,還剩12頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

程序員經(jīng)典1雙向鏈表的查找節(jié)點(diǎn)。?考點(diǎn):雙向鏈表的操作

出現(xiàn)頻率:★★★★?解析:

使用right指針遍歷,直至找到數(shù)據(jù)為dat(yī)a的節(jié)點(diǎn),假如找到節(jié)點(diǎn),返回節(jié)點(diǎn),否則返回NULL。

1

//查找節(jié)點(diǎn),成功則返回滿足條件的節(jié)點(diǎn)指針,否則返回NULL?2

DbNode

*FindNode(DbNode

*head,

int

data)

//參數(shù)1是鏈表的表頭節(jié)點(diǎn)

3

{

//參數(shù)2是要查找的節(jié)點(diǎn),其數(shù)據(jù)為data?4

DbNode

*pnode

head;?5

6

if

(head

==

NULL)

//鏈表為空時返回NULL

7

{

8

return

NULL;

9

}

10

11

/*找到數(shù)據(jù)或者到達(dá)鏈表末尾退出while循環(huán)*/

12

while

(pnode->right

!=

NULL

&&

pnode->data

!=

data)?13

{?14

pnode

=

pnode->right;

//使用right指針遍歷

15

}?16

17

//沒有找到數(shù)據(jù)為dat(yī)a的節(jié)點(diǎn),返回NULL

18

if

(pnode->right

==

NULL)?19

{?20

return

NULL;?21

}

22?23

return

pnode;?24

}2考點(diǎn):模板的特化的理解

出現(xiàn)頻率:★★★?解析:

模板的特化(template

specialization)分為兩類:函數(shù)模板的特化和類模板的特化。?(1)函數(shù)模板的特化:當(dāng)函數(shù)模板需要對某些類型進(jìn)行特別解決,稱為函數(shù)模板的特化。例如:?1

bool

IsEqual(T

t1,

T

t2)?2

{?3

return

t1

==

t2;?4

}

5?6

int

main()?7

{?8

char

str1[]

=

"Hello";

char

str2[]

=

"Hello";?10

cout

<<

IsEqual(1,

1)

<<

endl;?11

cout

<<

IsEqual(str1,

str2)

<<

endl;

//輸出0?12

return

0;?13

}?代碼11行比較字符串是否相等。由于對于傳入的參數(shù)是char

*類型的,max函數(shù)模板只是簡樸的比較了傳入?yún)?shù)的值,即兩個指針是否相等,因此這里打印0。顯然,這與我們的初衷不符。因此,max函數(shù)模板需要對char

*類型進(jìn)行特別解決,即特化:?1

template

<>

2

bool

IsEqual(char*

t1,

char*

t2)

//函數(shù)模板特化?3

{?4

return

strcmp(t1,

t2)

==

0;?5

}?這樣,當(dāng)IsEqual函數(shù)的參數(shù)類型為char*

時,就會調(diào)用IsEqual特化的版本,而不會再由函數(shù)模板實(shí)例化。

(2)類模板的特化:與函數(shù)模板類似,當(dāng)類模板內(nèi)需要對某些類型進(jìn)行特別解決時,使用類模板的特化。例如:

template

2

class

compare?3

{

4

public:

5

bool

IsEqual(T

t1,

T

t2)?6

{?7

return

t1

==

t2;

}?9

};

10?11

int

main()?12

{?13

char

str1[]

=

"Hello";?14

char

str2[]

"Hello";?15

compare

c1;?16

compare

c2;

17

cout

<<

c1.IsEqual(1,

1)

<<

endl;

//比較兩個int類型的參數(shù)?18

cout

<<

c2.IsEqual(str1,

str2)

<<

endl;

//比較兩個char

*類型的參數(shù)?19

return

0;?20

}這里代碼18行也是調(diào)用模板類compare的IsEqual進(jìn)行兩個字符串比較,顯然這里存在的問題和上面函數(shù)模板中的同樣,我們需要比較兩個字符串的內(nèi)容,而不是僅僅比較兩個字符指針。因此,需要使用類模板的特化:?1

templat(yī)e<>

2

class

compare

//特化(char*)?3

{?4

public:

5

bool

IsEqual(char*

t1,

char*

t2)

6

{?7

return

strcmp(t1,

t2)

==

0;

//使用strcmp比較字符串?8

}?9

};

注意:進(jìn)行類模板的特化時,需要特化所有的成員變量及成員函數(shù)。3考點(diǎn):雙向鏈表的操作

出現(xiàn)頻率:★★★★?解析:?與測長的方法同樣,使用right指針進(jìn)行遍歷。?1

//打印整個鏈表

2

void

PrintList(DbNode

*head)

//參數(shù)為鏈表的表頭節(jié)點(diǎn)?3

{

4

DbNode

*pnode

=

NULL;?5?6

if

(head

==

NULL)

//head為NULL表達(dá)鏈表空?7

return;

9

}?10

pnode=

head;?11

while

(pnode

!=

NULL)?12

{?13

printf("%d

",

pnode->data);?14

pnode

=

pnode->right;

//使用right指針遍歷

15

}

16

printf("");

17

}4考點(diǎn):類模板的實(shí)例化的理解

出現(xiàn)頻率:★★★★

1

template?2

class

Array

{?3

};

5

void

foo(

)

6

{?7

Array

arr1;?8

Array

arr4,

arr5;

9

Array

arr2,

arr3;?10

Array

arr6;

11

…?12

}?How

many

instances

of

the

template

class

Array

will

get

instantiat(yī)ed

inside

the

function

foo()?A

B

6

C

4

D

解析:

模板類(template

class)的實(shí)例個數(shù)是由類型參數(shù)的種類決定的。代碼7行和9行實(shí)例化的模板類都是Array,代碼8行實(shí)例化的模板類是Array,代碼10行實(shí)例化的模板類是Array。一共是三個實(shí)例。?答案:

A5考點(diǎn):雙向鏈表的操作?出現(xiàn)頻率:★★★★?解析:

為了得到雙向鏈表的長度,需要使用right指針進(jìn)行遍歷,直到得到NULL為止。

1

//獲取鏈表的長度?2

int

GetLength(DbNode

*head)

//參數(shù)為鏈表的表頭節(jié)點(diǎn)

3

{?4

int

count

1;

DbNode

*pnode

NULL;

6?7

if

(head

==

NULL)

//head為NULL表達(dá)鏈表空

{?9

return

0;?10

11

pnode

head->right;

12

while

(pnode

!=

NULL)?13

{?14

pnode

=

pnode->right;

//使用right指針遍歷

15

count++;

16

}

17

18

return

count;?19

}?更多精彩內(nèi)容,請到“融智技術(shù)學(xué)苑rzchina”

使用模板有什么缺陷?如何避免??6考點(diǎn):理解模板編程的缺陷?出現(xiàn)頻率:★★★?解析:?templates(模板)是節(jié)省時間和避免代碼反復(fù)的極好方法,我們可以只輸入一個類模板,就能讓編譯器實(shí)例化所需要的很多個特定類及函數(shù)。類模板的成員函數(shù)只有被使用時才會被實(shí)例化,所以只有在每一個函數(shù)都在實(shí)際中被使用時,我們才會得到這些函數(shù)。

的確這是一個很重要的技術(shù),但是假如不小心,使用模板也許會導(dǎo)致代碼膨脹。什么是代碼膨脹?請看下面的例子:?1

templat(yī)e

2

class

3

{

4

public:?5

void

work()

6

{

7

cout

<<

"work()

<<

endl;

8

cout

<<

num

<<

endl;

9

}?10

};

11

12

int

main()

13

{

14

Av1;?15

Av2;?16

Av3;

17

Av4;

18

v1.work();?19

v2.work();

20

v3.work();?21

v4.work();

22

return

0;?23

}

類模板A取得一個類型參數(shù)T,并且它尚有一個類型為int的參數(shù),一個非類型參數(shù)(non-type

parameter),與類型參數(shù)相比,雖然非類型參數(shù)不是很通用,但他們是完全合法的。在本例中,由于num的不同,代碼14到17行的調(diào)用將會生成了三個A的實(shí)例,然后在18~21行又生成了不同的函數(shù)調(diào)用。

雖然這些函數(shù)做了相同的事情(打印一個“work()”和num),但他們卻有不同的二進(jìn)制代碼。這就是所說的由于模板導(dǎo)致的代碼膨脹。也就是說,雖然源代碼看上去緊湊而整潔,但是目的代碼卻臃腫而松散,會嚴(yán)重影響程序的運(yùn)營效率。

如何避免由于這種代碼膨脹呢?有一個原則,就是把C++模板中與參數(shù)無關(guān)的代碼分離出來。也就是讓與參數(shù)無關(guān)的代碼只有一份拷貝。對類模板A可以進(jìn)行如下地修改:

1

template?2

class

Base?3

{?4

public:

5

void

work(int

num)

6

{

7

cout

<<

"work

";?8

cout

<<

num

<<

endl;?9

10

};?11?12

templat(yī)e?13

class

Derived

:

public

Base

14

{?15

public:

16

void

work()?17

{?18

Base::work(num);

19

}?20

};?21

22

int

main()

23

{?24

Derivedd1;?25

Derivedd2;

26

Derivedd3;

27?28

d1.work();?29

d2.work();?30

d3.work();

31

return

0;?32

}

程序中work的參數(shù)版本是在一個Base類(基類)中的。與Derived類同樣,Base類也是一個類模板,但是與Derived類不同樣的是,它參數(shù)化的僅僅是類型T,而沒有num。因此,所有持有一個給定類型的Derived將共享一個單一的Base類。比如代碼24~26行實(shí)例化的模板類都共享Base模板類,從而他們的成員函數(shù)都共享Base模板類中的work這個單一的拷貝。

答案:

模板的缺陷:不本地使用模板會導(dǎo)致代碼膨脹,即二進(jìn)制代碼臃腫而松散,會嚴(yán)重影響程序的運(yùn)營效率。?解決方法:把C++模板中與參數(shù)無關(guān)的代碼分離出來。7如何建立一個雙向鏈表?

考點(diǎn):雙向鏈表的操作

出現(xiàn)頻率:★★★★

解析:?雙向鏈表的定義如下:?1

typedef

struct

DbNode

2

{

3

int

data;

//節(jié)點(diǎn)數(shù)據(jù)?4

DbNode

*left;

//前驅(qū)節(jié)點(diǎn)指針?5

DbNode

*right;

//后繼節(jié)點(diǎn)指針?6

}

DbNode;

(1)建立雙向鏈表:為方便,這里定義了三個函數(shù):?q

CreateNode()根據(jù)數(shù)據(jù)來創(chuàng)建一個節(jié)點(diǎn),返回新創(chuàng)建的節(jié)點(diǎn)。?q

CreateList()函數(shù)根據(jù)一個節(jié)點(diǎn)數(shù)據(jù)創(chuàng)建鏈表的表頭,返回表頭節(jié)點(diǎn)。

q

AppendNode

()函數(shù)總在表尾插入新節(jié)點(diǎn)(其內(nèi)部調(diào)用CreateNode()生成節(jié)點(diǎn)),返回表頭節(jié)點(diǎn)。

1

//根據(jù)數(shù)據(jù)創(chuàng)建創(chuàng)建節(jié)點(diǎn)

2

DbNode

*Creat(yī)eNode(int

data)

3

{?4

DbNode

*pnode

=

(DbNode

*)malloc(sizeof(DbNode));

pnode->data

=

data;

6

pnode->left

=

pnode->right

=

pnode;

//創(chuàng)建新節(jié)點(diǎn)時?7

//讓其前驅(qū)和后繼指針都指向自身?8

return

pnode;

9}

10?11

//創(chuàng)建鏈表?12

DbNode

*CreateList(int

head)

//參數(shù)給出表頭節(jié)點(diǎn)數(shù)據(jù)?13

{

//表頭節(jié)點(diǎn)不作為存放故意義數(shù)據(jù)的節(jié)點(diǎn)

14

DbNode

*pnode

(DbNode

*)malloc(sizeof(DbNode));

15

pnode->dat(yī)a

head;

16

pnode->left

=

pnode->right

pnode;?17

18

return

pnode;

19

}?20?21

//插入新節(jié)點(diǎn),總是在表尾插入;

返回表頭節(jié)點(diǎn)

22

DbNode

*AppendNode(DbNode

*head,

int

data)

//參數(shù)1是鏈表的表頭節(jié)點(diǎn),

23

{

//參數(shù)2是要插入的節(jié)點(diǎn),其數(shù)據(jù)為data

24

DbNode

*node

=

CreateNode(data);

//創(chuàng)建數(shù)據(jù)為data的新節(jié)點(diǎn)

25

DbNode

*p

=

head,

*q;

26

27

while(p

!=

NULL)

28

{

29

q

=

p;

30

=

p->right;

31

}

32

q->right

=

node;

33

node->left

=

q;?34?35

return

head;

36

}?我們可以使用其中的CreateList()和AppendNode()來生成一個鏈表,下面是一個數(shù)據(jù)生成從0到9具有10個節(jié)點(diǎn)的循環(huán)鏈表。

1

DbNode

*head

Creat(yī)eList(0);

//生成表頭,表頭數(shù)據(jù)為0?2?3

for

(int

1;

i

<

10;

i++)?4

{

5

head

AppendNode(head,

i);

//添加9個節(jié)點(diǎn),數(shù)據(jù)為從1到9

6

}

8考點(diǎn):函數(shù)模板與類模板的基本概念和區(qū)別

出現(xiàn)頻率:★★★?解析:

(1)什么是函數(shù)模板和類模板。

函數(shù)模板是一種抽象函數(shù)定義,它代表一類同構(gòu)函數(shù)。通過用戶提供的具體參數(shù),C++編譯器在編譯時刻可以將函數(shù)模板實(shí)例化,根據(jù)同一個模板創(chuàng)建出不同的具體函數(shù),這些函數(shù)之間的不同之處重要在于函數(shù)內(nèi)部一些數(shù)據(jù)類型的不同,而由模板創(chuàng)建的函數(shù)的使用方法與一般函數(shù)的使用方法相同。函數(shù)模板的定義格式如下:?1

templateFunction_Definition

其中,Function_Definition為函數(shù)定義;TYPE_LIST被稱為類型參數(shù)表,是由—系列代表類型的標(biāo)記符組成的,其間用逗號分隔,這些標(biāo)記符的通常風(fēng)格是由大寫字母組成,ARG_LIST稱為變量表,其中具有由逗號分隔開的多個變量說明,相稱于一般函數(shù)定義中的形式參數(shù)。前面例題中的max就是函數(shù)模板的一個例子,因此這里不再此外舉例。

C++提供的類模板是一種更高層次的抽象的類定義,用于使用相同代碼創(chuàng)建不同類模板的定義與函數(shù)模板的定義類似,只是把函數(shù)摸板中的函數(shù)定義部分換作類說明,并對類的成員函數(shù)進(jìn)行定義即可。在類說明中可以使用出現(xiàn)在TYPE_LIST中的各個類型標(biāo)記以及出現(xiàn)在ARG_LIST中的各變量。?1

template<<棋板參數(shù)表>>?2

class<類模板名>?3

{<類模板定義體>},?例如我們需要定義一個表達(dá)平面的點(diǎn)(Point)類,這個類有兩個成員變量分別表達(dá)橫坐標(biāo)和縱坐標(biāo),并且這兩個坐標(biāo)的類型可以是int、float、double等等類型。因此也許寫出類似Point_int_int、Point_float_int、Point_float_float等這樣的類。通過類模板,我們只需要寫一個類。

1

#include?2

using

namespace

std;?3

template?5

class

Point_T

6

{?7

public:?8

T1

a;

//成員a為T1類型?9

T2

b;

//成員b為T2類型

10

Point_T()

:

a(0),

b(0)

{}

//默認(rèn)構(gòu)造函數(shù)?11

Point_T(T1

ta,

T2

tb)

:

a(ta),

b(tb)

{}

//帶參數(shù)的構(gòu)造函數(shù)?12

Point_T&

operator=(Point_T

&pt);

//賦值函數(shù)

13

friend

Point_T

operator

+(Point_T

&pt1,

Point_T

&pt2);

//重載+?14

};

15?16

template

17

Point_T&

Point_T::operator=(Point_T

&pt)

//賦值函數(shù)

18

{?19

this->a

=

pt.a(chǎn);

20

this->b

=

pt.b;

21

return

*this;

22

}?23

24

template?25

Point_T

operator

+(Point_T

&pt1,

Point_T

&pt2)

//重載+?26

{

27

Point_T

temp;

28

temp.a(chǎn)

pt1.a(chǎn)

+

pt2.a;

//結(jié)果對象中的a和b分別為兩個參數(shù)對象的各自a和b之和?29

temp.b

=

pt1.b

+

pt2.b;?30

return

temp;?31

}?32

33

template?34

ostream&

operator

<<

(ostream&

out,

Point_T&

pt)

//重載輸出流操作符

35

{?36

out

<<

"("

<<

pt.a(chǎn)

<<

",

";

//輸出(a,

b)

37

out

<<

pt.b

<<

")";?38

return

out;

39

}?40?41

int

main()

42

{?43

Point_T

intPt1(1,

2);

//T1和T2都是int?44

Point_T

intPt2(3,

4);

//T1和T2都是int?45

Point_T

floatPt1(1.1f,

2.2f);

//T1和T2都是float

46

Point_T

floatPt2(3.3f,

4.4f);

//T1和T2都是float(yī)?47

48

Point_T

intTotalPt;

49

Point_T

floatTotalPt;?50

51

intTotalPt

=

intPt1

+

intPt2;

//類型為Point_T的對象相加?52

float(yī)TotalPt

=

floatPt1

+

floatPt2;

//類型為Point_T的對象相加

53

54

cout

<<

intTotalPt

<<

endl;

//輸出Point_T的對象?55

cout

<<

float(yī)TotalPt

<<

endl;

//輸出Point_T的對象

56?57

return

0;?58

}

Point_T類就是一個類模板,它的成員a和b分別為T1和T2類型,這里我們還實(shí)現(xiàn)了它的構(gòu)造函數(shù)、賦值函數(shù)、“+”運(yùn)算符的重載以及輸出流操作符“<<”的重載。?使用Point_T類非常方便,我們可以進(jìn)行各種類型的組合。?代碼43、44行,定義了兩個Point_T類的對象intPt1和intPt2,表白這兩個對象的成員a和b都是int類型。?代碼45、46行,定義了兩個Point_T類的對象floatPt1和floatPt2,表白這兩個對象的成員a和b都是float(yī)類型。

代碼51行,對intPt1和intPt2進(jìn)行對象加法,結(jié)果保存到intTotalPt中,此過程先調(diào)用“+”函數(shù),再調(diào)用了“=”函數(shù)。

代碼52行,與51行類似,只是相加的對象和結(jié)果對象都是Point_T類的對象。

代碼54、55行,輸出對象intTotalPt和float(yī)TotalPt的內(nèi)容。

可以看出,通過使用類模板Point_T我們可以創(chuàng)建不同的類,大大提高了代碼的可維護(hù)性以及可重用性。

有一些概念需要區(qū)別:函數(shù)模板與模板函數(shù),類模板和模板類是不同的意思。?函數(shù)模板的重點(diǎn)是模板,它表達(dá)的是一個模板,用來生產(chǎn)函數(shù)。例如前面例題的max是一個函數(shù)模板。而模板函數(shù)的重點(diǎn)是函數(shù),它表達(dá)的是由一個模板生成而來的函數(shù)。例如max,max等都是模板函數(shù)。?類模板和模板類的區(qū)別與上面的類似,類模板用于生產(chǎn)類,例如Point_T就是一個類模板。而模板類是由一個模板生成而來的類,例如Point_T和Point_T都是模板類。

(2)函數(shù)模板和類模板有什么區(qū)別。?在面試?yán)}1的程序代碼中,我們在使用函數(shù)模板max時不一定要必須指明T的類型,函數(shù)模板max的實(shí)例化是由編譯程序在解決函數(shù)調(diào)用時自動完畢的,當(dāng)調(diào)用max(1,

2)時自動生成實(shí)例max,而調(diào)用max(1.1f,

2.2f)時自動生成實(shí)例max。當(dāng)然也可以顯示指定T的類型。

對于本例題的類模板Point_T來說,其實(shí)例化必須被顯示地指定,比如Point_T、Point_T。

答案:

函數(shù)模板是一種抽象函數(shù)定義,它代表一類同構(gòu)函數(shù)。類模板是一種更高層次的抽象的類定義。?函數(shù)模板的實(shí)例化是由編譯程序在解決函數(shù)調(diào)用時自動完畢的,而類模板的實(shí)例化必須由程序員在程序中顯式地指定。9約瑟夫問題的解答?考點(diǎn):循環(huán)鏈表的操作?出現(xiàn)頻率:★★★★?編號為1,2,....,N的N個人按順時針方向圍坐一圈,每人持有一個密碼(正整數(shù)),一開始任選一個正整數(shù)作為報數(shù)上限值M,從第一個人開始按順時針方向自1開始順序報數(shù),報到M時停止報數(shù)。報M的人出列,將他的密碼作為新的M值,從他在順時針方向上的下一個人開始重新從1報數(shù),如此下去,直至所有人所有出列為止。試設(shè)計一個程序求出出列順序。?解析:

顯然當(dāng)有人退出圓圈后,報數(shù)的工作要從下一個人開始繼續(xù),而剩下的人仍然是圍成一個圓圈的,因此可以使用循環(huán)單鏈表,由于退出圓圈的工作相應(yīng)著表中結(jié)點(diǎn)的刪除操作,對于這種刪除操作頻繁的情況,選用效率較高的鏈表結(jié)構(gòu),為了程序指針每一次都指向一個具體的代表一個人的結(jié)點(diǎn)而不需要判斷,鏈表不帶頭結(jié)點(diǎn)。所以,對于所有人圍成的圓圈所相應(yīng)的數(shù)據(jù)結(jié)構(gòu)采用一個不帶頭結(jié)點(diǎn)的循環(huán)鏈表來描述。設(shè)頭指針為p,并根據(jù)具體情況移動。

為了記錄退出的人的先后順序,采用一個順序表進(jìn)行存儲。程序結(jié)束后再輸出依次退出的人的編號順序。由于只記錄各個結(jié)點(diǎn)的data值就可以,所以定義一個整型一維數(shù)組。如:int

quit[n];n為一個根據(jù)實(shí)際問題定義的一個足夠大的整數(shù)。

程序代碼如下:

1

#include

2

using

namespace

std;

3?4

/*

結(jié)構(gòu)體和函數(shù)聲明

*/?5

typedef

struct

node?6

{?7

int

data;

node

*next;?9

}

node;?10?11

node

*node_create(int

n);?12

13

//構(gòu)造節(jié)點(diǎn)數(shù)量為

n

的單向循環(huán)鏈表?14

node

*

node_create(int

n)?15

16

node

*pRet

=

NULL;

17?18

if

(0

!=

n)?19

{

20

int

n_idx

1;?21

node

*p_node

=

NULL;

22

23

/*

構(gòu)造

node

*/?24

p_node

=

new

node[n];?25

if

(NULL

==

p_node)

//申請內(nèi)存失敗,返回NULL

26

27

return

NULL;?28

}

29

else?30

{

31

memset(p_node,

0,

*

sizeof(node));

//初始化內(nèi)存?32

}?33

pRet

=

p_node;?34

while

(n_idx

n)

//構(gòu)造循環(huán)鏈表

35

//初始化鏈表的每個節(jié)點(diǎn),從1到n?36

p_node->data

n_idx;

37

p_node->next

p_node

1;?38

p_node

p_node->next;

39

n_idx++;?40

41

p_node->data

=

n;?42

p_node->next

=

pRet;

43

44

45

return

pRet;

46

}?47?48

int

main()?49

{

50

node

*pList

=

NULL;?51

node

*pIter

NULL;;?52

int

n

=

20;?53

int

m

=

6;?54

55

/*

構(gòu)造單向循環(huán)鏈表

*/?56

pList

node_create(n);?57?58

/*

Josephus

循環(huán)取數(shù)

*/?59

pIter

=

pList;?60

%=

n;

61

while

(pIter

!=

pIter->next)

62

{

63

int

=

1;

64?65

/*

取到第

m-1

個節(jié)點(diǎn)

*/

66

for

(;

m

-

1;

i++)?67

{?68

pIter

pIter->next;

69

}

70

71

/*

輸出第

m

個節(jié)點(diǎn)的值

*/?72

printf("%d

",

pIter->next->data);?73?74

/*

從鏈表中刪除第

個節(jié)點(diǎn)

*/

75

pIter->next

=

pIter->next->next;?76

pIter

=

pIter->next;

77

}?78

printf("%d",

pIter->dat(yī)a);?79

80

/*

釋放申請的空間

*/?81

delete

[]pList;

82

return

0;?83

}10舉例說明什么是泛型編程?考點(diǎn):泛型編程的基本概念?出現(xiàn)頻率:★★★

解析:?泛型編程指編寫完全一般化并可反復(fù)使用的算法,其效率與針對某特定數(shù)據(jù)類型而設(shè)計的算法相同。所謂泛型,是指具有在多種數(shù)據(jù)類型上皆可操作的含意,在C++中事實(shí)上就是使用模板實(shí)現(xiàn)。?舉一個簡樸的例子,比如我們要比較兩個數(shù)的大小,這兩個數(shù)的類型也許是int,也也許是float,尚有也許是double。一般編程時我們也許這樣寫函數(shù)(不考慮使用宏的情況):

1

int

max(int

a,

int

b)

//參數(shù)和返回值都是int類型?2

{?3

return

a

>

b?

a:

b;?4

}

5

6

float

max(float

a,

float

b)

//參數(shù)和返回值都是float類型

7

{?8

return

a

>

b?

a:

b;?9

}?10

11

double

max(double

a,

double

b)

//參數(shù)和返回值都是double類型?12

{

13

return

a

>

b?

a:

b;?14

}?可以看到,上面寫了3個重載函數(shù),他們的區(qū)別僅僅只是類型(參數(shù)及返回值)不同,而函數(shù)體完全同樣。

而假如使用模板,我們可以這樣寫:?1

template

//class也可用typename替換?2

T

max(T

a,

T

b)

//參數(shù)和返回值都是T類型

3

{?4

return

a

>

b?

a:

b;?5

}?這里的class不代表對象的類,而是類型(可用typename替換)。這樣max函數(shù)的各個參數(shù)以及返回值類型都為T,對于任意類型的兩個數(shù),我們都可以調(diào)用max求大小,測試代碼如下:?1

int

main()?2

{?3

cout

<<

max(1,

2)

<<

endl;

//隱式調(diào)用int類型的max

4

cout

<<

max(1.1f,

2.2f)

<<

endl;

//隱式調(diào)用float類型的max?5

cout

<<

max(1.11l,

2.22l)

<<

endl;

//隱式調(diào)用double類型的max?6

cout

<<

max('A',

'C')

<<

endl;

//隱式調(diào)用char類型的max?7

cout

<<

max(1,

2.0)

<<

endl;

//必須指定int類型?8?9

return

0;?10

}?程序執(zhí)行結(jié)果如下:?1

2?2

2.2?3

2.22

5

2?上面的程序中對于int、float、double、以及char類型的都進(jìn)行了測試。這里需要注意的是第7行的測試中顯示的指定了類型為int,這是由于參數(shù)1為int類型,參數(shù)2.0為double類型,此時假如不指定是使用什么類型,會產(chǎn)生編譯的模糊性,即編譯器不知道是需要調(diào)用int版本的max還是調(diào)用double版本的max函數(shù)。

此外,T作為max函數(shù)的各參數(shù)以及返回值類型,它幾乎可以是任意類型,即除了基本類型(int、float、char等),還可以是類,當(dāng)然這個類需要重載“>”操作符(由于max函數(shù)體使用了這個操作符)。?顯然,使用泛型編程(模板)可以極大地增長了代碼的重用性。11考點(diǎn):單鏈表的操作

出現(xiàn)頻率:★★★★

已知兩個鏈表head1

和head2

各自有序,請把它們合并成一個鏈表仍然有序。使用非遞歸方法以及遞歸方法。?解析:?一方面介紹非遞歸方法。由于兩個鏈表head1

和head2都是有序的,所以我們只需要找把較短鏈表的各個元素有序的插入到較長的鏈表之中就可以了。?源代碼如下:

node*

insert_node(node

*head,

node

*item)

//head

!=

NULL

2

{?3

node

*p

head;

node

*q

=

NULL;

//始終指向p之前的節(jié)點(diǎn)

5

6

while(p->data

item->data

&&

p

!=

NULL)?7

{?8

p;?9

p

p->next;?10

}?11

if

(p

==

head)

//插入到原頭節(jié)點(diǎn)之前?12

{?13

item->next

p;

14

return

item;

15

}

16

//插入到q與p之間之間?17

q->next

=

item;?18

item->next

=

p;

19

return

head;

20

}?21?22

/*

兩個有序鏈表進(jìn)行合并

*/?23

node*

merge(node*

head1,

node*

head2)?24

{?25

node*

head;

//合并后的頭指針

26

node

*p;?27

node

*nextP;

//指向p之后

28?29

if

head1

==

NULL

)

//有一個鏈表為空的情況,直接返回另一個鏈表?30

{

31

return

h

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論