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

下載本文檔

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

文檔簡(jiǎn)介

程序員經(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)

//鏈表為空時(shí)返回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ù)模板需要對(duì)某些類型進(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行比較字符串是否相等。由于對(duì)于傳入的參數(shù)是char

*類型的,max函數(shù)模板只是簡(jiǎn)樸的比較了傳入?yún)?shù)的值,即兩個(gè)指針是否相等,因此這里打印0。顯然,這與我們的初衷不符。因此,max函數(shù)模板需要對(duì)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*

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

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

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;

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

cout

<<

c2.IsEqual(str1,

str2)

<<

endl;

//比較兩個(gè)char

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

return

0;?20

}這里代碼18行也是調(diào)用模板類compare的IsEqual進(jìn)行兩個(gè)字符串比較,顯然這里存在的問題和上面函數(shù)模板中的同樣,我們需要比較兩個(gè)字符串的內(nèi)容,而不是僅僅比較兩個(gè)字符指針。因此,需要使用類模板的特化:?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í),需要特化所有的成員變量及成員函數(shù)。3考點(diǎn):雙向鏈表的操作

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

//打印整個(gè)鏈表

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

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

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

1

//獲取鏈表的長(zhǎng)度?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)容,請(qǐng)到“融智技術(shù)學(xué)苑rzchina”

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

的確這是一個(gè)很重要的技術(shù),但是假如不小心,使用模板也許會(huì)導(dǎo)致代碼膨脹。什么是代碼膨脹?請(qǐng)看下面的例子:?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取得一個(gè)類型參數(shù)T,并且它尚有一個(gè)類型為int的參數(shù),一個(gè)非類型參數(shù)(non-type

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

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

如何避免由于這種代碼膨脹呢?有一個(gè)原則,就是把C++模板中與參數(shù)無關(guān)的代碼分離出來。也就是讓與參數(shù)無關(guān)的代碼只有一份拷貝。對(duì)類模板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ù)版本是在一個(gè)Base類(基類)中的。與Derived類同樣,Base類也是一個(gè)類模板,但是與Derived類不同樣的是,它參數(shù)化的僅僅是類型T,而沒有num。因此,所有持有一個(gè)給定類型的Derived將共享一個(gè)單一的Base類。比如代碼24~26行實(shí)例化的模板類都共享Base模板類,從而他們的成員函數(shù)都共享Base模板類中的work這個(gè)單一的拷貝。

答案:

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

考點(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)建立雙向鏈表:為方便,這里定義了三個(gè)函數(shù):?q

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

CreateList()函數(shù)根據(jù)一個(gè)節(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)時(shí)?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()來生成一個(gè)鏈表,下面是一個(gè)數(shù)據(jù)生成從0到9具有10個(gè)節(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個(gè)節(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ù)模板實(shí)例化,根據(jù)同一個(gè)模板創(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)記符組成的,其間用逗號(hào)分隔,這些標(biāo)記符的通常風(fēng)格是由大寫字母組成,ARG_LIST稱為變量表,其中具有由逗號(hào)分隔開的多個(gè)變量說明,相稱于一般函數(shù)定義中的形式參數(shù)。前面例題中的max就是函數(shù)模板的一個(gè)例子,因此這里不再此外舉例。

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

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

class<類模板名>?3

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

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é)果對(duì)象中的a和b分別為兩個(gè)參數(shù)對(duì)象的各自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的對(duì)象相加?52

float(yī)TotalPt

=

floatPt1

+

floatPt2;

//類型為Point_T的對(duì)象相加

53

54

cout

<<

intTotalPt

<<

endl;

//輸出Point_T的對(duì)象?55

cout

<<

float(yī)TotalPt

<<

endl;

//輸出Point_T的對(duì)象

56?57

return

0;?58

}

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

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

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

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

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

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

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

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

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

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

答案:

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

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

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

quit[n];n為一個(gè)根據(jù)實(shí)際問題定義的一個(gè)足夠大的整數(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)造

個(gè)

node

*/?24

p_node

=

new

node[n];?25

if

(NULL

==

p_node)

//申請(qǐng)內(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

//初始化鏈表的每個(gè)節(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

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

*/

66

for

(;

m

-

1;

i++)?67

{?68

pIter

pIter->next;

69

}

70

71

/*

輸出第

m

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

*/?72

printf("%d

",

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

/*

從鏈表中刪除第

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

*/

75

pIter->next

=

pIter->next->next;?76

pIter

=

pIter->next;

77

}?78

printf("%d",

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

80

/*

釋放申請(qǐng)的空間

*/?81

delete

[]pList;

82

return

0;?83

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

解析:?泛型編程指編寫完全一般化并可反復(fù)使用的算法,其效率與針對(duì)某特定數(shù)據(jù)類型而設(shè)計(jì)的算法相同。所謂泛型,是指具有在多種數(shù)據(jù)類型上皆可操作的含意,在C++中事實(shí)上就是使用模板實(shí)現(xiàn)。?舉一個(gè)簡(jiǎn)樸的例子,比如我們要比較兩個(gè)數(shù)的大小,這兩個(gè)數(shù)的類型也許是int,也也許是float,尚有也許是double。一般編程時(shí)我們也許這樣寫函數(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個(gè)重載函數(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不代表對(duì)象的類,而是類型(可用typename替換)。這樣max函數(shù)的各個(gè)參數(shù)以及返回值類型都為T,對(duì)于任意類型的兩個(gè)數(shù),我們都可以調(diào)用max求大小,測(cè)試代碼如下:?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?上面的程序中對(duì)于int、float、double、以及char類型的都進(jìn)行了測(cè)試。這里需要注意的是第7行的測(cè)試中顯示的指定了類型為int,這是由于參數(shù)1為int類型,參數(shù)2.0為double類型,此時(shí)假如不指定是使用什么類型,會(huì)產(chǎn)生編譯的模糊性,即編譯器不知道是需要調(diào)用int版本的max還是調(diào)用double版本的max函數(shù)。

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

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

已知兩個(gè)鏈表head1

和head2

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

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

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

/*

兩個(gè)有序鏈表進(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

)

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

{

31

return

h

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論