版權(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";
9
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í),使用類模板的特化。例如:
1
template
2
class
compare?3
{
4
public:
5
bool
IsEqual(T
t1,
T
t2)?6
{?7
return
t1
==
t2;
8
}?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
{
8
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
…
4
};
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
3
B
6
C
4
D
1
解析:
模板類(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;
5
DbNode
*pnode
=
NULL;
6?7
if
(head
==
NULL)
//head為NULL表達(dá)鏈表空
8
{?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
A
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));
5
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
=
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
i
=
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
4
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;
8
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)造
n
個(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,
n
*
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
m
%=
n;
61
while
(pIter
!=
pIter->next)
62
{
63
int
i
=
1;
64?65
/*
取到第
m-1
個(gè)節(jié)點(diǎn)
*/
66
for
(;
i
<
m
-
1;
i++)?67
{?68
pIter
=
pIter->next;
69
}
70
71
/*
輸出第
m
個(gè)節(jié)點(diǎn)的值
*/?72
printf("%d
",
pIter->next->data);?73?74
/*
從鏈表中刪除第
m
個(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
4
C
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)的鏈表之中就可以了。?源代碼如下:
1
node*
insert_node(node
*head,
node
*item)
//head
!=
NULL
2
{?3
node
*p
=
head;
4
node
*q
=
NULL;
//始終指向p之前的節(jié)點(diǎn)
5
6
while(p->data
<
item->data
&&
p
!=
NULL)?7
{?8
q
=
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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 航空部件維修合同模板
- 甜品店勞動(dòng)合同
- 梯阻系統(tǒng)安裝合同
- 《食管癌的治療》課件
- 《大學(xué)英語(yǔ)UNI》課件
- 2025年丹東a2貨運(yùn)從業(yè)資格證模擬考試
- 軍訓(xùn)個(gè)人心得體會(huì)匯編15篇
- 2025年石家莊貨運(yùn)從業(yè)資格證模擬考試題及答案解析
- 智能家居項(xiàng)目延期還款協(xié)議
- 風(fēng)電設(shè)備運(yùn)輸司機(jī)聘用合同模板
- 民事陪審員培訓(xùn)課件
- 湖南財(cái)政經(jīng)濟(jì)學(xué)院《世界市場(chǎng)行情》2023-2024學(xué)年第一學(xué)期期末試卷
- 2024年執(zhí)業(yè)醫(yī)師考試-中醫(yī)師承及確有專長(zhǎng)考核考試近5年真題集錦(頻考類試題)帶答案
- 醫(yī)學(xué)細(xì)胞生物學(xué)學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 駐店藥師考試題及答案
- 醫(yī)藥公司中藥采購(gòu)年終工作總結(jié)(8篇)
- 境外投資設(shè)備合同模板
- 滬科版數(shù)學(xué)八年級(jí)上冊(cè)期末考試試卷含答案
- 江蘇省昆山市、太倉(cāng)、常熟、張家港市2023-2024學(xué)年八年級(jí)上學(xué)期期末陽(yáng)光測(cè)評(píng)語(yǔ)文試卷
- 2024年全國(guó)職業(yè)院校技能大賽中職組(法律實(shí)務(wù)賽項(xiàng))考試題庫(kù)-下(多選、判斷題)
- 國(guó)際結(jié)算第五版劉衛(wèi)紅課后參考答案
評(píng)論
0/150
提交評(píng)論