#include?iostream
創(chuàng)新互聯(lián)公司專注于企業(yè)成都營(yíng)銷網(wǎng)站建設(shè)、網(wǎng)站重做改版、東勝網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5技術(shù)、商城建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為東勝等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。
int?main()
{
int?a?=?0,b?=?0;
printf("請(qǐng)輸入一次方程的系數(shù)a和b(以逗號(hào)隔開(kāi)):");
scanf("%d,%d",a,b);
double?c?=?(double)-b?/?a;
printf("一次方程?%dx+%d=0?的根是:x?=?%lf\n",a,b,c);
system("pause");
return?0;
#include iostream.h
#include math.h
void main()
{
char L;
do
{
double M[100][100];
double x[100],y[100];
double X=1,xx=0,w=1,N=0,P,R=1;
int n;
cout"請(qǐng)輸入所求均差階數(shù):";
cinn;
for(int i=0;i=n;i++)
{
cout"請(qǐng)輸入x"i"的值:"endl;
cinx[i];
cout"請(qǐng)輸入y"i"的值:"endl;
ciny[i];
M[i][0]=x[i];
M[i][1]=y[i];
}
for( int j=2;j=n+1;j++)
{
for( i=1;i=n;i++)
{
M[i][j]=(M[i][j-1]-M[i-1][j-1])/(M[i][0]-M[i-j+1][0]);
}
}
for(i=1;i=n;i++)
{
cout"其"i"階均差為:"M[i][i+1]endl;
}
cout"請(qǐng)輸入x的值:x=";
cinxx;
for(i=0;in;i++)
{
X*=xx-x[i];
N+=M[i+1][i+2]*X;
P=M[0][1]+N;
}
cout"其函數(shù)值:y="Pendl;
for(i=0;in;i++)
{
w*=xx-x[i];
R=fabs(M[n][n+1]*w);
}
cout"其截?cái)嗾`差:R="Rendl;
coutendl"還想算其它插值嗎?是請(qǐng)按'y'否則按'n'"endl;
cinL;
}while(L=='y');
}
#includestdio.h
#includestdlib.h
#includeiostream.h
typedef struct data
{
float x;
float y;
}Data;//變量x和函數(shù)值y的結(jié)構(gòu)
Data d[20];//最多二十組數(shù)據(jù)
float f(int s,int t)//牛頓插值法,用以返回插商
{
if(t==s+1)
return (d[t].y-d[s].y)/(d[t].x-d[s].x);
else
return (f(s+1,t)-f(s,t-1))/(d[t].x-d[s].x);
}
float Newton(float x,int count)
{
int n;
while(1)
{
cout"請(qǐng)輸入n值(即n次插值):";//獲得插值次數(shù)
cinn;
if(n=count-1)// 插值次數(shù)不得大于count-1次
break;
else
system("cls");
}
//初始化t,y,yt。
float t=1.0;
float y=d[0].y;
float yt=0.0;
//計(jì)算y值
for(int j=1;j=n;j++)
{
t=(x-d[j-1].x)*t;
yt=f(0,j)*t;
//coutf(0,j)endl;
y=y+yt;
}
return y;
}
float lagrange(float x,int count)
{
float y=0.0;
for(int k=0;kcount;k++)//這兒默認(rèn)為count-1次插值
{
float p=1.0;//初始化p
for(int j=0;jcount;j++)
{//計(jì)算p的值
if(k==j)continue;//判斷是否為同一個(gè)數(shù)
p=p*(x-d[j].x)/(d[k].x-d[j].x);
}
y=y+p*d[k].y;//求和
}
return y;//返回y的值
}
void main()
{
float x,y;
int count;
while(1)
{
cout"請(qǐng)輸入x[i],y[i]的組數(shù),不得超過(guò)20組:";//要求用戶輸入數(shù)據(jù)組數(shù)
cincount;
if(count=20)
break;//檢查輸入的是否合法
system("cls");
}
//獲得各組數(shù)據(jù)
for(int i=0;icount;i++)
{
cout"請(qǐng)輸入第"i+1"組x的值:";
cind[i].x;
cout"請(qǐng)輸入第"i+1"組y的值:";
cind[i].y;
system("cls");
}
cout"請(qǐng)輸入x的值:";//獲得變量x的值
cinx;
while(1)
{
int choice=3;
cout"請(qǐng)您選擇使用哪種插值法計(jì)算:"endl;
cout" (0):退出"endl;
cout" (1):Lagrange"endl;
cout" (2):Newton"endl;
cout"輸入你的選擇:";
cinchoice;//取得用戶的選擇項(xiàng)
if(choice==2)
{
cout"你選擇了牛頓插值計(jì)算方法,其結(jié)果為:";
y=Newton(x,count);break;//調(diào)用相應(yīng)的處理函數(shù)
}
if(choice==1)
{
cout"你選擇了拉格朗日插值計(jì)算方法,其結(jié)果為:";
y=lagrange(x,count);break;//調(diào)用相應(yīng)的處理函數(shù)
}
if(choice==0)
break;
system("cls");
cout"輸入錯(cuò)誤!!!!"endl;
}
coutx" , "yendl;//輸出最終結(jié)果
}
#include?stdio.h
double?Lerp(double?x0,double?y0,double?x1,double?y1,double?x)
{
double?dy?=?y1?-?y0;
if(dy?==?0){
printf("除0錯(cuò)誤!\n");
return?0;
}
return?x?*?(x1?-?x0)?/?dy;
}
int?main()
{
double?x0,x1,y1,y0,x,y;
printf("Inptu?x0?y0?x1?y1?x:");
scanf("%lf?%lf?%lf?%lf?%lf",x0,y0,x1,y1,x);
y?=?Lerp(x0,y0,x1,y1,x);
printf("y?=?%lf\n",y);
return?0;
}
1)數(shù)據(jù)數(shù)據(jù)的概念十分廣泛,它通常是對(duì)客觀事物的數(shù)量、特征、性質(zhì)的描述。對(duì)計(jì)算機(jī)而言,數(shù)據(jù)是計(jì)算機(jī)所能處理的一切數(shù)值、字符、圖形或其他特定符號(hào)的總稱,是計(jì)算機(jī)加工處理的“原料”和它所生產(chǎn)的“產(chǎn)品”(計(jì)算的結(jié)果)。2)數(shù)據(jù)元素?cái)?shù)據(jù)元素是數(shù)據(jù)的基本單位,也稱作結(jié)點(diǎn)和記錄。在計(jì)算機(jī)程序中通常作為一個(gè)整體進(jìn)行考慮和處理。一個(gè)數(shù)據(jù)元素可由若干個(gè)數(shù)據(jù)項(xiàng)組成。數(shù)據(jù)項(xiàng)是數(shù)據(jù)的不可分割的最小單位。3)數(shù)據(jù)對(duì)象數(shù)據(jù)對(duì)象是具有相同性質(zhì)的數(shù)據(jù)元素的集合,是數(shù)據(jù)的子集。 1、 數(shù)據(jù)結(jié)構(gòu)(Data Structure)
數(shù)據(jù)結(jié)構(gòu)是指同一數(shù)據(jù)對(duì)象中個(gè)數(shù)據(jù)元素之間存在的關(guān)系(相互間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合)。
根據(jù)數(shù)據(jù)結(jié)構(gòu)的形式定義,數(shù)據(jù)結(jié)構(gòu)是一個(gè)二元組:
S(Data-Structure)=(D,R)
其中:D是數(shù)據(jù)元素的有限集,R是D上關(guān)系的有限集。
邏輯結(jié)構(gòu)與物理結(jié)構(gòu)
數(shù)據(jù)之間的相互關(guān)系稱為邏輯結(jié)構(gòu)。通常分為三類基本結(jié)構(gòu):
(一)集合:結(jié)構(gòu)中的數(shù)據(jù)元素除了同屬于一種類型外,別無(wú)其它關(guān)系。
(二)線性結(jié)構(gòu):結(jié)構(gòu)中的數(shù)據(jù)元素之間存在一對(duì)一的關(guān)系。
(三)非線性結(jié)構(gòu):
樹(shù)型結(jié)構(gòu)——結(jié)構(gòu)中的數(shù)據(jù)元素之間存在一對(duì)多的關(guān)系。
圖狀結(jié)構(gòu)或網(wǎng)狀結(jié)構(gòu)——結(jié)構(gòu)中的數(shù)據(jù)元素之間存在多對(duì)多的關(guān)系。
數(shù)據(jù)結(jié)構(gòu)在計(jì)算機(jī)中的表示稱為數(shù)據(jù)的物理結(jié)構(gòu),又稱為存儲(chǔ)結(jié)構(gòu)。
(一般我們將數(shù)據(jù)的邏輯結(jié)構(gòu)稱為是數(shù)據(jù)結(jié)構(gòu),)
存儲(chǔ)結(jié)構(gòu)可分為:順序存儲(chǔ)與鏈?zhǔn)酱鎯?chǔ)。
順序存儲(chǔ)結(jié)構(gòu)——借助元素在存儲(chǔ)器中的相對(duì)位置來(lái)表示數(shù)據(jù)元素間的邏輯關(guān)系;
鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)——借助指示元素存儲(chǔ)地址的指針表示數(shù)據(jù)元素間的邏輯關(guān)系。
數(shù)據(jù)的邏輯結(jié)構(gòu)與存儲(chǔ)結(jié)構(gòu)密切相關(guān)。
2.1.2 線性表
1)線性表定義
線性表(Linear List) :由n(n≧)個(gè)數(shù)據(jù)元素(結(jié)點(diǎn))a1,a2, …an組成的有限序列。其中數(shù)據(jù)元素的個(gè)數(shù)n定義為表的長(zhǎng)度。當(dāng)n=0時(shí)稱為空表,常常將非空的線性表(n0)記作:
L = (a1,a2,…an)
這里的數(shù)據(jù)元素ai(1≦i≦n)只是一個(gè)抽象的符號(hào),其具體含義在不同的情況下可以不同。
2)線性表特點(diǎn)
線性表的邏輯結(jié)構(gòu)有以下特點(diǎn):
在數(shù)據(jù)元素的非空有限集中
? 存在唯一的一個(gè)被稱作“第一個(gè)”的數(shù)據(jù)元素
? 存在唯一的一個(gè)被稱作“最后一個(gè)”的數(shù)據(jù)元素
? 除第一個(gè)外,集合中的每個(gè)數(shù)據(jù)元素均只有一個(gè)前驅(qū)
? 除最后一個(gè)外,集合中的每個(gè)數(shù)據(jù)元素均只有一個(gè)后繼
3)線性表的基本運(yùn)算
線性表的主要運(yùn)算有:
插入:在兩個(gè)確定元素之間插入一個(gè)新元素;
刪除:刪除線性表中的某個(gè)元素;
查找:按某種要求查找線性表中的一個(gè)元素,需要時(shí)還可以進(jìn)行更新;
排序:按給定要求對(duì)表中元素重新排序;
還有初始化、求長(zhǎng)度等。
在不同問(wèn)題的線性表中,需要進(jìn)行的運(yùn)算也不相同,實(shí)際應(yīng)用中還可能涉及建立線性表、修改表中元素?cái)?shù)值(編輯)等運(yùn)算,但是基本上可以由上述四種運(yùn)算組成。
4)順序存儲(chǔ)線性表
(1)順序存儲(chǔ)結(jié)構(gòu)
把線性表的數(shù)據(jù)元素,按順序依次存放在一組地址連續(xù)的存儲(chǔ)單元里。用這種方法存儲(chǔ)的線性表簡(jiǎn)稱順序表,也稱為向量式存儲(chǔ)結(jié)構(gòu)。
假設(shè)線性表的每個(gè)元素需占用個(gè)存儲(chǔ)單元,且線性表在內(nèi)存中的首地址為,則線性表中第個(gè)數(shù)據(jù)元素的存儲(chǔ)地址為:
則線性表中第個(gè)數(shù)據(jù)元素的存儲(chǔ)位置和第個(gè)數(shù)據(jù)元素的存儲(chǔ)位置之間滿足下列關(guān)系:
這種存儲(chǔ)結(jié)構(gòu)只要知道數(shù)據(jù)元素序號(hào),就很容易找到第個(gè)數(shù)據(jù)元素。它的主要特點(diǎn)有:一、各數(shù)據(jù)元素存儲(chǔ)地址上相鄰;二、無(wú)論序號(hào)為何值,找到第個(gè)元素的時(shí)間相同。
這種存儲(chǔ)結(jié)構(gòu)在高級(jí)語(yǔ)言中可以用一維數(shù)組的形式實(shí)現(xiàn)。
(2)順序存儲(chǔ)結(jié)構(gòu)的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
? 邏輯相鄰,物理相鄰;
? 可隨機(jī)存取任一元素;
? 存儲(chǔ)空間使用緊湊。
缺點(diǎn)
? 插入、刪除操作需要移動(dòng)大量的元素;
? 預(yù)先分配空間需按最大空間分配,利用不充分;
? 表容量難以擴(kuò)充。
5)線性鏈表
特點(diǎn):
? 用一組任意的存儲(chǔ)單元存儲(chǔ)線性表的數(shù)據(jù)元素;
? 利用指針實(shí)現(xiàn)了用不相鄰的存儲(chǔ)單元存放邏輯上相鄰的元素;
? 每個(gè)數(shù)據(jù)元素,除存儲(chǔ)本身信息外,還需存儲(chǔ)其直接后繼的信息。
數(shù)據(jù)元素由兩部分組成:
? 數(shù)據(jù)域:存放元素本身信息;
? 指針域:指示直接后繼的存儲(chǔ)地址。
線性鏈表一般在第一個(gè)結(jié)點(diǎn)之前附加一個(gè)頭結(jié)點(diǎn):
2.1.3 棧與隊(duì)
棧和隊(duì)是兩種特殊的線性表,它們的運(yùn)算規(guī)則較一般線性表由更多的約束和限制,因此稱作限定性數(shù)據(jù)結(jié)構(gòu)。
1)棧的結(jié)構(gòu)和運(yùn)算
(1)棧的定義
棧(Stack)是限制在表的一端進(jìn)行插入和刪除運(yùn)算的線性表,通常稱插入、刪除的這一端為棧頂(Top),另一端為棧底(Bottom)。當(dāng)表中沒(méi)有元素時(shí)稱為空棧。
假設(shè)棧,則稱為棧底元素,為棧頂元素。棧中元素按的次序進(jìn)棧,的順序退棧,退棧的第一個(gè)元素應(yīng)為棧頂元素。換句話說(shuō),棧的修改是按后進(jìn)先出的原則進(jìn)行的。因此,棧稱為后進(jìn)先出表(LIFO,last in first out)。
棧的存儲(chǔ)結(jié)構(gòu)也有順序與鏈?zhǔn)絻煞N,稱為順序棧與鏈棧。
(2)順序棧
由于棧是運(yùn)算受限的線性表,因此線性表的存儲(chǔ)結(jié)構(gòu)對(duì)棧也適應(yīng)。
棧的順序存儲(chǔ)結(jié)構(gòu)簡(jiǎn)稱為順序棧,它是運(yùn)算受限的線性表。因此,可用數(shù)組來(lái)實(shí)現(xiàn)順序棧。因?yàn)闂5孜恢檬枪潭ú蛔兊?,所以可以將棧底位置設(shè)置在數(shù)組的兩端的任何一個(gè)端點(diǎn);棧頂位置是隨著進(jìn)棧和退棧操作而變化的,故需用一個(gè)整型變量top來(lái)指示棧頂位置。如果用m來(lái)表示棧的最大容量,則top=0表示??眨藭r(shí)出棧,則下溢(underflow);top=m表示棧滿,此時(shí)入棧,則上溢(overflow)。
(3)棧的應(yīng)用
表達(dá)式求值
表達(dá)式求值步驟:首先在OS棧中放入表達(dá)式結(jié)束符“;”,
l 若為操作數(shù),將其壓入NS棧;
l 若為運(yùn)算符,比較當(dāng)前OS棧的棧頂元素:
ü 若當(dāng)前運(yùn)算符的優(yōu)先數(shù)大于OS棧頂?shù)倪\(yùn)算符,則將當(dāng)前運(yùn)算符壓入OS棧;
ü 若當(dāng)前運(yùn)算符的優(yōu)先數(shù)不大于OS棧頂運(yùn)算符,則從NS棧中彈出兩個(gè)操作數(shù)x,y,再?gòu)腛S中彈出一個(gè)運(yùn)算符,,并將結(jié)果T送入NS棧。
ü 若當(dāng)前運(yùn)算符為“;”,且OS棧頂也為“;”,則表示表達(dá)式處理結(jié)束,此時(shí),NS棧頂元素即為此表達(dá)式值。
過(guò)程嵌套和遞歸調(diào)用
過(guò)程嵌套調(diào)用如圖所示:
當(dāng)調(diào)用子過(guò)程時(shí),必須把斷點(diǎn)的信息及地址保存起來(lái),當(dāng)子過(guò)程執(zhí)行完畢,返回時(shí),取用這些信息,找到返回地址,從此斷點(diǎn)繼續(xù)執(zhí)行。當(dāng)程序中出現(xiàn)多重嵌套調(diào)用時(shí),必須開(kāi)辟一個(gè)棧,將各層斷點(diǎn)信息依次入棧,當(dāng)各層子過(guò)程返回時(shí),又以相反的次序從棧頂取出。
遞歸調(diào)用
函數(shù)直接或間接地調(diào)用自身叫遞歸調(diào)用,這主要時(shí)用遞歸工作棧來(lái)實(shí)現(xiàn)的。下面舉一個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明遞歸調(diào)用。
例 一段遞歸調(diào)用的C語(yǔ)言程序如下:
void print(int w)
{
int I;
if (w!=0)
{
print (w-1);
for (I=1; I=w; ++I)
printf(“%3d,”,w);
printf(“/n”);
}
}
在這段程序中,遞歸調(diào)用的執(zhí)行過(guò)程如圖所示:
2) 隊(duì)的結(jié)構(gòu)和運(yùn)算
(1)隊(duì)的定義
隊(duì)是限定只能在表的一端進(jìn)行插入,在表的另一端進(jìn)行刪除的線性表。
隊(duì)尾(rear)——允許插入的一端
隊(duì)頭(front)——允許刪除的一端
隊(duì)的特點(diǎn)是:先進(jìn)先出(FIFO)
(2)順序隊(duì)
存在問(wèn)題:
設(shè)數(shù)組維數(shù)為M,則:
當(dāng)front=-1,rear=M-1時(shí),再有元素入隊(duì)發(fā)生溢出——真溢出
l當(dāng)front1-1,rear=M-1時(shí),再有元素入隊(duì)發(fā)生溢出——假溢出
解決方案:
l 隊(duì)首固定,每次出隊(duì)剩余元素向下移動(dòng)——浪費(fèi)時(shí)間
l 循環(huán)隊(duì)列
? 基本思想:把隊(duì)列設(shè)想成環(huán)形,讓sq[0]接在sq[M-1]之后,若rear+1==M,則令rear=0;
? 實(shí)現(xiàn):利用“?!边\(yùn)算
入隊(duì): rear=(rear+1)%M; sq[rear]=x;
出隊(duì): front=(front+1)%M; x=sq[front];
? 隊(duì)滿、隊(duì)空判定條件
front=rear
解決方案:
n 另外設(shè)一個(gè)標(biāo)志以區(qū)別隊(duì)空、隊(duì)滿
n 少用一個(gè)元素空間:
隊(duì)空:front==rear
隊(duì)滿:(rear+1)%M==front
2.1.4 數(shù)組
1)數(shù)組的定義
(1)定義
數(shù)組可以看成是一種特殊的線性表,即線性表中數(shù)據(jù)元素本身也是一個(gè)線性表。用線性表的一般表示形式定義二維數(shù)組為:
其中,K由個(gè)結(jié)點(diǎn)組成:
R由以下兩種關(guān)系組成:
(2)數(shù)組特點(diǎn)
l 數(shù)組結(jié)構(gòu)固定
l 數(shù)據(jù)元素同構(gòu)
(3)數(shù)組運(yùn)算
數(shù)組一旦被定義,它的維數(shù)和數(shù)據(jù)元素的個(gè)數(shù)就已經(jīng)固定,不能插入和刪除,所以數(shù)組運(yùn)算只有:
l 給定一組下標(biāo),存取相應(yīng)的數(shù)據(jù)元素
l 給定一組下標(biāo),修改數(shù)據(jù)元素的值
2)數(shù)組的順序存儲(chǔ)結(jié)構(gòu)
由于計(jì)算機(jī)的內(nèi)存結(jié)構(gòu)是一維的,因此用一維內(nèi)存來(lái)表示多維數(shù)組,就必須按某種次序?qū)?shù)組元素排成一列序列,然后將這個(gè)線性序列存放在存儲(chǔ)器中。
又由于對(duì)數(shù)組一般不做插入和刪除操作,也就是說(shuō),數(shù)組一旦建立,結(jié)構(gòu)中的元素個(gè)數(shù)和元素間的關(guān)系就不再發(fā)生變化。因此,一般都是采用順序存儲(chǔ)的方法來(lái)表示數(shù)組。
根據(jù)不同的存放形式,可以分為按行優(yōu)先和按列優(yōu)先順序存放。
(1)按行優(yōu)先順序存放
按行優(yōu)先順序存放,對(duì)二維數(shù)組來(lái)說(shuō)就是按行進(jìn)行切分,如圖所示:
假設(shè)每個(gè)數(shù)據(jù)元素只占一個(gè)單元地址,則元素的存放地址可以通過(guò)以下關(guān)系式計(jì)算:
(2)按列優(yōu)先順序存放
如果數(shù)組按列切分,就得到按列優(yōu)先順序存放方式。如圖所示:
元素的存放地址可以通過(guò)以下關(guān)系式計(jì)算:
2.1.5 樹(shù)與二叉樹(shù)
1)樹(shù)的定義及其存儲(chǔ)結(jié)構(gòu)
(1)樹(shù)的定義和術(shù)語(yǔ)
定義:樹(shù)(Tree)是n(n=0)個(gè)結(jié)點(diǎn)的有限集T,T為空時(shí)稱為空樹(shù),否則它滿足如下兩個(gè)條件:
(1)有且僅有一個(gè)特定的稱為根(Root)的結(jié)點(diǎn);
(2)其余的結(jié)點(diǎn)可分為m(m=0)個(gè)互不相交的子集T1,T2,T3…Tm,其中每個(gè)子集又是一棵樹(shù),并稱其為子樹(shù)(Subtree)。
基本術(shù)語(yǔ):
l 結(jié)點(diǎn)(node)——表示樹(shù)中的元素,包括數(shù)據(jù)項(xiàng)及若干指向其子樹(shù)的分支;
l 結(jié)點(diǎn)的度(degree)——結(jié)點(diǎn)擁有的子樹(shù)數(shù);
l 葉子(leaf)——度為0的結(jié)點(diǎn);
l 孩子(child)——結(jié)點(diǎn)子樹(shù)的根稱為該結(jié)點(diǎn)的孩子;
l 雙親(parents)——孩子結(jié)點(diǎn)的上層結(jié)點(diǎn)叫該結(jié)點(diǎn)的雙親;
l 兄弟(sibling)——同一雙親的孩子;
l 樹(shù)的度——一棵樹(shù)中最大的結(jié)點(diǎn)度數(shù);
l 結(jié)點(diǎn)的層次(level)——從根結(jié)點(diǎn)算起,根為第一層,它的孩子為第二層……;
l 深度(depth)——樹(shù)中結(jié)點(diǎn)的最大層次數(shù);
l 森林(forest)——m(m=0)棵互不相交的樹(shù)的集合;
(2)樹(shù)的存儲(chǔ)結(jié)構(gòu)
樹(shù)的存儲(chǔ)結(jié)構(gòu)有多種形式,這里只討論鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。因?yàn)闃?shù)是多分支非線性表,因此采用多重鏈表結(jié)構(gòu),即每個(gè)結(jié)點(diǎn)設(shè)有多個(gè)指針域,其中每個(gè)指針指向一棵子樹(shù)的根結(jié)點(diǎn)。對(duì)于每一個(gè)結(jié)點(diǎn)的結(jié)構(gòu)類型有兩種形式:結(jié)點(diǎn)異構(gòu)型、結(jié)點(diǎn)同構(gòu)型。
結(jié)點(diǎn)異構(gòu)型,是根據(jù)每個(gè)結(jié)點(diǎn)的子樹(shù)數(shù)設(shè)置相應(yīng)的指針域,由于每個(gè)結(jié)點(diǎn)的度數(shù)不同,則同一棵樹(shù)中,結(jié)點(diǎn)形式也不同。這種結(jié)構(gòu)形式雖然能節(jié)省存儲(chǔ)空間,但運(yùn)算不方便。
結(jié)點(diǎn)同構(gòu)型,是每個(gè)結(jié)點(diǎn)的指針域個(gè)數(shù)均為樹(shù)的度數(shù)。這種形式運(yùn)算方便,但會(huì)使鏈表中出現(xiàn)很多空鏈域,浪費(fèi)空間。
當(dāng)樹(shù)的度數(shù)k=2時(shí),空鏈域的比例最低,這就是要介紹的二叉樹(shù)。
2)二叉樹(shù)及其性質(zhì)
二叉樹(shù)在樹(shù)結(jié)構(gòu)的應(yīng)用中起著非常重要的作用,因?yàn)閷?duì)二叉樹(shù)的許多操作算法簡(jiǎn)單,而任何樹(shù)都可以與二叉樹(shù) 相互轉(zhuǎn)換,這樣就解決了樹(shù)的存儲(chǔ)結(jié)構(gòu)及其運(yùn)算中存在的復(fù)雜性。
(1)二叉樹(shù)定義及其存儲(chǔ)結(jié)構(gòu)
定義:二叉樹(shù)是由n(n=0)個(gè)結(jié)點(diǎn)的有限集合構(gòu)成,此集合或者為空集,或者由一個(gè)根結(jié)點(diǎn)及兩棵互不相交的左右子樹(shù)組成,并且左右子樹(shù)都是二叉樹(shù)。
這也是一個(gè)遞歸定義。二叉樹(shù)可以是空集合,根可以有空的左子樹(shù)或空的右子樹(shù)。二叉樹(shù)不是樹(shù)的特殊情況,它們是兩個(gè)概念。
二叉樹(shù)結(jié)點(diǎn)的子樹(shù)要區(qū)分左子樹(shù)和右子樹(shù),即使只有一棵子樹(shù)也要進(jìn)行區(qū)分,說(shuō)明它是左子樹(shù),還是右子樹(shù)。這是二叉樹(shù)與樹(shù)的最主要的差別。
圖2-8 二叉樹(shù)
存儲(chǔ)結(jié)構(gòu):通常用具有兩個(gè)指針域的鏈表作為二叉樹(shù)的存儲(chǔ)結(jié)構(gòu),其中,每個(gè)結(jié)點(diǎn)由數(shù)據(jù)域(data)、左指針域(L child)和右指針域(R child)組成,如圖所示:
圖2-9 二叉鏈表
這就是二叉鏈表,還有三叉鏈表就是在這一基礎(chǔ)上增加一個(gè)雙親結(jié)點(diǎn)指針。
(2)二叉樹(shù)的基本性質(zhì)
(1) 在二叉樹(shù)的第層上,至多有個(gè)結(jié)點(diǎn)。
(2) 深度為h的二叉樹(shù)中,至多含有個(gè)結(jié)點(diǎn)。
(3) 對(duì)任意一棵二叉樹(shù),若有個(gè)子結(jié)點(diǎn),個(gè)度為2的結(jié)點(diǎn),則必有。
(3)幾種特殊形式的二叉樹(shù)
l 滿二叉樹(shù)
一棵深度為h且有2h-1個(gè)結(jié)點(diǎn)的二叉樹(shù)稱為滿二叉樹(shù)。
l 完全二叉樹(shù)
如果深度為h、有n個(gè)結(jié)點(diǎn)的二叉樹(shù)中的結(jié)點(diǎn)能夠與深度為h的順序編號(hào)的滿二叉樹(shù)從1到n標(biāo)號(hào)的結(jié)點(diǎn)相對(duì)應(yīng),則該樹(shù)稱為完全二叉樹(shù)。
完全二叉樹(shù)的特點(diǎn)是:
所有的葉結(jié)點(diǎn)都出現(xiàn)在第h層或h-1層。
錯(cuò)任一結(jié)點(diǎn),如果其右子樹(shù)的最大層次為1,則其左子樹(shù)的最大層次為1或l+1。
滿二叉樹(shù)是完全二叉樹(shù)的特例。
(1) 平衡二叉樹(shù)
所有結(jié)點(diǎn)的平衡因子為-1、0、1。
(4)一般樹(shù)轉(zhuǎn)換為二叉樹(shù)
為了使一般樹(shù)也能象二叉樹(shù)一樣用二叉樹(shù)鏈表表示,必須找出樹(shù)與二叉樹(shù)之間的對(duì)應(yīng)關(guān)系。將一般樹(shù)轉(zhuǎn)換為二叉樹(shù)的方法為:
(1) 在兄弟結(jié)點(diǎn)之間加一連線;
(2) 對(duì)每個(gè)結(jié)點(diǎn),除了與它的第一個(gè)孩子保持聯(lián)系外,去除與其它孩子的聯(lián)系;
(3) 以樹(shù)根為軸心將整棵樹(shù)順時(shí)針旋轉(zhuǎn)45度。
任何一棵樹(shù)轉(zhuǎn)換為二叉樹(shù),其根結(jié)點(diǎn)的右子樹(shù)必為空。
3)二叉樹(shù)的遍歷
遍歷——按一定規(guī)律走遍樹(shù)的各個(gè)結(jié)點(diǎn),每一結(jié)點(diǎn)僅被訪問(wèn)一次,即找一個(gè)完整而有規(guī)律的走法,以得到樹(shù)中所有結(jié)點(diǎn)的一個(gè)線性排列。
常用方法
先序遍歷(DLR):先訪問(wèn)根結(jié)點(diǎn),然后分別先序遍歷左子樹(shù)、右子樹(shù)
中序遍歷(LDR):先中序遍歷左子樹(shù),然后訪問(wèn)根結(jié)點(diǎn),最后中序遍歷右子樹(shù)
后序遍歷(LRD):先后序遍歷左、右子樹(shù),然后訪問(wèn)根結(jié)點(diǎn)
2.2 工程手冊(cè)的數(shù)據(jù)處理
基本要求:
(1)熟悉工程手冊(cè)的數(shù)據(jù)處理方法;(2)掌握數(shù)表的程序化方法;(3)了解線圖的程序化方法;(4)掌握最小二乘法擬合方法及其應(yīng)用;(4)能用高級(jí)程序設(shè)計(jì)語(yǔ)言(如C語(yǔ)言)編寫(xiě)前述相應(yīng)數(shù)據(jù)處理方法的基本程序并上機(jī)通過(guò)。
教學(xué)內(nèi)容:
(1)數(shù)表的程序化;(2)線圖的程序化;(3)建立經(jīng)驗(yàn)公式的方法。
重點(diǎn)與難點(diǎn):
重點(diǎn):(1)查表程序設(shè)計(jì);(2)一元函數(shù)的插值;(3)最小二乘法擬合。
難點(diǎn):(1)拋物線插值中結(jié)點(diǎn)的選?。唬?)插值程序設(shè)計(jì)及上機(jī)調(diào)試;(3)最小二乘法擬合程序設(shè)計(jì)及上機(jī)調(diào)試。
學(xué)時(shí)安排:
講課4學(xué)時(shí),課外上機(jī)練習(xí)不少于2學(xué)時(shí)。
在機(jī)械設(shè)計(jì)過(guò)程中,往往需要從有關(guān)的工程手冊(cè)或設(shè)計(jì)規(guī)范中查找各種設(shè)計(jì)數(shù)據(jù)(資料)。這些數(shù)據(jù)在手冊(cè)或規(guī)范中一般是以數(shù)表和線圖的形式存放(記錄)的。在進(jìn)行機(jī)械CAD時(shí),首先要把這些數(shù)表、線圖形式的數(shù)據(jù)計(jì)算機(jī)化,即把它們存入計(jì)算機(jī)外、內(nèi)存儲(chǔ)器中,并設(shè)計(jì)相應(yīng)的自動(dòng)檢索程序。
從總體上說(shuō),這些設(shè)計(jì)資料的計(jì)算機(jī)處理有以下三種方法:
(1)程序化:在應(yīng)用程序內(nèi)部對(duì)這些數(shù)表和線圖進(jìn)行處理,包括數(shù)組法和擬合公式法。
(2)數(shù)據(jù)文件法:將數(shù)表或線圖中得數(shù)據(jù)編成一個(gè)獨(dú)立的數(shù)據(jù)文件,存入外存,供設(shè)計(jì)解題時(shí)調(diào)用。高級(jí)程序設(shè)計(jì)語(yǔ)言本身一般均具備相應(yīng)的數(shù)據(jù)文件處理功能。
(3)數(shù)據(jù)庫(kù)法:將數(shù)表或線圖中的數(shù)據(jù)暗數(shù)據(jù)庫(kù)中的規(guī)定進(jìn)行文件結(jié)構(gòu)化,即建成數(shù)據(jù)庫(kù)。
本章重點(diǎn)討論程序化方法,補(bǔ)充介紹有關(guān)數(shù)據(jù)文件法的基本內(nèi)容,數(shù)據(jù)庫(kù)存儲(chǔ)方法在后面第5章中介紹。
2.2.1 數(shù)表的程序化
l 數(shù)表的形式:
從函數(shù)角度看有:
單變量表:e.g. T.3-1~T.3-3
雙變量表:e.g. T.3-4~T.3-5 單值表:e.g. T.3-3~T.3-6
多變量表:e.g. T.3-6 多值表:e.g. T.3-1~T.3-2
無(wú)變量表:e.g. 齒輪標(biāo)準(zhǔn)模數(shù)(m)系列值。
l 數(shù)表數(shù)據(jù)的形成(來(lái)源)及處理原則:
(1)有些本來(lái)就有精確的計(jì)算公式,為了便于手工設(shè)計(jì)使用,才制成表格供設(shè)計(jì)時(shí)查用(如各種數(shù)學(xué)用表)——力求找到原來(lái)的理論計(jì)算公式或經(jīng)驗(yàn)公式→編入應(yīng)用程序。(最簡(jiǎn)單的方法)。
(2)對(duì)大多數(shù)數(shù)表而言,或本來(lái)就無(wú)法表達(dá)成公式,或一時(shí)難以找到原來(lái)公式——程序化處理。
l 數(shù)表程序化方法:
1) 數(shù)組法:適于只需要用數(shù)表中所列數(shù)據(jù)(離散點(diǎn)、型值點(diǎn)或結(jié)點(diǎn)數(shù)據(jù)),
2) 插值法(擬合公式法):對(duì)于需要用到數(shù)表中各離散點(diǎn)中間的數(shù)據(jù)。
1)數(shù)組法實(shí)例
本教材共介紹了六個(gè)實(shí)例,這里選取二個(gè)重點(diǎn)介紹,其余四個(gè)自己分析。
例1 平鍵和鍵槽的剖面尺寸,見(jiàn)圖2-10和表2-1(摘引自GB/T 1095-1979)
它是單變量多值表。查表時(shí),設(shè)計(jì)計(jì)算出的軸徑dgiven→D(范圍) →b,h,t,t1??墒褂靡痪S數(shù)組,D的范圍可用其上限表示。變量及數(shù)組的定義:
int i;
float dgiven,b,h,t,t1;
float D[12]={10.0,12.0,…,85.0};
float kb[12]=…
.
.
.
float kt[12]=…
圖2-10 平鍵和鍵槽的剖面圖
表2-1 平鍵和鍵槽的尺寸表
圖2-11平鍵和鍵槽的剖面尺寸查詢流程
尺寸查取流程圖見(jiàn)圖2-11。
要求:用C(Turbo C or Visual C++等均可)語(yǔ)言編程實(shí)現(xiàn)該數(shù)表數(shù)據(jù)存儲(chǔ)及查詢。
例2 齒輪傳動(dòng)工況系數(shù)KA,見(jiàn)表2-2。
表2-2 齒輪傳動(dòng)工況系數(shù)KA
圖2-12 齒輪傳動(dòng)工況系數(shù)KA查詢流程
根據(jù)原動(dòng)機(jī)機(jī)、工作機(jī)的工況→KA,使用二維數(shù)組:KK[i][j],i=0~2:表示原動(dòng)機(jī)工況,j=0~2:表示工作機(jī)工況。
變量及數(shù)組定義:
float KA;
int i,j;
float;
KK[3][3]={{1.0,1.25,1.75},{1.25,1.5,2.0},{1.5,1.75,2.25}};
查表程序流程圖見(jiàn)圖2-12。
要求:用C(Turbo C or Visual C++等均可)語(yǔ)言編程實(shí)現(xiàn)該數(shù)表數(shù)據(jù)存儲(chǔ)及查詢。
例3 說(shuō)明:多變量單值表
① P1值需用三維數(shù)組NN(4,4,14),可以將P1值→數(shù)據(jù)文件→NN數(shù)組。
② 降維處理:三維→二個(gè)二維。
2) 一元函數(shù)的插值
設(shè)有一用數(shù)據(jù)表格給出的列表函數(shù)y=f(x),如下表2-3:
表2-3 列表函數(shù)y=f(x)
表中只有幾個(gè)離散點(diǎn)(或型值點(diǎn)、結(jié)點(diǎn))的數(shù)據(jù),當(dāng)自變量為結(jié)點(diǎn)間的中間值時(shí),就要用到插值法求取其函數(shù)值。
基本思想:在插值點(diǎn)附近選取幾個(gè)合適的結(jié)點(diǎn),過(guò)這些點(diǎn)構(gòu)造一個(gè)簡(jiǎn)單函數(shù)g(x),在此小段上用g(x)代替原來(lái)函數(shù)f(x),這樣插值點(diǎn)的函數(shù)值就用g(x)的值來(lái)代替,如圖2-13。
圖2-13 一元函數(shù)插值
插值的實(shí)質(zhì)問(wèn)題:如何構(gòu)造一個(gè)既簡(jiǎn)單又具有足夠精度的函數(shù)f(x)。
插值方法類型:線性插值、拋物線插值。
(1)線性插值
方法步驟:(1)選xi,xi+1,滿足xix xi+1;(2)過(guò)(xi,yi)及(xi+1,yi+1)兩點(diǎn)構(gòu)造直線g(x)→f(x)。
誤差問(wèn)題:存在誤差,當(dāng)自變量間隔較小,而插值精度不要很高時(shí),可以滿足要求。
x(n),y(n)——一維數(shù)值,n——結(jié)點(diǎn)數(shù)。C語(yǔ)言下標(biāo)從0開(kāi)始。xgiven,ygiven——已知的x 插入值及求出的函數(shù)值。
圖2-14 線性插值流程
(2)拋物線插值
在f(x)上選取三點(diǎn)(xi-1,yi-1),(xi,yi),(xi+1,yi+1),構(gòu)造拋物線g(x)→f(x)。比線性插值精度好。
關(guān)鍵問(wèn)題:根據(jù)插值點(diǎn)x選取合適的三個(gè)點(diǎn)。選取方法歸納為(“靠近原則”):
設(shè)插值點(diǎn)為x,且xi-1x≤xi,i=3,4,…,n-1,
(1)若|x-xi-1|≤|x-xi|,即x靠近xi-1點(diǎn)或居于xi-1與 xi之中點(diǎn),則選xi-2,xi-1,xi三個(gè)點(diǎn),上式中i=i-1;
(2)若|x-xi-1||x-xi|,即x靠近xi點(diǎn),則選xi-1,xi,xi+1三個(gè)點(diǎn),上式中i=I;
(3)若x1≤x≤x2,即x靠近表頭,則選x1,x2,x3三個(gè)點(diǎn),上式中i=2;
(4)若x n-1≤x≤xn,即x靠近表尾,則選xn-2,xn-1,xn三個(gè)點(diǎn),上式中i=n-1。
程序流程圖見(jiàn)下圖2-15。
圖2-15 拋物線插值流程
要求:將線性插值與拋物線插值統(tǒng)一編程。
3)二元函數(shù)的插值
有二元列表函數(shù)f(xi,yi),i=1,2,…,n,如下表2-4。
表2-4 二元列表函數(shù)
插值幾何意義:在3D空間中選定幾個(gè)點(diǎn),通過(guò)這些點(diǎn)構(gòu)造一塊曲面g(x,y),用它近似地表示在這區(qū)間內(nèi)原有的曲面f (x,y),從而得到插值后的函數(shù)值Zk=g(xk,yk) , 如圖2-15所示。
插值方式類型,在一元函數(shù)插值方法的基礎(chǔ)上延伸,有以下幾種:
(1)直線-直線插值
最最基本、最簡(jiǎn)單、精度最低。
如圖所示,g(x,y)形成:以AB、CD為導(dǎo)線,作//yoz平面的直母線(EF)直線的運(yùn)動(dòng)→柱狀面。
插值步驟:
圖2-15 二元函數(shù)插值
圖2-16 拋物線插值流程
(a)根據(jù)k點(diǎn)的(xk,yk)→周圍四點(diǎn)a,b,c,d,滿足xa=xc,xb=xd,ya=yb,yc=yd,xaxkxb,yaykyb;
(b)A,B,C,D,過(guò)A,B用線性插值→E,過(guò)C,D用線性插值→F;
(c)過(guò)E,F用線性插值→K點(diǎn)。
(2)拋物線-直線插值
將導(dǎo)線AB、CD→拋物線ABE,CDF。插值步驟:
(1)據(jù)k點(diǎn)的(xk,yk)→a,b,c,d+e,f;
(2)據(jù)a,b,c,d,e,f→A,B,C,D,E,F,過(guò)A,B,E 用拋物線插值→U點(diǎn),過(guò)C,D,F用拋物線插值→V點(diǎn);
(3)U,V用線性插值→K點(diǎn)。
(3)拋物線-拋物線插值
(1)據(jù)k點(diǎn)的(xk,yk)→a,b,c,d+e,f+r,s,t;
(2)據(jù)a,b,c,d, e,f,r,s,t→A,B,C,D,E,F,R,S,T,
過(guò)A,B,E用拋物線插值→U點(diǎn),過(guò)C,D,F用拋物線插值→V點(diǎn),過(guò)R,S,T用拋物線插值→W點(diǎn);
(3) 過(guò)U,V,W用拋物線插值→K點(diǎn)。
上述三種插值方法統(tǒng)一的程序流程圖見(jiàn)P44圖3-10,三種方法由變量II控制。
要求:讀懂該流程圖,有余力的學(xué)生編程上機(jī)。
2.2.2 數(shù)表的公式擬合
工程實(shí)際中常需要用一定的數(shù)學(xué)方法將一系列測(cè)試數(shù)據(jù)或統(tǒng)計(jì)數(shù)據(jù)擬合成近似的經(jīng)驗(yàn)公式——曲線擬合。
插值法的實(shí)質(zhì)是在幾何上用嚴(yán)格通過(guò)各結(jié)點(diǎn)的曲線或曲面來(lái)近似代替列表函數(shù)曲線或曲面。但通過(guò)試(實(shí))驗(yàn)所得的數(shù)據(jù)離散性很大,誤差比較大,因此,插值法建立的公式必然保留了所有誤差,此外,要構(gòu)造這樣的函數(shù)的復(fù)雜度或難度比較大。有鑒于此,采用構(gòu)造近似曲線、曲面,此曲線、曲面并不嚴(yán)格通過(guò)所有結(jié)點(diǎn),而是盡可能反映所給數(shù)據(jù)的趨勢(shì),這種利用所給數(shù)據(jù)建立擬合或近似曲線或曲面經(jīng)驗(yàn)公式的過(guò)程稱為曲線、曲面擬合或公式擬合。
本節(jié)介紹最常用最基本的單變量曲線擬合方法——最小二乘法。(其他常用的還有Bezier法、三次參數(shù)樣條法、B樣條法等)。
1)最小二乘法擬合的基本思想
根據(jù)離散點(diǎn)的大致分布規(guī)律,先確定擬合函數(shù)的類型,如多項(xiàng)式函數(shù)、指數(shù)函數(shù)、對(duì)數(shù)函數(shù)等,計(jì)算出各數(shù)據(jù)點(diǎn)橫坐標(biāo)處的函數(shù)值與縱坐標(biāo)之間的偏差的平方,求其和并使之為最小值,從而解出函數(shù)的待定系數(shù)。
已知由線圖或?qū)嶒?yàn)所得m個(gè)點(diǎn)的值為:(x1,y1),(x1,y1),……,(xm,ym),設(shè)擬合函數(shù)公式為:y=f(x),則每一結(jié)點(diǎn)處的偏差為: (i=1,2,…,m),偏差的平方和為:
求 min 函數(shù)f(x)的待定系數(shù)→ f(x)
擬合函數(shù)的類型,常選取初等函數(shù),如對(duì)數(shù)函數(shù)、指數(shù)函數(shù)、代數(shù)多項(xiàng)式等。一般是根據(jù)數(shù)據(jù)曲線形態(tài)判斷所采用的函數(shù)類型。最常用的是代數(shù)多項(xiàng)式擬合。本節(jié)只討論在選定函數(shù)類型的情況下如何確定各系數(shù)值的問(wèn)題。
2)最小二乘法的(代數(shù))多項(xiàng)式擬合
設(shè)擬合公式為: (n次多項(xiàng)式)
已知m個(gè)點(diǎn)的值(x1,y1),(x1,y1),……,(xm,ym),且mn,結(jié)點(diǎn)偏差的平方和為:
為使 j=0,1,2,…,n
其中:(k=1,2,…,2m+1)
這是一個(gè)關(guān)于的n+1個(gè)線性方程組,求解該方程組→→f(x)
常用二次三項(xiàng)式擬合公式:
例1 介紹
程序流程圖,見(jiàn)P.44圖3-13
要求:看懂該流程圖,該流程圖中采用了高斯消去法解聯(lián)立方法(詳見(jiàn)3.3.4節(jié)),有余力的學(xué)生編程上機(jī)。