版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
詩算機(jī)科學(xué)技術(shù)系
第一部分、專業(yè)課終極筆記.........................................................3
一、本科生筆記...............................................................3
二、《c程序設(shè)計》考研總結(jié)筆記
三、老師講義(附錄電子版).................................................129
四、整理過的筆記...........................................................129
第二部分:專業(yè)課復(fù)習(xí)方法.......................................................155
第三部分:復(fù)試詳細(xì)情況介紹.....................................................155
第四部分:本科生期末考試試卷,平時作業(yè)題目....................................171
-、數(shù)據(jù)結(jié)構(gòu)期末試題及其答案................................................
二、期中考試.................................................................
三、平時作業(yè)..................................................................
第五部分、導(dǎo)師近兩年發(fā)表的論文.................................................179
第六部分:外校同專業(yè)真題.......................................................179
第七部分:部分年份真題解析180
第一部分、專業(yè)課筆記
一、專業(yè)課筆記《C程序設(shè)計》
關(guān)于C語言的筆記分兩部分:第一部分是關(guān)于基礎(chǔ)知識的,第二部分是一些考生必須掌握的
程序。
第一部分C語言基礎(chǔ)知識
在C考試中有C語言選擇題,主要考察基礎(chǔ)知識,考生只需掌握以下幾個知識點就可以了。
1、指針知識總結(jié):
Int*pP為指向整形數(shù)據(jù)的指針變量
Int*p[n]指針數(shù)組,它由N個指向整形數(shù)據(jù)的指針元素組成,通常用字符數(shù)組
Int(*p)[n]P為指向含N個元素的一維數(shù)組的指針變量,通常用于二維數(shù)組a[][]
Int*p()P帶回一個指針的函數(shù),該指針指向整性數(shù)據(jù)。
Int(*p)()P為指向函數(shù)的指針,返回以整形值。
Int**pP為指針變量,指向一個指向整形數(shù)據(jù)的指針變量。
至于每個指針例子考生可參看書上第十章。這個問就一定要掌握透徹,每年都會考這個
知識點。
2、常見文件的打開方式:
(l)“r”只讀,為輸入打開一個文本文件。
(2)“晨'只寫,為輸出打開一個文本文件
(3)“r+”/“w+”為讀寫打開/新建一個文本文檔。
3關(guān)于文件的一些命令息結(jié):
(D打開文件:
If((fp=fopcn(student.datw,"r+"))==NULL)
{printf("can'topenthisfile\nw);
Exit(O);)
(2)文件打開:FILE*P;
fp=fopen(文件名,使用方式);
關(guān)閉文件:fp=fclose(文件名,使用方式);
(3)把一個字符寫到磁盤文件中:fputc(ch,fp);
把一個字符讀入磁盤文件中:fgotc(fp);
(4)frecid(buffer,size,count,fp)讀入數(shù)據(jù)
fwrite(buffer,size,count,fp)輸出數(shù)據(jù)
(5)fwrite(文件指針,格式字符串,輸出表列)
Fscanf(文件指針,格式字符串,輸入表列)
它們的讀寫對象是文件磁盤
(6)fgets(str,n,fp)從fp中讀入字符串到str中
fputs(str,n,fp)向指定文件中輸出字符串
(7)fseek(文件指針,位置偏移量,起始位)
'O'表示開始點’1'表示當(dāng)前’2'表示末尾
其他的知識點比較瑣碎,考生需要把書上第7、10章的內(nèi)容仔細(xì)的看一邊,又一些細(xì)節(jié)
的知識在考試的選擇題中經(jīng)常出現(xiàn),不過就一兩道。
第二部分C程序源代碼
1、起泡排序
/*fromsmalltobig*/
main()
{inta[ll];
inti,j,t;
printf(,/input10mnumbers:\n,z);
for(i=l;i<ll;i++)
scanf(〃%d",&a[i]);
printf(〃\n〃);
for(j=l;j<=9;j++)
for(i=l;i<=10-j;i++;
if(a[i]>a[i+l])
{t=a[i];a[i]=a[i+l]:a[i+l]=t;J
printf(Sprintthesortednumber:\n,z);
for(i=l;i<l1;i++)
printf("%5d”,a[i]);
2、選擇排序
\main()
{inta[10];
inti,j,temp;
printf(z,input10numbers:\n,z);
for(i=0;i<10;i++)
scanf&a[i]):
printf(〃\n〃);
for(i=0;i<9;i++)
for(j=i+l;j<10;j+-)
if(a[i]>a[j])
{temp=a[i];
a[i]=a[j];
a[j]=temp;}
printf(〃\n");
for(i=0;i<10;i++)
printf(〃%3d〃,a[i]J;
}
3、插入排序
main()
{inti,j,a[ll];
printf("input10numbers:\nz,);
for(i=l;i<l1;i++)
scanf("d〃,&a[i]);
for(i=2;i<ll;i++)
{a[0]=a[i];
j=i-l;
while(a[0]>a[j])
a[j+l]=a[j-];
a[j+l]=a[0];
}
for(i=l;i<ll;i++)
printf(〃%3d〃,a[i]>;
)
4、判斷是不是閏年
main()
(intyear;
printf("inputayear:");
scanf(〃%d〃,&year);
if((year%4-0&&year%100!=0)||year%400-0)
printf("it'saleapyear");
else
printf(〃it'snotaleapyear");
)
5、排序和折半查找的綜合:
#include<stdio.h>
ttdefineN10
voidinput(intnum[],charname[N][8])
{inti;
for(i=0;i<N;i++)
{printf(z/\ninputNO.:〃);
scanf);
printf(/z\ninputname:");
getchar();
gets(name[i]);
)
)
voidsort(intnum[],charname[N][8])
{inti,j,min,tempi;
chartemp2[8];
for(i=0;i<N;i++)
{min=i;
for(j=i;j<N;j++)
if(num[min]>num[j])
min=j;
templ=num[i];
strcpy(temp2,nane[i]);
num[i]=num[min]:
strcpy(name[i],name[min]);
num[min]=templ;
strcpy(name[min],temp2);
)
printf(,z\nresult:\n,z);
for(i=0;i<N;i++)
,,,,
printf(\n%5d%10s,num[i],name[i]);
)
voidsearch(intn,intnum[],charnamc[N][8])
(intbott=N-l,top=0,mid,loca=0,sign=l;
if(n<num[0]||n>num[N-l])
loca=-l;
while(sign-l&&top<=bott)
{mid=(top+bott)/2;
if(n-num[mid])
{loca=mid;
printf(^NO.%d,hisnameis%s\n/z,n,name[loca]);
sign=T;
)
elseif(n<num[mid])
bott=mid-l;
elsetop=mid+l;
)
if(sign==l||loca--1)
printf(/zcannotfind%d\n〃,n);
)
main()
{intnum[N],number,flag=l,c,n;
charname[N][8];
input(num,name);
sort(num,name);
while(flag)
{printf(,?\ninputnumbertolookfor:〃);
scanf(〃%d〃,&number);
search(number,nun,name);
printf(z/\nCONTINUEornot(Y/N)?");
getchar();
c=getchar();
if(c='N'||c二二'n)
flag=0;
)
}
6,在數(shù)組中插入一個數(shù):
(第一種方法)
main()
{inta[10]={l,5,7,9,10,13,45,59,100};
intn,i,j,tempi,tenp2;
printfCAnthearrayis:\n〃);
for(i=0;i<9;i++)
printf(〃%5d〃,a[i]);
printf(?,inputtheinsertednumber:");
scanf("%d〃,&n);
if(n>a[8])
a[9]=n;
else
{for(i=0;i<9;i++J
{if(a[i]>n)
{templ=a[i];
a[i]=n;
for(j=i+l;j<10;j++)
{temp2=a[j];
a[j]=templ;
templ=temp2;
)
break;
}
)
)
printf(z/\nthenewarrayis:\n〃);
for(i=0;i<10;i++)
printf(〃%5d〃,a[i]J;
}
(第二種方法)
/*charusort*/
main()
{inti,j,n,a[5]={l,4,6,7};
printf(^Xninputanumber:\n〃);
scanf&n);
if(n>a[3])
a[4]=n;
else
(
i=0;
while(n>a[i])i++;
for(j=3;j>=i;j-)
a[j+l]=a[j];
a[j+l]=n;}
printf(〃\n〃);
printf(z,thesortedarrayis〃);
for(i=0;i<=4;i++)
printf(〃%5d〃,a[i]);
}
7、鏈表的基本操作:
#dcfineNULL0
#defineLENsizeof(structstudent)
structstudent
{longnum;
floatscore;
structstudent*next;
};
intn;
structstudent*creat(void)
{structstudent*hcad,*pl,*p2;
n=0;
pl=p2=(structstudent*)malloc(LEN);
scanf(,z%ld,%f”,&pl->num,&pl->score);
head二NULL;
while(pl->num!=0)
{n=n+l;
if(n==l)head=pl;
elsep2->next=pl;
p2=pl;
pl=(structstudent*)malloc(LEN);
scanf(〃%ld,%f〃,&pl->num,&pl->score);
)
p2->next=NULL;
return(head);
)
voidprint(structstudent*head)
(structstudent*p;
printf('AnNow,these%drecordsare:\n,z,n);
p=head;
if(head!=NULL)
do
{printf(,z%ld%5.p->num,p->score);
p=p->next;
}while(p!:NULL);
}
structstudent*del[structstudent*head,longnum)
{structstudent*pl,*p2;
if(hcad==NULL)
{printf(z,\nlistnull!\n〃);gotoend;}
pl二head;
while(num!=p1->num&&p1->next!=NULL)
{p2=pl;
pl=pl->next;
)
if(num==pl->num)
(if(pl==head)head=pl->next;
elsep2->next=pl->next;
printf("delete%:d\n〃,num);
n=n-l;
)
,z
elseprintf(%ldnotbeenfound!\n〃,num);
end:
return(head);
)
structstudent*insert(structstudent*head,structstudent*stud)
{structstudent*p0,*pl,*p2;
pl=head;
pO=stud;
if(head二二NULL)
{head=pO;
pO->next=NULL;
)
else
while(pO->num>p?num&&pl->next!=NULL)
{p2=pl;pl=pl->next;
)
if(pO->num<=pl->nun)
{if(head==pl)head=pO;
elsep2->next=p0;
pO->next=pl;
else
{pl->next=pO;
pO->next=NULL;
)
n=n+l;
return(head);
)
main()
(structstudent*head,stu;
longdelnum;
printf(z,\ninputrecords:\nz,);
head=creat();
print(head);
printf("inputthedeletednumber/');
scanf(*%1d〃,&delnum);
head=del(head,del_num);
print(head);
printf(,z\ninputtheinsertedrecord:");
scanf%f”,&stu.num,&stu.score);
head=insert(head,&stu);
print(head);
}
8、文件的基本操作:
^defineNULL0
#include<stdio.h>
main()
{FILE*fp;
charch,filename[10];
scanf("%s〃,filename);
if((fp=fopen(filename,*w'))==NULL)
{printf(^cannotopenthisfile");
exit(0);
)
ch=getchar();
while(ch!=,#')
{fputc(ch,fp);
ch=getchar();
)
fclose(fp);
)
9、判斷是不是素數(shù)〉
#include<math.h>
main()
{intx,i;
printf("inputanunber:/z);
scanf(〃%d〃,&x);
printf(〃\n〃);
for(i=2;i<sqrt(x);i++)
if(x%i=0)
{printf(/znotasushu");
break;}
if(i>=sqrt(x))
printf("it'sasushu");
)
10、指針的應(yīng)用
voidaverage(float*p,intn)
{float*p_end;
floatsum=0,aver;
p_cnd=p+n-l;
for(;p<=p_end;p++)
sum=sum+(*p);
aver=sum/n;
printf("average二用5.2f\n〃,aver);
)
voidsearch(float(*p)[4],intn)
(inti;
printf(/?thescoreofNO.%dare:\n?/,n);
for(1=0;i<4;i++)
printfC%6.2f",*(*(p+n)+i));
)
voidsearchfai1(float(*p)[4],intn)
(inti,j,flag;
for(j=0;j<n;j++)
{flag=0;
for(i=0;i<4;i++)
if(*(*(p+j)+i)<60)
flag=l;
if(flag-l)
(printf(//N0.%dfails,hisscoresare:\n〃,j+1);
for(i=0;i<4;i-+)
printf(〃%5.lf〃,*(*(p+j)+i));
printf(〃\n〃);
)
}
}
main()
{floatscore[3][4]={{65,67,70,60},{48,87,90,81},{90,99,100,98}};
average(*score,12);
search(score,2);
searchfail(score,3);
)
Ik對文件方面的題,考生只需把05年的題弄明白就可以了,一般文件的題
與排序算法相結(jié)合。請看下面例題:
現(xiàn)有一個記錄學(xué)生成績的數(shù)據(jù)文件studcnt.dat,其中人數(shù)不清,其文件數(shù)據(jù)結(jié)構(gòu)如下所
示,每位學(xué)生參加8門課程考試,請將其中有三門及三門以上考試成績不及格的學(xué)生信息寫
入新數(shù)據(jù)文件fail,dat。文件結(jié)構(gòu)同student,dat,同時在student,dat中刪除該條記錄。
Structstudent
{intnum;
Charname[20];
Intscore[8];
Intmark;
)
答題要點:
^defineM1000
Main()
{FILE*fpl,*fp2;
Structstudentstu[M];
Inti,j,k,count,m=0?n;
If((fpl=fopen(student.dat“,"r+"))==NULL)
{printf("can'topenthisfile\nM);
Exit(O);)
If((fp2=fopen(“fail,dat“,"w"))==NULL)
{printf(“can'topenthisfile\nw);
Exit(0);}
i=0;
whi1e(fread(&stu[i],sizeof(structstudent),1,fp))
i++;
count=l;
for(i=0;i<count;i++)
{for(j=0;j<8;j4-+)
If(stu[i].score[j]<60)m++;
If(m>=3)mark=0;
Elsemark-1;)
For(i=0;i<count;1++)
If(stu[i].mark==0)
{fwrite(&stu[i]?sizeof(structstudent),1,fp2);
For(j=I;j<count-l;j++)
{stu[j].num=stu[j+l].num;
strcpy(stu[j].name,stu[j+l].name);
for(n=0;n<8;n++)
stu[j].score[n]=stu[j+l].score[n.;
stu[j].mark=stu[j+l].mark;}
Elsefwrite(&stu[i].sizeof(structstudent
二、《數(shù)據(jù)結(jié)構(gòu)教程》本科生筆記
第一章線性表
線性表是最常用、垠簡單的一種線性結(jié)構(gòu)。因為它的應(yīng)用范圍十分廣泛,所以有必要
在這里作較詳細(xì)的介紹。
1.1線性表及其基本運(yùn)算
1.1.1線性表
線性表是具有相同類型的n個數(shù)據(jù)元素ko,ki,…J的有限序列,記為(ko,ki,…匕一3元
素個數(shù)n稱為線性表的長度,稱長度為零的線性表為空的線性表(簡稱為空表)。當(dāng)n21
時,ko是最前面的一個元素,k”/是最后一個元素,線性表相數(shù)據(jù)元素的相對位置是確定的。
因為線性表的數(shù)據(jù)元素構(gòu)成一個序列,在序列中,k排在ki+i前面,我們稱太是ki+i的前趨
元素;排在左后面,我們稱ki+i是%的后繼元素。k0沒有前趨元素,%」沒有后繼元素;
當(dāng)n22時,ko有后繼元素ki,k『i有前趨元素km;當(dāng)n23時,ki(0<i<n-l)既有前趨
元素ki”,也有后繼元素ki+i。
對于給定的線性表(koH,…kn/),它的數(shù)據(jù)元素集合為{ko.k1,…匕」),而數(shù)據(jù)元素之間
的關(guān)系由數(shù)據(jù)元素出現(xiàn)在線性表中的位置所確定。我們可用數(shù)據(jù)元素&ki+1構(gòu)成的偶對表
示數(shù)據(jù)元素h和ki+1所存在的這種關(guān)系。因此,可用數(shù)據(jù)元素的偶對的集合表示線性表中數(shù)
據(jù)元素之間的關(guān)系,這種關(guān)系記為{(ki,ki+i)|0&i<n-l}o對于相同數(shù)據(jù)元素集合的兩個
線性表,如果數(shù)據(jù)元素出現(xiàn)在表中的次序不相同,那么若兩個線性表是不想同的.
線性表中的數(shù)據(jù)元素也稱為結(jié)點,或稱為記錄,它可以是一個整數(shù)、一個實數(shù)、一個字
符或一個字符串;也可以由若干個數(shù)據(jù)項組成,其中每個數(shù)據(jù)項可以是一般數(shù)據(jù)類型,也可
以是構(gòu)造類型。數(shù)據(jù)項也稱為空段,或稱為城.
比如,表1.1.1的線性表用于記錄最近一周每天的平均氣溫。每個結(jié)點有兩個字段:一
個是星期,用于指明是星期兒,它的數(shù)據(jù)類型是由三個字符組成的字符串;另一個是溫度,
用于指明平均氣溫,它的數(shù)據(jù)類型是實數(shù)。
表1.1.1一周內(nèi)眉頭的平均氣溫記錄表
星期MonTucWedThuFriSatSun
溫度15.516.016.515.715.016.116.4
再比如,表1.1.2也是一個線性表,它是一個企業(yè)的職工工資表。改表由職工號、姓名、
性別、年齡和工資等五個字段所組成,其中職工號、年齡的數(shù)據(jù)類型是整數(shù);姓名和性別是
字符串;工資是實數(shù)。
表L1.2職工工資表
職工號姓名性別年齡工資
001Wangmale35160.50
002Caimale32150.00
003Zhangfemale28130.00
線性表中的結(jié)點可由若干個字段組成,我們稱能唯一標(biāo)識結(jié)點的字段為關(guān)鍵字,或簡稱
為鍵。如表1.1.1的線性表的關(guān)鍵字是星期,而表1.1.2的線性表的關(guān)鍵字是職工號。在本書
中,為了討論方便,往往只考慮結(jié)點的關(guān)鍵字,而忽略其他字段。這樣的假設(shè)也不失?股性,
只要知道存放某結(jié)點的存貯單元,就能取到該結(jié)點的其他字段上的值。
1.1.2線性表的基本運(yùn)算
上面介紹了線性表的基本概念,下面介紹線性表的一些基本運(yùn)算。
線性表結(jié)構(gòu)可以動態(tài)地增長或收縮,在線性表的任何位置上可以訪問、插入或刪除結(jié)點。
我們把線性表常用的運(yùn)算分成幾類,每類包括若干種運(yùn)算。
I.查找
(1)查找線性表的笫i(OWi<n-l)個結(jié)點。
(2)在線性表中查找值為x的結(jié)點。
2.插入
<1)把新結(jié)點插在線性表的第i(0<個位置上。
(2)把新結(jié)點插在值為x的結(jié)點的前面(或后面)
3.刪除
(I)在線性表中刪除第i(0WiWn-1)個結(jié)點。
(2)在線性表中刪除值為x的結(jié)點。
4.其他運(yùn)算
(1)統(tǒng)計線性表中結(jié)點的個數(shù)。
(2)打印線性表中眇有結(jié)點。
(3)復(fù)制一份線性表。
(4)把一個線性表拆成幾個線性表。
(5)把幾個線性表合并成一個線性表。
(6)根據(jù)結(jié)點的某個字段值按升序(或降序)重新排列線性表。
1.2順序存貯的線性表
在計算機(jī)內(nèi),可以利用不同的存貯方式表示線性表,其中最常用、最簡單的方式就是順
序存貯。所謂線性表的順序存貯,就是用一組連續(xù)的存貯單元一次存貯線性表中的結(jié)點。
因為線性表中所有結(jié)點的數(shù)據(jù)類型是相同的,所以每個結(jié)點在存貯器中占用大小相同的
空間。如果每個結(jié)點占用計算機(jī)中按機(jī)器字編址或按字節(jié)編址的S個地址的存貯單元,并假
設(shè)存放結(jié)點ki(OWi<n-l)的開始地址為ak”那么結(jié)點ki的地址aki可用整數(shù)i,以及地
址計算公式
aki=ako+i*s
計算出來。
對于順序存貯的線性表,因為可以利用地址計算公式直接計算出k,,所以存取第i(0
<iWn-1)個結(jié)點特別方便。
如果用C語言的數(shù)組表示線性表(kok,…kn/),我們可使用如下的說明:
#defineMAXSIZE100
intlist[MAXSIZE];
intn;
其中MAXSIZE是數(shù)組IE中元素個數(shù)的最大值,n是線性表中當(dāng)前結(jié)點個數(shù)。這里假設(shè)線
性表的結(jié)點值是整數(shù),所以數(shù)組元素也是整數(shù),當(dāng)然可根據(jù)需要取其他類型。線性表的結(jié)點
%,ki,…knd依次存放在數(shù)組元素list[O],list[1],?--list[n-1](I3o這樣,存放線性表各個結(jié)點的地
址與數(shù)組list各個下表變量?的地址有如下的對應(yīng)關(guān)系:
akn-i
t
&list[O]&list[i-l]&list[i]
有了上述的對應(yīng)關(guān)系,可得到卜面計算長的地址的公式,這里我們假設(shè)s=sizeof(int):
因aki=&list[i]
而&list[i]=&list|Oj+i*s
故aki=&list[O]+i*s
1.2.1線性表的插入
這里所講的插入是在具有n個結(jié)點的線性表中,把新結(jié)點插在線性表的第i(0WiWn-l)
個位置上,使原來長度為n的線性表變成長度為(n+1)的線性表。在把新結(jié)點放進(jìn)線性表
前,必須把原來位置號(序號)為(n-l)至位置號為i的結(jié)點依次往后移一個位置,然后
把新結(jié)點放在第i個位置上,此時宮移動(n-i)個結(jié)點。對于i=n,只要把新結(jié)點插在第n
個位置上,此時無需移動結(jié)點。
下面用一個C函數(shù)sq_insert()實現(xiàn)上述的插入算法。此函數(shù)在具有n個結(jié)點的線性表
list中,把值為x的結(jié)點插入在第i(0WiWn-1)個位置上。若插入位置i不在可以插入的
位置上(即<0或i>n),則返回I;若產(chǎn)^^*5也£(即線性表已滿),此時lisl數(shù)組沒有存
貯單元存放新結(jié)點,則返回2;若插入成功,則返回0。在函數(shù)的參數(shù)中,有一個指針變量
p_n,在調(diào)用時,把存放線性表的當(dāng)前結(jié)點個數(shù)的變量n的地址賦給指針變量p_n,以此來
實現(xiàn)插入后線性表長度n增加1。
intsq_inscrt(list,p_n,i,x)
intlistfLx;
int*p_nj;
{intj;
if(i<O||i>*p_n)
retum(I);
if(*p_n=MAXSIZE)
rcturn(2);
foi(j=*p_n;j'>i;j-)
list[i]=x;
(*p_n)++;
retum(O);
}
對于存放在數(shù)組list中的、具有n個結(jié)點的線性表,為了把值為x的結(jié)點插在線性表第
i(O<iWn-l)個位置上,可用如下的調(diào)用語句:
k=sq_inscrt(list,&n,i,x);
在具有n個結(jié)點的線性表中,插入一個新結(jié)點時,其執(zhí)行時間主要花費(fèi)在移動結(jié)點的
循環(huán)上。假設(shè)把新結(jié)點插在第i(0WiWn-1)個位置上的概率為p,各個硒應(yīng)滿足約束條
件=因為把一個新結(jié)點插在第i個位置上需移動(n-i)個結(jié)點,所以移動結(jié)點的平
1=0
均次數(shù)為
;=0
如果線性表中每個可插入位置的插入概率相同,即有
1
P(尸P產(chǎn)…二Pn-尸----
1.2.2線性表的刪除
這里所講的刪除是在具有n個結(jié)點的線性表中刪除第i(OWiWn-l)個位置上的結(jié)點,
使原來長度為n的線性表變成長度為(聯(lián)1)的線性表.刪|除時,要把位置號為(i+1)至位置號為
(n-1)的結(jié)點都依次向前移動一個位置,此時共需移動(n-i-1)個結(jié)點.
下面用一個C函數(shù)sq_delele()實現(xiàn)上述的刪除算法.此函數(shù)在具有n個結(jié)點的線性表
list中,刪除第i(OWiWnT)個位置上的結(jié)點.若刪除的結(jié)點不在可刪除的位置上(即i<0活i
2n),則返回1;若刪除成功則返回0.在函數(shù)的參數(shù)中,有一個指針變量p_n,在調(diào)用時,把存
放線性表當(dāng)前結(jié)點個數(shù)的變量n的地址賦給指針變量pn,以此來實現(xiàn)刪除后線性表的長度n
減少L
intsq_delete(list,p_n,i)
intlist[];
int*p_n,i;
intj;
if(i<0||i>=*pn)return(l);
for(j=i+l;j<*p_n;j++)
list[j-l]=list[j];
(*p_n)—;
return(0);
}
調(diào)用時,可使用如下的語句:
k=sq_delete(list,&n,i);
在具有n個結(jié)點的線性表中,刪除一個結(jié)點所需的執(zhí)行時間主要花費(fèi)在移動結(jié)點
的循環(huán)上.假設(shè)刪除第i(OWiWnT)個位置上的結(jié)點的概率為pi,每個止應(yīng)滿足約束條件
n-\
2〃尸1?因為刪除第1(0(]?「1)位置上的結(jié)點需移動(11-廣1)個結(jié)點,所以移動結(jié)點的平
<=0
均次數(shù)為
J-0
如果假設(shè)刪除線性表任何一個結(jié)點的概率相同,即有
1
P0=Pl=,,,=Pn-1=----
〃+1
那么上面的和式可改寫為
n-\n
一1?-〃-(-〃--一-1-)=-----七一
n222
上式表明,在順序存貯的線性表中,刪除一個結(jié)點,平均大約需要移動一半結(jié)點。當(dāng)線性表
的結(jié)點很多,且每個結(jié)點的數(shù)據(jù)量相當(dāng)大時,花贄在移劭結(jié)點上的執(zhí)行時間就會很長。
1.2.3用順序存貯的線性表表示多項式
一般代數(shù)多項式可寫成
e,H
A(x)=amx+…+qK+q//
其中每個%(OWiWm)是A(x)的非零系數(shù);次數(shù)4(OWiWm)是遞減的,即>ei)
20。
我們可用包含coef和exp兩個字段的結(jié)點表示多項式的非零項,其中coef給出系數(shù),exp
給出次數(shù).這樣,可用數(shù)組poly[MAXW表示多項式.因此,可使用如下的說明:
#defineMAXN100
typedefstructterm
(
floatcoef;
intexp;
}TERM;
TERMpoly[MAXN];
其中MAXN是數(shù)組poly可存放結(jié)點的最大個數(shù).有時,我們可把MAXN取得適當(dāng)大,使得多個多項
式可共享數(shù)組poly。
例如,對于下面兩個多項式:
A(X)=8X60+6X50+4X25+2X10+1
B(X)=7X60-6X50+3X20
它們在數(shù)組poly中的存貯情況如圖1.2.1所示。
0123456789???MAXN-1
coef864217-63???
exp605025100605020■?■
ahatbhbtfree
圖1.2.1多項式的存貯
我們使用了攘tah和bh,它們分別給出A(x)和B(x)的第一項在數(shù)組中的存放位置,而指
針al和bl分別給出A(x)和B(x)的最后一項在數(shù)組中的存放位置,取free=9;
這里順便指出一點,ah,at,bh,bt及free等,它們其實不是指針,只是一種蝴.這是因為
存放在ah,at,bh,bl及free內(nèi)的不是數(shù)組元素在存貯器中的地址,而是數(shù)組元素的下標(biāo)值,但
由于使用上的習(xí)慣,我們?nèi)匀环Q它們?yōu)橹羔?希望讀者加以區(qū)別.
上面介紹如果用數(shù)組存放多項式的方法,下面我們討論如何用C函數(shù)首先多項式相加的
算法.在下面的程序中,函數(shù)polyadd()首先C(x)=A(x)+B:x)的運(yùn)算;而函數(shù)append。把系數(shù)c
和次數(shù)。構(gòu)成的項存放到指針free所指出的位置上,成為結(jié)果多項式的一個項,同時free加1,
為下次添加結(jié)點但提供存放位置.下面給出C語言的說明及實現(xiàn)運(yùn)算的函數(shù).
^defineMAXN100
typedefstruct
{
intcoef;
intexp;
)TERM;
TERMpoly[MAXN];
intah,at,bh,bt,ch,ct,free;
intappend(c,e)
intc,e;
(
if(free〉=MAXN)return(1);
poly[free],cocf=c;
poly[free++].exp=e;
return(0);
)
intpoly_add(ah,at,bh,bt,p_ch,pct)
intah,at,bh,bt;
int*p_ch,*p_ct;
(
intp,q,pe,qe;
intc;
charch;
p二ah;
q=bh;
*p_ch=free;
while(p<=at&&q<=bt)
{
pe=polyfp].exp;
qe=poly[q].exp;
if(pe==qe)ch="=>;
elseif(pe<qe)ch=><';
elsech='>';
switch(ch)
case'=':
c=poly[p].coef+poly[q].coef;
if(c)
if(append(c,pe))
return(l);
p++;
q++;
break;
case'<':
if(append(poly[q].coef,qe))
return(l);
q++;
break;
case'>’:
if(append(poly[p].coef,pe))
return(l);
P++;
break;
}
)
while(p<=at)
(
if(append(poly[p].coef,poly.[p].exp))
return(l);
P++;
)
while(q<=bt)
if(append(poly[p].cocf,poly[q].exp))
return(l);
*pct=free-l;
return(0);
可用如下的調(diào)用語句執(zhí)行A(x)和B(x)兩個多項式的相加:
if(polyadd(ah,at,bh,bt,&ch,&ct))
printf("ERROR'n");
如果打印出ERROR,那么說明數(shù)組poly不夠用;如果沒有打印出ERROR,但調(diào)用后出現(xiàn)ct/ch,那
么說明相加后得到一個零多項式.
現(xiàn)在分析polyadd。的執(zhí)行時間.首先應(yīng)指出,執(zhí)行函數(shù)append。的時間是0(1).在
polyadd()中,執(zhí)行三個循環(huán)之外的幾個語句的時間也是0(1).所以,執(zhí)行時間主要花費(fèi)在三
個循環(huán)上.設(shè)A(x)和B(x)非零項的個數(shù)分別為m和n,對于第一個循環(huán),當(dāng)A(x)和B(x)的各項的
次數(shù)都不想同時,執(zhí)行循步的次數(shù)最多,共執(zhí)行(mE)次,故其執(zhí)行時間最多為0(min);第二和
第三個循環(huán)最多分別執(zhí)行m次和n次,故其執(zhí)行時間最多分別為0(m)和0(n).這樣,執(zhí)行
po1yadd()的時間為0(1)+0(m+n)+0(m)+0(n)=0(m+n).
1.3順序存貯的棧和隊列
棧和隊列都是特殊的線性表。這兩種結(jié)構(gòu)比一般的線性表簡單,但非常有用,所以有
必要對它們進(jìn)行仔細(xì)討論,
1.3.1棧及其基本運(yùn)算
棧是只允許在一端進(jìn)行插入和刪除的線性表。稱允許插入和刪除的一端為棧頂;稱不
允許插入和刪除的一端為.愎頂。若給定棧5=(so,s.,…,sQ,則sD是棧底結(jié)點,Sn?是棧頂結(jié)
點,s,”是在sMOWiWn-1)之上,棧S的結(jié)構(gòu)圖如圖1.3.1所示.通常稱棧的插入為進(jìn)棧,?稱棧的
刪除為出棧?因為最后進(jìn)棧的結(jié)點必定最先出棧,所以棧具有后進(jìn)先出的特性.這樣,棧也稱
后進(jìn)先出表,簡稱LIFO(LastInFirstOut)表.
棧頂
棧底
圖1.3.1棧的結(jié)構(gòu)
日常生活中有很多棧的例子.比如,我們可以把放在桌上的一疊書看作是一個棧,并約
定不能把書插入中間,或從中間把書抽出.那么,后來放進(jìn)的書只能放在頂上,從這疊書取走
的只能是頂上的那一本.又如圖I.3.2討示的鐵路棧道B,只能從A進(jìn)入B,在B中停留的列車只
能從C離去.這樣,只有最后進(jìn)入棧道B的列車才能馬上向C離去.
我們可以用數(shù)組表示棧,在一般情況下,用一個指針top指向棧頂結(jié)點在數(shù)組的存放位
置,稱lop為棧頂指針.對于C語言來講,下標(biāo)為0的數(shù)組元素也用來存放棧的結(jié)點.我們置
top=-l表示??盏某跏紶顟B(tài).結(jié)點進(jìn)棧時,首先執(zhí)行top加1,使top指向進(jìn)棧結(jié)點在數(shù)組的存
放位置,然后把進(jìn)棧結(jié)點送到top當(dāng)前所指的位置上;在執(zhí)行出棧時,首先把top所指向的棧頂
結(jié)點送到接受結(jié)點的變量中,然后執(zhí)行top減1,使top指向新的棧頂結(jié)點.進(jìn)棧和出棧可以交
替進(jìn)行.當(dāng)成功的出棧次數(shù)等于成功的進(jìn)棧次數(shù)時,這時出現(xiàn)top=T的??諣顟B(tài).??諘r不能
出棧.如果表示棧的數(shù)組共有MAXN個元素,那么當(dāng)成功的進(jìn)棧比成功的山棧多MAXN次時,這時
出現(xiàn)top=MAXNT的棧滿狀態(tài).棧滿時不能進(jìn)棧,圖1.3.3表示棧的這種表示方法.
第二種用C語言的數(shù)組表示棧的方法時用棧頂指針lop指向下一次進(jìn)棧結(jié)點的存放位
置,并用top=0表示???,當(dāng)top=MAXN時,表示棧滿.圖1.3.裱明了這種表示方法.在結(jié)點進(jìn)棧
時,首先把結(jié)點送到lop所指的數(shù)組元素中,然后top加1,比lop指向下次結(jié)點進(jìn)棧的存放位置;
在出棧時,首先top減1,然后把top現(xiàn)在所指的數(shù)組元素所存放的結(jié)點送到接受出棧結(jié)點的變
量中.當(dāng)然,在出現(xiàn)??諘r,不能出棧;在出現(xiàn)棧滿時,不能進(jìn)棧.圖1.3.靜出每次進(jìn)棧和出棧
時棧的變化情況.
在下面實現(xiàn)棧的運(yùn)算時,采用如儆.3.初『示的第二種表示方法.對于第一種棧的表示
方法,處理棧的運(yùn)算也是相似的,請讀者自己去完成.
下面給出C語言的說明及實現(xiàn)棧運(yùn)算的函數(shù).假設(shè)棧中結(jié)點的數(shù)據(jù)類型是char.
#defineMAXN26
charstack[MAXN];
inttop=0;/*把棧置成空的狀態(tài)*/
intpush(x)/*push。函數(shù)實現(xiàn)結(jié)點x進(jìn)棧*/
chairx;
(
if(lop>=MAXN)
return(l);/*棧滿,進(jìn)棧失敗,返回1*/
stack[top++]=x;
return(0);/*進(jìn)棧成功,返回0*/
intpop(p_y)/*pop()函數(shù)實現(xiàn)出棧*/
char*p_y;
if(top==0)
return(l);/*??眨鰲J?,返回1*/
*P_y=stack[-top];
return(0);/*出棧成功,返回0*/
1.3.2隊列及其基本運(yùn)算
隊列是只允許在一端進(jìn)行插入,且只允許在另一端進(jìn)行刪除的線性表.稱允許刪除的
一端為班直,.稱允許插入的i端為JO。有時稱隊列的插入為進(jìn)叢;稱隊列的刪除為出?限.
若給定的隊列為Q=(q°,q】,…,qn-i),則q0是隊首結(jié)點,qm是隊尾結(jié)點,q:在q.之前,q-
在卬之后(OWiWnT).圖1.3.6給出隊列Q的結(jié)構(gòu).因為最先進(jìn)入隊列的結(jié)點必定最先出隊.
所以隊列具有先進(jìn)先出的特性.因此,隊列也稱先進(jìn)先出表,簡稱£!K(FirstInFirstOut)
&
出隊^_qOq1...qiqi+1...qn-1----------進(jìn)隊
隊首隊尾
圖1.3.6隊列Q的結(jié)構(gòu)
我們可以用數(shù)組表示隊列,通常用一個指針head指向隊首結(jié)點在數(shù)組的存放位置,稱
head為頭指軌;用另一個指針tail指向隊尾結(jié)點在數(shù)組的存放位置,稱tail為星指針.我們置
head=O和tail=T表示隊列空的初始狀態(tài).
假設(shè)用C語言的數(shù)組q[\IAXN]表示隊列,當(dāng)tail=MAXNT時,出現(xiàn)隊列滿.在隊列不滿時,
可執(zhí)行進(jìn)隊運(yùn)算.進(jìn)隊時,首先執(zhí)行tail加1,使tail給出新結(jié)點的存放位置,再把新結(jié)點送到
由tail所指的數(shù)組元素中.在隊列非空時,可執(zhí)行出隊運(yùn)算.出隊時,首先把head所指的隊首
結(jié)點送到接受結(jié)點的變量中,然后執(zhí)行head加1,使head指向新的隊首結(jié)點.當(dāng)頭指針超過尾
指針時,出現(xiàn)隊空狀態(tài),這時有head>tail.圖1.3.琳述了用這種方法表示隊列的進(jìn)隊和出隊
的情況.
為配合下面環(huán)形隊列的描述,這里給出隊列的第二種表示方法.我們讓頭指針head指
向存放隊首結(jié)點的數(shù)組元素的前?個數(shù)組元素,而不是指向隊首結(jié)點的數(shù)組元素;讓尾指針
tail仍然指向存放隊尾結(jié)點的數(shù)組元素.這時,隊列空的初始狀態(tài)是hcad=tail=T.在經(jīng)過多
次進(jìn)隊和出隊運(yùn)算之后,一旦head趕上tail(即head二tail)時,則出現(xiàn)隊列空.隊列滿的標(biāo)志
仍然是tail=MAXN-l.圖L3.硼述了用第二種表示方法時進(jìn)隊和出隊的情況.
對于用笫一種方法表示的隊列,在隊列不滿的情況下,允許進(jìn)隊.進(jìn)隊時,首先讓tail
加1,然后把新結(jié)點存放在由tail所指的數(shù)組元素中.在隊列非空的情況下,允許出隊.出隊時,
首先讓head加1,然后將存放在由head指出的數(shù)組元素中的結(jié)點取出,送到接受出隊結(jié)點的變
量中.
下面給出C語言的說明及實現(xiàn)用第二種方法表示的隊列的進(jìn)隊和退隊的函數(shù).
^defineMAXN26
charq[MAXN];
inthead=-l,tail=-l;
inten_queue(x)/*結(jié)點x進(jìn)隊*/
charx;
(
if(tail==MAXN-l)
return(l);
q[++tail]=x;
return(0);/*進(jìn)隊成功,返回0*/
)
intdc_queue(py)/*出隊*/
char*p_y;
(
if(head==tail)
return(1);/*對空,不能出隊,返回1*/
*P_y=q[++head];/*頭指針加1,把隊首結(jié)點送到指針
p_y所指的變量中*/
return(0);/*出隊成功,返回0*/
)
從圖I.3.8可以看出,一旦出現(xiàn)tail=MAXNT時,盡管原來存放出隊結(jié)點的數(shù)組元素已
空著,但卻沒有再被使用.所以,當(dāng)tail=MAXNT時,隊列不是真正的滿,而是假滿.這時,我們
可以采取卜面的處理方法.以充分利用已空著的數(shù)組元素.首先,當(dāng)隊列出現(xiàn)隊空時,就把頭
指針和尾指針置成隊空的初始狀態(tài),即置headrail二T.另外,可采用兩種極端方法:一是當(dāng)
一個結(jié)點出隊時,就把隊列中所有的結(jié)點都依次向隊首方向移動?個位置,并修改頭指針和
尾指針;另一是當(dāng)tai1=MAXNT且隊列不是真正滿時,把隊列的所有結(jié)點都依次移到數(shù)組的最
前端,并修改頭指針和尾指針.雖然這兩種方法都能充分利用數(shù)組元素,但需要移動隊列的所
有結(jié)點,這樣做很麻煩且花費(fèi)時間.為了克服這一缺點,我們下面引進(jìn)更為實用的環(huán)形隊列.
1.3.3環(huán)形隊列
如果我們把表示隊列的數(shù)組的元素q[0]和q[MAXNT]連接起來,形成一個環(huán)形的表,稱
這樣的環(huán)形表為環(huán)形隊列(見圖/.3.9).初始時,置隊列空的初態(tài)為head=tail=0,如圖?所
示.此時,如果連續(xù)進(jìn)隊三次,那么進(jìn)隊后的隊列如圖b所示.然后出隊兩次,則有如圖c所示的
隊列.
在隊列不滿的情況下,可以進(jìn)隊.當(dāng)出現(xiàn)tail=hcad時,隊列已滿,此時不能再進(jìn)隊了,
如圖c所示.在隊列非空的情況下,可以出隊.當(dāng)出現(xiàn)headXail時,隊列已空,此時不能再出隊
了,如圖e所示.由此可見,環(huán)形隊列的隊滿和隊空都有hcad=tail.
如上所述,環(huán)形隊列的隊滿和隊空都有headrail.因此,不能只用headfail來判斷隊
滿或隊空.此時,必須增加一個標(biāo)志tag.在head=tail的情況下,由tag為0(或1)來表示隊列空
(或滿).根據(jù)環(huán)形隊列的特點,下面給出實現(xiàn)進(jìn)隊和出隊的函數(shù).環(huán)形隊列空的初始狀態(tài)為
head=tail=0,且tag=0.
#defineMAXN26
cheirq[MAXN];
inthead=0,tai1=0,tag=D;
intenqueue(x)
charx;
(
if(tail==head&&tag==l)
return(l);/*隊滿,進(jìn)隊失敗,返回1*/
tail=(tail+l)%MAXN;
q[tail]=x;
if(tail==hcad)tag=l;/*置堆滿標(biāo)志*/
return(0);/*進(jìn)隊成功,返回0*/
)
intde_queue(py)
char*p_y;
{
if(head==tail&&tag==O)
return(l);/*隊列空,出隊失敗,返回1*/
head=(head+l)%MAXN;
*p_y=qLhead];
if(hecid==tail)tag=0;/*置隊空標(biāo)志*/
return(0);/*出隊成功,返回0*/
)
由于增加了一個標(biāo)志tag,使得程序的語句增加了,判斷條件也更雜了,這樣將增加程
序的運(yùn)行時間.在頻繁執(zhí)行進(jìn)隊和出隊運(yùn)算的情況下,如操作系統(tǒng)的作業(yè)排隊和進(jìn)程排隊,將
大大地增加運(yùn)行時間.為了盡量提高運(yùn)行速度而減少執(zhí)行時間,我們以?個結(jié)點所占用的存
貯空間為代價,來節(jié)省執(zhí)行時間.實現(xiàn)的辦法是在進(jìn)隊時,首先讓tail加上1進(jìn)行模MAXN運(yùn)算
后,再存入tail.然后判別tail是否已趕上head:如果tail沒有趕上head,那么就執(zhí)行進(jìn)隊運(yùn)
算;如果tail趕上head,盡管還有一個空的數(shù)組元素可以存放進(jìn)隊結(jié)點,但我們不允許新結(jié)點
進(jìn)隊,而是報告隊滿.引入上述機(jī)制后,可以把上面兩個函數(shù)改寫成如下的函數(shù):
^defineMAXN26
charq[MAXN];
inthead=0,tai1=0;
intencq(x)
charx;
{
tail=(tail+l)%MAXN;
if(tail==head)
(
if(tail==0)
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 46794-2025化工園區(qū)氣體防護(hù)站建設(shè)運(yùn)行指南
- 2025年興業(yè)銀行珠海分行社會招聘備考題庫及參考答案詳解一套
- 2026年建筑材料標(biāo)準(zhǔn)化合同
- 2026年建筑質(zhì)量保證金合同
- 2025年達(dá)州銀行股份有限公司社會招聘備考題庫帶答案詳解
- 2026年藥品含量測定方法學(xué)驗證合同
- 2025年廣西工藝美術(shù)研究院有限公司所屬企業(yè)廣西絹麻紡織科學(xué)研究所有限公司招聘備考題庫及參考答案詳解
- 急性乳腺炎溝通記錄
- 2025年安全生產(chǎn)監(jiān)管人員考試試題及答案(完整版)
- 2025年濟(jì)南市檢察機(jī)關(guān)公開招聘聘用制書記員25人備考題庫及參考答案詳解1套
- 墻壁維護(hù)施工方案(3篇)
- 人工智能安全風(fēng)險測評白皮書(2025年)
- 2025下半年貴州遵義市第一人民醫(yī)院招聘事業(yè)單位65人筆試備考重點試題及答案解析
- 圍麻醉期應(yīng)激反應(yīng)的調(diào)控策略
- 2025年外貿(mào)實習(xí)合同協(xié)議
- 集成電路封裝測試廠建設(shè)項目可行性研究報告
- 醫(yī)院服務(wù)禮儀培訓(xùn)
- 亞朵酒店管理分析
- 弘歷指標(biāo)源碼6個(僅提供源碼)
- 新產(chǎn)品開發(fā)項目進(jìn)度計劃表
- 設(shè)計公司生產(chǎn)管理辦法
評論
0/150
提交評論