嚴(yán)蔚敏數(shù)據(jù)結(jié)構(gòu)習(xí)題集答案_第1頁
嚴(yán)蔚敏數(shù)據(jù)結(jié)構(gòu)習(xí)題集答案_第2頁
嚴(yán)蔚敏數(shù)據(jù)結(jié)構(gòu)習(xí)題集答案_第3頁
嚴(yán)蔚敏數(shù)據(jù)結(jié)構(gòu)習(xí)題集答案_第4頁
嚴(yán)蔚敏數(shù)據(jù)結(jié)構(gòu)習(xí)題集答案_第5頁
已閱讀5頁,還剩150頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

嚴(yán)蔚敏《數(shù)據(jù)結(jié)構(gòu)(C語言版)習(xí)題集》答案

第一章緒論

1.16

voidprint_descending(intx,inty,intz)〃按從大到小順序輸出三個(gè)數(shù)

(

scanf(n%d,%d,%dn,&x,&y,&z);

if(x<y)x<->y;〃v.>為表示交換的雙目運(yùn)算符似下同

if(y<z)y<->z;

if(xvy)xv->y;〃冒泡排序

printf(n%d%d%d",x,y,z);

}//print_descending

1.17

Statusfib(intk,intm,int&f)〃求k階斐波那契序列的第m項(xiàng)的值f

(

inttempd;

if(k<2llm<0)returnERROR;

if(m<k-l)f=0;

elseif(m=k-1IIm==k)f=l;

else

(

for(i=0;i<=k-2;i++)temp[i]=0;

temp[k?l]=l;temp[k]=l;〃初始化

sum=l;

j=0;

for(i=k+l;i<=m;i++,j++)〃求出序列第k至第m個(gè)元素的值

tempfi]=2*sum-temp[j];

f=temp[m];

returnOK;

}//fib

分析:k階斐波那契序列的第m項(xiàng)的值f[m]=f(m-11+f[m-2]+....4-ffm-k]

=f[m-l]+f[m-2]+.....+f[m-k]+f[m-k-1]-f[m-k-1]

=2*f[m-l]-f[m-k-l]

所以上述算法的時(shí)間復(fù)雜度僅為O(m).如果采用遞歸設(shè)計(jì),將達(dá)到0(k八m).即使采用暫存中

間結(jié)果的方法,也將達(dá)到O(m八2).

1.18

typedefstruct{

char*sport;

enum{male,female}gender;

charschoolname;//校名為AKCD或E'

char.result;

intscore;

}resulttype;

typedefstruct{

intmalescore;

intfemalescore;

inttotalscore;

}scoretype;

voidsummary(resulttyperesult]])〃求各校的男女總分和團(tuán)體總分,假設(shè)結(jié)果已經(jīng)儲(chǔ)存在result口

數(shù)組中

(

scoretypescorefMAXSIZE];

i=0;

while(result[i].sport!=NULL)

(

switch(result[i].schoolname)

(

case'A':

score[0].totalscore+=result[i].score;

if(result[i].gender==0)scoref0].malescore+=result[i].score;

elsescore[0l.femalescore+=result[i].score;

break;

case'B':

score[0].totalscore+=result[i].score;

if(result[i].gender==0)score[0].malescore+=result[i].score;

elsescore[0].femalescore+=result[i].score;

break;

i++;

)

for(i=0;i<5;i++)

(

printf(HSchool%d:\n",i);

printf(nTotalscoreofmale:%d\nH,score[i].malescore);

printf(nTotalscoreoffemale:%d\n",score[i].femalescore);

printf(nTotalscoreofall:%d\n\n'\scoreri].totalscore);

)

}//summary

1.19

Statusalgoll9(inta[ARRSIZE])〃求i!*2八i序列的值且不超過maxint

(

last=l;

for(i=1;i<=ARRSIZE;i++)

(

a[i-l]=last*2*i;

if((a[i-l]/last)!=(2*i))reumOVERFLOW;

last=a[i-l];

returnOK;

)

}//algoll9

分析:當(dāng)某一項(xiàng)的結(jié)果超過了maxint時(shí),它除以前面一項(xiàng)的商會(huì)發(fā)生異常.

1.20

voidpolyvalue()

floattemp;

float*p=a;

printf(nInputnumberofterms:,r);

scanf(H%d'\&n);

printf(HInputvalueofx:n);

scanf(n%fn,&x);

printf("Inputthe%dcoefficientsfromaOtoa%d:\nH,n+l,n);

p=a;xp=l;sum=O;//xp用于存放x的i次方

for(i=0;i<=n;i++)

(

scanf(,'%f,,,&temp);

sum+=xp*(temp);

xp*=x;

)

printf(nValueis:%fn,sum);

}//polyvalue

第二章線性表

2.10

StatusDeleteK(SqList&a,inti,intk)〃刪除線性表a中第i個(gè)元素起的k個(gè)元素

(

if(i<lllk<Olli+k-l>a.length)returnINFEASIBLE;

for(count=1;i+count?1v=a.length-k;count++)〃注意循環(huán)結(jié)束的條件

a.elem[i+count-1]=a.elem[i+count+k-1];

a.length-=k;

returnOK;

}//DeleteK

2.11

StatusInsert_SqList(SqList&va,intx)〃把x插入遞增有序表va中

if(va.length+1>va.listsize)returnERROR;

va.length++;

for(i=va.length-l;va.elem[i]>x&&i>=0;i—)

va.elem[i+1]=va.elem[i];

va.elem[i+l]=x;

returnOK;

}//Insert_SqList

2.12

intListComp(SqListA,SqListB)〃比較字符表A和B,并用返回值表示結(jié)果,值為1,表示A>B;值

為-1,表示A<B;值為0,表示A=B

(

for(i=1;i<=A.length&&i<=B.length;i++)

if(A.elem[i]!=B.elem[i])

returnA.elem[i]>B.elem[i]?l:-l;

if(A.length==B.length)return0;

returnA.length>B.length?l:-l;〃當(dāng)兩個(gè)字符表可以互相比較的部分完全相同時(shí),哪個(gè)較長,

哪個(gè)就較大

}//ListComp

2.13

LNode*Locate(LinkListL,intx)〃鏈表上的元素查找,返回指針

(

for(p=l->next;p&&p->data!=x;p=p->next);

returnp;

}//Locate

2.14

intLength(LinkListL)〃求鏈表的長度

(

for(k=0,p=L;p->next;p=p->next,k++);

returnk;

}//Length

2.15

voidListConcat(LinkListha,LinkListhb,LinkList&hc)〃把鏈表hb接在ha后面形成鏈表he

(

hc=ha;p=ha;

while(p->next)p=p->next;

p->next=hb;

}//ListConcat

2.16

見書后答案.

2.17

StatusInsert(LinkList&L,inti,intb)〃在無頭結(jié)點(diǎn)鏈表L的第i個(gè)元素之前插入元素b

(

p=L;q=(LinkList*)malloc(sizeof(LNode));

q.data=b;

if(i==l)

(

q.next=p;L=q;//插入在鏈表頭部

)

else

(

while(—i>l)p=p->next;

q->next=p->next;p->next=q;〃插入在第i個(gè)元素的位置

}

}//Insert

2.18

StatusDelete(LinkList&L,inti)〃在無頭結(jié)點(diǎn)鏈表L中刪除第i個(gè)元素

(

if(i==l)L=L->next;〃刪除第一'個(gè)元素

else

(

P=L;

while(—i>l)p=p->next;

p->next=p->next->next;〃刪除第i個(gè)元素

}

}//Delete

2.19

StatusDelete_Between(Linklist&L,intmink,intmaxk)〃刪除元素遞增排列的鏈表L中值大于

mink且小于maxk的所有元素

P=L;

while(p->next->data<=mink)p=p->next;//p是最后一個(gè)不大于mink的元素

if(p->next)〃如果還有比mink更大的元素

(

q=p->next;

while(q->data<maxk)q=q->next;//q是第一個(gè)不小于maxk的元素

p->next=q;

)

}//Delete_Between

2.20

StatusDelete_Equal(Linklist&L)〃刪除元素遞增排列的鏈表L中所有值相同的元素

(

p=L->next;q=p->next;//p,q指向相鄰兩元素

while(p->next)

(

if(p->data!=q->data)

(

p=p->next;q=p->next;〃當(dāng)相鄰兩元素不相等時(shí),p,q都向后推一步

)

else

(

while(q->data==p->data)

(

free(q);

q=q->next;

)

p->next=q;p=q;q=p->next;〃當(dāng)相鄰元素相等時(shí)刪除多余元素

}//else

}//while

}//Delete_Equal

2.21

voidreverse(SqList&A)〃順序表的就地逆置

for(i=l,j=A.length;i<j;i++,j—)

A.elem[i]<->A.elem[j];

}//reverse

2.22

voidLinkList_reverse(Linklist&L)〃鏈表的就地逆置;為簡化算法,假設(shè)表長大于2

(

p=L->next;q=p->next;s=q->next;p->next=NULL;

while(s->next)

(

q->next=p;p=q;

q=s;s=s->next;〃把L的元素逐個(gè)插入新表表頭

)

q->next=p;s->next=q;L->next=s;

}//LinkList_reverse

分析:本算法的思想是,逐個(gè)地把L的當(dāng)前元素q插入新的鏈表頭部,p為新表表頭.

2.23

voidmergel(LinkList&A,LinkList&B,LinkList&C)〃把鏈表A和B合并為C,A和B的元素間

隔排列,且使用原存儲(chǔ)空間

(

p=A->next;q=B->next;C=A;

while(p&&q)

{

s=p->next;p->next=q;〃將B的元素插入

if(s)

(

t=q->next;q->next=s;〃如A非空,將A的元素插入

)

p=s;q=t;

{//while

}//merge1

2.24

voidreverse_merge(LinkList&A,LinkList&B,LinkList&C)〃把元素遞增排列的鏈表A和B合并

為C,且C中元素遞減排列,使用原空間

pa=A-〉next;pb=B->next;pre=NULL;〃pa和pb分別指向A,B的當(dāng)前元素

while(pallpb)

(

if(pa->data<pb->datall!pb)

(

pc=pa;q=pa->next;pa->next=pre;pa=q;〃將A的元素插入新表

}

else

(

pc=pb;q=pb->next;pb->next=pre;pb=q;〃將B的元素插入新表

)

pre=pc;

)

C=A;A->next=pc;〃構(gòu)造新表頭

}//reverse_merge

分析:本算法的思想是,按從小到大的順序依次把A和B的元素插入新表的頭部pc處,最后處理

A或B的剩余元素.

2.25

voidSqList_Intersect(SqListA,SqListB,SqList&C)〃求元素遞增排列的線性表A和B的元素的

交集并存入C中

(

i=l;j=l;k=O;

while(A.elem[i]&&B.elem[j])

(

if(A.elem[i]<B.elem[j])i++;

if(A.elem[i]>B.elemfj])j++;

if(A.elem[i]==B.elem[j])

(

C.elem[++k]=A.elem[i];〃當(dāng)發(fā)現(xiàn)了一個(gè)在A,B中都存在的元素,

i++;j++;〃就添加到C中

}//while

}//SqList_Intersect

2.26

voidLinkList_Intersect(LinkListA,LinkListB,LinkList&C)〃在鏈表結(jié)構(gòu)上重做上題

(

p=A->next;q=B->next;

pc=(LNode*)malloc(sizeof(LNode));

C=pc;

while(p&&q)

(

if(p->data<q->data)p=p->next;

elseif(p->data>q->data)q=q->next;

else

(

s=(LNode*)malloc(sizeof(LNode));

s->data=p->data;

pc->next=s;pc=s;

p=p->next;q=q->next;

)

}//while

}〃LinkList_Intersect

2.27

voidSqList_Intersect_True(SqList&A,SqListB)〃求元素遞增排列的線性表A和B的元素的交

集并存回A中

(

i=l;j=l;k=O;

while(A.elem[i]&&B.elemfj])

(

if(A.elem[i]<B.elem[j])i++;

elseif(A.elem[i]>B.elem[j])j++;

elseif(A.elem[i]!=A.elem[k])

(

A.elem[++k]=A.elem[i];〃當(dāng)發(fā)現(xiàn)了一個(gè)在A,B中都存在的元素

i++;j++;〃且C中沒有,就添加到C中

else{i++;j++;}

}//while

while(A.elem[k])A.elem[k++]=O;

}//SqList_Intersect_True

2.28

voidLinkList_Intersect_True(LinkList&A,LinkListB)〃在鏈表結(jié)構(gòu)上重做上題

(

p=A->next;q=B->next;pc=A;

while(p&&q)

(

if(p->data<q->data)p=p->next;

elseif(p->data>q->data)q=q->next;

elseif(p->data!=pc->data)

(

pc=pc->next;

pc->data=p->data;

p=p->next;q=q->next;

)

}//while

}//LinkList_Intersect_True

2.29

voidSqList_Intersect_Delete(SqList&A,SqListB,SqListC)

(

i=0;j=0;k=0;m=0;//i指示A中元素原來的位置,m為移動(dòng)后的位置

while(i<A.length&&j<B.length&&k<C.length)

(

if(B.elem[j]<C.elem[k])j++;

elseif(B.elem[j]>C.elem[k])k++;

else

(

same=B.elemfjl;〃找到了相同元素same

while(B.elem[j]==same)j++;

while(C.elem[k]==same)k++;//j,k后移到新的元素

while(i<A.length&&A.elem[i]<same)

A.elem[m++]=A.elem[i+4-];〃需保留的元素移動(dòng)到新位置

while(i<A.length&&A.elem[i]==same)i++;〃跳過相同的元素

)

}//while

while(i<A.length)

A.elem[m++]=A.elem[i++];//A的剩余元素重新存儲(chǔ)。

A.length=m;

}//SqList_Intersect_Delete

分析:先從B和C中找出共有元素,記為same,再在A中從當(dāng)前位置開始,凡小于same的

元素均保留(存到新的位置),等于same的就跳過,到大于same時(shí)就再找下一個(gè)same.

2.30

voidLinkList_Intersect_Delete(LinkList&A,LinkListB,LinkListC)〃在鏈表結(jié)構(gòu)上重做上題

(

p=B->next;q=C->next;r=A-next;

while(p&&q&&r)

(

if(p->data<q->data)p=p->next;

elseif(p->data>q->data)q=q->next;

else

(

u=p->data;〃確定待刪除元素u

while(r->next->data<u)r=r?>next;〃確定最后一個(gè)小于u的元素指針r

if(r->next->data==u)

{

s=r->next;

while(s->data==u)

(

t=s;s=s->next;free(t);〃確定第?個(gè)大于u的元素指針s

}//while

r->next=s;〃刪除r和s之間的元素

}//if

while(p->data=u)p=p->next;

while(q->data=u)q=q->next;

}//else

}//while

}//LinkList_Intersect_Delete

2.31

StatusDelete_Pre(CiLNode*s)〃刪除單循環(huán)鏈表中結(jié)點(diǎn)s的直接前驅(qū)

(

p=s;

while(p->next->next!=s)p=p->next;〃找至ljs的前驅(qū)的前驅(qū)p

p->next=s;

returnOK;

}//Delete_Pre

2.32

StatusDuLNode_Pre(DuLinkList&L)〃完成雙向循環(huán)鏈表結(jié)點(diǎn)的pre域

(

for(p=L;!p->next->pre;p=p->next)p->next->pre=p;

returnOK;

}//DuLNode_Pre

2.33

StatusLinkList_Divide(LinkList&L,CiList&A,CiList&B,CiList&C)〃把單鏈表L的元素按類型

分為三個(gè)循環(huán)鏈表CiList為帶頭結(jié)點(diǎn)的單循環(huán)鏈表類型.

{

s=L->next;

A=(CiList*)malloc(sizeof(CiLNode));p=A;

B=(CiList*)malloc(sizeof(CiLNode));q=B;

C=(CiList*)malloc(sizeof(CiLNode));r=C;〃建立頭結(jié)點(diǎn)

while(s)

(

if(isalphabet(s->data))

p->next=s;p=s;

elseif(isdigit(s->data))

q->next=s;q=s;

)

else

(

r->next=s;r=s;

}

}//while

p->next=A;q->next=B;r->next=C;〃完成循環(huán)鏈表

}//LinkList_Divide

2.34

voidPrint_XorLinkedList(XorLinkedListL)〃從左向右輸出異或鏈表的元素值

(

p=L.left;pre=NULL;

while(p)

(

printf(n%dn,p->data);

q=XorP(p->LRPtr,pre);

pre=p;p=q;〃任何一個(gè)結(jié)點(diǎn)的LRPtr域值與其左結(jié)點(diǎn)指針進(jìn)行異或運(yùn)算即得到其右結(jié)點(diǎn)指

)

}//Print_XorLinkedList

2.35

StatusInsert_XorLinkedList(XorLinkedList&L,intx,inti)〃在異或鏈表L的第i個(gè)元素前插入元

素x

{

p=L.left;pre=NULL;

r=(XorNode*)malloc(sizeof(XorNode));

r->data=x;

if(i==l)〃當(dāng)插入點(diǎn)在最左邊的情況

p->LRPtr=XorP(p.LRPtr,r);

r->LRPtr=p;

L.left=r;

returnOK;

j=l;q=p->LRPtr;〃當(dāng)插入點(diǎn)在中間的情況

while(++j<i&&q)

(

q=XorP(p->LRPtr,pre);

pre=p;p=q;

"/while〃在p,q兩結(jié)點(diǎn)之間插入

if(!q)returnINFEASIBLE;//i不可以超過表長

p->LRPtr=XorP(XorP(p->LRPtr,q),r);

q->LRPtr=XorP(XorP(q->LRPtr,p),r);

r->LRPtr=XorP(p,q);〃修改指針

returnOK;

}//Insert_XorLinkedList

2.36

StatusDelete_XorLinkedList(XorlinkedList&L,inti)〃刪除異或鏈表L的第i個(gè)元素

(

p=L.left;pre=NULL;

if(i==l)〃刪除最左結(jié)點(diǎn)的情況

(

q=p->LRPtr;

q->LRPtr=XorP(q->LRPtr,p);

L.left=q;free(p);

returnOK;

)

j=l;q=p->LRPtr;

while(++j<i&&q)

(

q=XorP(p->LRPtr,pre);

pre=p;p=q;

"/while〃找到待刪結(jié)點(diǎn)q

if(!q)returnINFEASIBLE;//i不可以超過表長

if(L.right==q)//q為最右結(jié)點(diǎn)的情況

(

p->LRPtr=XorP(p->LRPtr,q);

L.right=p;free(q);

returnOK;

)

r=XorP(q->LRPtr,p);//q為中間結(jié)點(diǎn)的情況,此時(shí)p,r分別為其左右結(jié)點(diǎn)

p->LRPtr=XorP(XorP(p->LRPtr,q),r);

r->LRPtr=XorP(XorP(r->LRPtr,q),p);〃修改指針

free(q);

returnOK;

}//Delete_XorLinkedList

2.37

voidOEReform(DuLinkedList&L)〃按1,3,5,…4,2的順序重排雙向循環(huán)鏈表L中的所有結(jié)點(diǎn)

(

p=L.next;

while(p->next!=L&&p->next->next!=L)

(

p->next=p->next->next;

p=p->next;

)〃此時(shí)p指向最后一個(gè)奇數(shù)結(jié)點(diǎn)

if(p->next==L)p->next=L->pre->pre;

elsep->next=l->pre;

p=p->next;//此時(shí)p指向最后一個(gè)偶數(shù)結(jié)點(diǎn)

while(p->pre->pre!=L)

(

p->next=p->pre->pre;

p=p->next;

)

p->next=L;〃按題目要求調(diào)整了next鏈的結(jié)構(gòu),此時(shí)pre鏈仍為原狀

for(p=L;p->next!=L;p=p->next)p->next->pre=p;

L->pre=p;〃調(diào)整pre鏈的結(jié)構(gòu),同2.32方法

}//OEReform

分析:next鏈和pre鏈的調(diào)整只能分開進(jìn)行.如同時(shí)進(jìn)行調(diào)整的話,必須使用堆棧保存偶數(shù)結(jié)點(diǎn)的

指針,否則將會(huì)破壞鏈表結(jié)構(gòu),造成結(jié)點(diǎn)丟失.

2.38

DuLNode*Locate_DuList(DuLinkedList&L,intx)〃帶freq域的雙向循環(huán)鏈表上的查找

{

p=L.next;

while(p.data!=x&&p!=L)p=p->next;

if(p==L)returnNULL;//沒找至U

p->freq++;q=p->pre;

while(q->freq<=p->freq&&p!=L)q=q->pre;〃查找插入位置

if(q!=p->pre)

(

p->pre->next=p->next;p->next->pre=p->pre;

q->next->pre=p;p->next=q->next;

q?>next=p;p->pre=q;〃調(diào)整位置

)

returnp;

}//Locate_DuList

2.39

floatGetValue_SqPoly(SqPolyP,intx0)〃求升幕順序存儲(chǔ)的稀疏多項(xiàng)式的值

(

PolyTerm*q;

xp=l;q=P.data;

sum=0;ex=0;

while(q->coef)

(

while(ex<q->exp)xp*=xO;

sum+=q->coef*xp;

q++;

)

returnsum;

}//GetValue_SqPoly

2.40

voidSubtract_SqPoly(SqPolyPl,SqPolyP2,SqPoly&P3)〃求稀疏多項(xiàng)式Pl減P2的差式P3

(

PolyTerm*p,*q,*r;

Create_SqPoly(P3);//建立空多項(xiàng)式P3

p=Pl.data;q=P2.data;r=P3.data;

while(p->coef&&q->coef)

(

if(p>>exp<q->exp)

(

r->coef=p->coef;

r->exp=p->exp;

p++;r++;

}

elseif(p->exp<q->exp)

(

r->coef=-q->coef;

r->exp=q->exp;

q++;r++;

)

else

(

if((p->coef.q.>coef)!=0)〃只有同次項(xiàng)相減不為零時(shí)才需要存入P3中

(

r->coef=p->coef-q->coef;

r->exp=p->exp;r++;

}//if

p++;q++;

}//else

}//while

while(p->coef)〃處理Pl或P2的剩余項(xiàng)

r->coef=p->coef;

r->exp=p->exp;

p++;r++;

)

while(q->coef)

(

r->coef=-q->coef;

r->exp=q->exp;

q++;r++;

}

}//Subtract_SqPoly

2.41

voidQiuDao_LinkedPoly(LinkedPoly&L)〃對(duì)有頭結(jié)點(diǎn)循環(huán)鏈表結(jié)構(gòu)存儲(chǔ)的稀疏多項(xiàng)式L求導(dǎo)

(

p=L->next;

if(!p->data.exp)

(

L->next=p->next;p=p->next;〃跳過常數(shù)項(xiàng)

)

while(p!=L)

(

p->data.coef*=p->data.exp--;〃對(duì)每?項(xiàng)求導(dǎo)

p=p->next;

)

}//QiuDao_LinkedPoly

2.42

voidDivide_LinkedPoly(LinkedPoly&L,&A,&B)〃把循環(huán)鏈表存儲(chǔ)的稀疏多項(xiàng)式L拆成只含奇

次項(xiàng)的A和只含偶次項(xiàng)的B

(

p=L->next;

A=(PolyNode*)malloc(sizeof(PolyNode));

B=(PolyNode*)malloc(sizeof(PolyNode));

pa=A;pb=B;

while(p!=L)

if(p->data.exp!=2*(p>>data.exp/2))

pa->next=p;pa=p;

)

else

(

pb->next=p;pb=p;

)

p=p->next;

}//while

pa->next=A;pb->next=B;

}//Divide_LinkedPoly

第三章棧與隊(duì)列

3.15

typedefstruct{

Elemtype*base[2];

Elemtype*top[2];

JBDStacktype;〃雙向棧類型

StatusInit_Stack(BDStacktype&tws,intm)〃初始化一個(gè)大小為m的雙向棧tws

(

tws.base[0]=(Elemtype*)mailoc(sizeof(Elemtype));

tws.base[l]=tws.base[O]+m;

tws.top[0]=tws.base[0];

tws.topfl]=tws.base[l];

returnOK;

}//Init_Stack

Statuspush(BDStacktype&tws,inti,Elemtypex)//x入棧,i=0表示低端棧,i=l表示高端棧

(

if(tws.top[0]>tws.top[1])returnOVERFLOW;〃注意止匕時(shí)的棧滿條件

if(i==0)*tws.top[0]++=x;

elseif(i==l)*tws.top[l]—=x;

elsereturnERROR;

returnOK;

}//push

Statuspop(BDStacktype&tws,inti,Elemtype&x)//x出棧,i=0表示低端棧,i=l表示高端棧

{

if(i==0)

(

if(tws.top[0]==tws.base[0])returnOVERFLOW;

x=*—tws.topfO];

}

elseif(i==l)

(

if(tws.top[1]==tws.basef1])returnOVERFLOW;

x=*4-+tws.top[l];

}

elsereturnERROR;

returnOK;

}〃pop

3.16

voidTrain_arrange(char*train)〃這里用字符串train表示火車,H表示硬席,S1表示軟席

(

p=train;q=train;

InitStack(s);

while(*p)

(

if(*p='H')push(s,*p);〃把H存入棧中

else*(q++)=*p;〃把S'調(diào)至愉部

P++;

)

while(!StackEmpty(s))

pop(s,c);

*(q++)=c;〃把H接在后部

)

}//Train_arrange

3.17

intIsReverse()〃判斷輸入的字符串中&前和&后部分是否為逆串,是則返回1,否則返回0

(

InitStack(s);

while((e=getchar())!='&')

{

if(e==,@,)return0;〃不允許在之前出現(xiàn),e

push(s,e);

)

while((e=getchar())!=*@*)

(

if(StackEmpty(s))return0;

pop(s,c);

if(e!=c)return0;

)

if(!StackEmpty(s))return0;

return1;

}//IsReverse

3.18

StatusBracket_Test(char*str)〃判別表達(dá)式中小括號(hào)是否匹配

(

count=0;

for(p=str;*p;p++)

(

if(*p==gcount++;

elseif(*p==)')count—;

if(count<0)returnERROR;

}

if(count)returnERROR;〃注意括號(hào)不匹配的兩種情況

returnOK;

}//Bracket_Test

3.19

StatusAllBrackets_Test(char*str)〃判別表達(dá)式中三種括號(hào)是否匹配

(

InitStack(s);

for(p=str;*p;p++)

(

if(*p==,(,||*p==,[|||*p==,{,)push(s,*p);

elseif(*p==')'||*p==']'||*p==T)

(

if(StackEmpty(s))returnERROR;

pop(s,c);

if(*p==')'&&c!='(')returnERROR;

if(*p==']'&&c;='[')returnERROR;

if(*p=='}'&&c!='{')returnERROR;〃必須與當(dāng)前棧頂括號(hào)匹配

}

}//for

if(!StackEmpty(s))returnERROR;

returnOK;

}//AllBrackets_Test

3.20

typedefstruct{

.intx;

inty;

}coordinate;

voidRepaint_Color(intg[m][n],inti,intj,intcolor)〃把點(diǎn)(i,j)相鄰區(qū)域的顏色置換為color

(

old=g[i][j];

InitQueue(Q);

EnQueue(Q,{I,j});

while(!QueueEmpty(Q))

DeQueue(Q,a);

x=a.x;y=a.y;

if(x>l)

if(g[x-l][y]==old)

(

g[x-l]fy]=color;

EnQueue(Q,{x-1,y});〃修改左鄰點(diǎn)的顏色

)

if(y>D

if(g[x][y-l]==old)

(

g[x][y-l]=color;

EnQueue(Q,{x,y-l});//修改上鄰點(diǎn)的顏色

)

if(x<m)

if(g[x+l][y]==old)

(

g[x+l][y]=color;

EnQueue(Q,{x+1,y});〃修改右鄰點(diǎn)的顏色

)

if(y<n)

if(g[x][y+l]==old)

(

g[x][y+l]=color;

EnQueue(Q,{x,y+l});〃修改下鄰點(diǎn)的顏色

)

}//while

}//Repaint_Color

分析:本算法采用了類似于圖的廣度優(yōu)先遍歷的思想,用兩個(gè)隊(duì)列保存相鄰?fù)c(diǎn)的橫坐標(biāo)和

縱坐標(biāo).遞歸形式的算法該怎么寫呢?

3.21

voidNiBoLan(char*str,char*new)〃把中綴表達(dá)式str轉(zhuǎn)換成逆波蘭式new

p=str;q=new;〃為方便起見,設(shè)str的兩端都加上了優(yōu)先級(jí)最低的特殊符號(hào)

InitStack(s);//s為運(yùn)算符棧

while(*p)

if(*p是字母))*q++=*p;〃直接輸出

else

(

c=gettop(s);

if(*p優(yōu)先級(jí)比c高)push(s,*p);

else

(

while(gettop(s)優(yōu)先級(jí)不比*p低)

(

pop(s,c);*(q++)=c;

}//while

push(s,*p);〃運(yùn)算符在棧內(nèi)遵循越往棧頂優(yōu)先級(jí)越高的原則

}//else

}//else

P++;

}//while

}//NiBoLan〃參見編譯原理教材

3.22

intGetValue_NiBoLan(char*str)〃對(duì)逆波蘭式求值

(

p=str;InitStack(s);//s為操作數(shù)棧

while(*p)

(

if(*p是數(shù))push(s,*p);

else

(

pop(s,a);pop(s,b);

r=compute(b,*p,a);//假設(shè)compute為執(zhí)行雙目運(yùn)算的過程

push(s,r);

}//else

P++;

}//while

pop(s,r);retumr;

}//GetValue_NiBoLan

3.23

StatusNiBoLan_to_BoLan(char*str,stringtype&new)〃把逆波蘭表達(dá)式str轉(zhuǎn)換為波蘭式new

(

p=str;Initstack(s);//s的元素為stringtype類型

while(*p)

(

if(*p為字母)push(s,*p);

else

(

if(StackEmpty(s))returnERROR;

pop(s,a);

if(StackEmpty(s))returnERROR;

pop(s,b);

c=link(link(*p,b),a);

push(s,c);

}//else

P++;

}//while

pop(s,new);

if(!StackEmpty(s))returnERROR;

returnOK;

}//NiBoLan_to_BoLan

分析:基本思想見書后注釋.本題中暫不考慮串的具體操作的實(shí)現(xiàn),而將其看作一種抽象數(shù)據(jù)類

型stringtype,對(duì)其可以進(jìn)行連接操作:c=link(a,b).

3.24

Statusg(intm,intn,int&s)〃求遞歸函數(shù)g的值s

if(m==0&&n>=0)s=0;

elseif(m>0&&n>=0)s=n+g(m-l,2*n);

elsereturnERROR;

returnOK;

}//g

3.25

StatusF_recursive(intn,int&s)〃遞歸算法

(

if(n<0)returnERROR;

if(n==0)s=n+l;

else

(

F_recurve(n/2,r);

s=n*r;

)

returnOK;

}//F_recursive

StatusF_nonrecursive(intn,ints)〃非遞歸算法

(

if(n<0)returnERROR;

if(n==O)s=n+l;

else

(

InitStack(s);//s的元素類型為struct{inta;intb;}

while(n!=0)

(

a=n;b=n/2;

push(s,{a,b});

n=b;

}//while

s=l;

while(!StackEmpty(s))

pop(s,t);

s*=t.a;

}//while

returnOK;

}//F_nonrecursive

3.26

floatSqrt_recursive(floatA,floatp,floate)〃求平方根的遞歸算法

(

if(abs(pA2-A)<=e)returnp;

elsereturnsqrt_recurve(A,(p+A/p)/2,e);

}//Sqrt_recurve

floatSqrt_nonrecursive(floatA,floatp,floate)〃求平方根的非遞歸算法

(

while(abs(pA2-A)>=e)

p=(p+A/p)/2;

returnp;

}//Sqrt_nonrecursive

3.27

這一題的所有算法以及棧的變化過程請(qǐng)參見《數(shù)據(jù)結(jié)構(gòu)(pascal版)》,作者不再詳細(xì)寫出.

3.28

voidInitCiQueue(CiQueue&Q)〃初始化循環(huán)鏈表表示的隊(duì)列Q

(

Q=(CiLNode*)malloc(sizeof(CiLNode));

Q->next=Q;

}//InitCiQueue

voidEnCiQueue(CiQueue&Q,intx)〃把元素x插入循環(huán)鏈表表示的隊(duì)列Q,Q指向隊(duì)尾元

素,Q.>next指向頭結(jié)點(diǎn),Q.>next->next指向隊(duì)頭元素

(

p=(CiLNode*)malloc(sizeof(CiLNode));

p->data=x;

p->next二Q->next;〃直接把p加在Q的后面

Q->next=p;

Q=p;〃修改尾指針

StatusDeCiQueue(CiQueue&Q,intx)〃從循環(huán)鏈表表示的隊(duì)列Q頭部刪除元素x

(

if(Q==Q>>next)returnINFEASIBLE;〃隊(duì)列已空

p=Q->next->next;

x=p->data;

Q->next->next=p->next;

free(p);

returnOK;

}//DeCiQueue

3.29

StatusEnCyQueue(CyQueue&Q,intx)〃帶tag域的循環(huán)隊(duì)列入隊(duì)算法

(

if(Q.front==Q.rear&&Q.tag==l)//tag域的值為0表示“空表示“滿”

returnOVERFLOW;

Q.base[Q.rear]=x;

Q.rear=(Q.rear+l)%MAXSIZE;

if(Q.front==Q.rear)Q.tag=l;〃隊(duì)列滿

}//EnCyQueue

StatusDeCyQueue(CyQueue&Q,int&x)〃帶tag域的循環(huán)隊(duì)列出隊(duì)算法

(

if(Q.front==Q.rear&&Q.tag==0)returnINFEASIBLE;

Q.front=(Q.front+l)%MAXSIZE;

x=Q.base[Q.front];

if(Q.front==Q.rear)Q.tag=l;〃隊(duì)列空

returnOK;

}//DeCyQueue

分析:當(dāng)循環(huán)隊(duì)列容量較小而隊(duì)列中每個(gè)元素占的空間較多時(shí),此種表示方法可以節(jié)約較多的

存儲(chǔ)空間,較有價(jià)值.

3.30

StatusEnCyQueue(CyQueue&Q,intx)〃帶length域的循環(huán)隊(duì)列入隊(duì)算法

if(Q.length==MAXSIZE)returnOVERFLOW;

Q.rear=(Q.rear+l)%MAXSIZE;

Q.basefQ.rear]=x;

Q.length++;

returnOK;

}//EnCyQueue

StatusDeCyQueue(CyQueue&Q,int&x)〃帶length域的循環(huán)隊(duì)列出隊(duì)算法

(

if(Q.length==O)returnINFEASIBLE;

head=(Q.rear-Q.length+1)%MAXSIZE;〃詳見書后注釋

x=Q.base[head];

Q.length—;

}//DeCyQueue

3.31

intPalindrome_Test()〃判別輸入的字符串是否回文序列,是則返回1,否則返回0

{

InitStack(S);InitQueue(Q);

while((c=getchar())!=@)

(

Push(S,c);EnQueue(Q,c);〃同時(shí)使用棧和隊(duì)列兩種結(jié)構(gòu)

)

while(!StackEmpty(S))

(

Pop(S,a);DeQueue(Q,b));

if(a!=b)returnERROR;

}

returnOK;

}//Palindrome_Test

3.32

voidGetFib_CyQueue(intk,intn)〃求k階斐波那契序列的前n+1項(xiàng)

(

InitCyQueue(Q);〃其MAXSIZE設(shè)置為k

for(i=0;i<k-l;i++)Q.base[i]=0;

Q.base[k-l]=l;〃給前k項(xiàng)賦初值

for(i=0;i<k;i++)printf(H%d",Q.base[i]);

for(i=k;i<=n;i++)

m=i%k;sum=O;

for(j=0;j<k;j++)sum4-=Q.base[(m-4)%k];

Q.base[m]=sum;〃求第i項(xiàng)的值存入隊(duì)列中并取代已無用的第一項(xiàng)

printf(n%d",sum);

}

}//GetFib_CyQueue

3.33

StatusEnDQueue(DQueue&Q,intx)〃輸出受限的雙端隊(duì)列的入隊(duì)操作

(

if((Q.rear+l)%MAXSIZE==Q.front)returnOVERFLOW;〃隊(duì)歹I」?jié)M

avr=(Q.basefQ.rear-1]+Q.basefQ.front])/2;

if(x>=avr)〃根據(jù)x的值決定插入在隊(duì)頭還是隊(duì)尾

(

Q.base[Q.rear]=x;

Q.rear=(Q.rear+l)%MAXSIZE;

)〃插入在隊(duì)尾

else

(

Q.front=(Q.front-1)%MAXSIZE;

Q上ase[Q.front]=x;

)〃插入在隊(duì)頭

returnOK;

}//EnDQueue

StatusDeDQueue(DQueue&Q,int&x)〃輸出受限的雙端隊(duì)列的出隊(duì)操作

(

if(Q.front==Q.rear)returnINFEASIBLE;〃隊(duì)列空

x=Q.base[Q.front];

Q.front=(Q.front+l)%MAXSIZE;

returnOK;

}//DeDQueue

3.34

voidTrain_Rearrange(char*train)〃這里用字符串train表示火車,'P表示硬座,H表示硬臥;S'表示

軟臥,最終按PSH的順序排列

{

r=train;

InitDQueue(Q);

while(*r)

(

if(*r=='P')

(

printf("E");

printf("D");〃實(shí)際上等于不入隊(duì)列,直接輸出P車廂

)

elseif(*r==S)

(

printf("E");

EnDQueue(Q,*r,O);//0表示把S車廂從頭端入隊(duì)列

)

else

(

printf("A");

EnDQueue(Q,*r,l);〃1表示把H車廂從尾端入隊(duì)列

)

}//while

while(!DQueueEmpty(Q))

(

printf("D");

DeDQueue(Q);

"/while〃從頭端出隊(duì)列的車廂必然是先S后H的順序

}//Train_Rearrange

第四章串

4.10

voidString_Reverse(Stringtypes,Stringtype&r)〃求s的逆串r

{

StrAssign(rJ);〃初始化r為空串

for(i=Strlen(s);i;i—)

(

StrAssign(c,SubString(s,i,l));

StrAssign(r,Concat(r,c));//把s的字符從后往前添加到r中

)

}//String_Reverse

4.11

voidString_Subtract(Stringtypes,Stringtypet,Stringtype&r)〃求所有包含在串s中而t中沒有的字

符構(gòu)成的新串r

{

StrAssign(r,");

for(i=1;i<=Strlen(s);i++)

(

StrAssign(c,SubString(s,i,l));

for(j=l;j<i&&StrCompare(c,Substring。,j,1));j++);//判斷s的當(dāng)前字符c是否第一-次出現(xiàn)

if(i==j)

(

for(k=1;k<=Strlen(t)&&StrCompare(c,SubString(t,k,1));k++);〃判斷當(dāng)前字符是否包含在t

if(k>Strlen(t))StrAssign(r,Concat(r,c));

)

}//for

}//String_Subtract

4.12

intReplace(Stringtype&S,StringtypeT,StringtypeV);〃將串S中所有子串T替換為V,并返回置換

次數(shù)

for(n=0,i=l;i<=Strlen(S)-Strlen(T)+l;i++)〃注意i的取值范圍

if(!StrCompare(SubString(S,i,StrIen(T)),T))〃找到了與T匹配的子串

{〃分別把T的前面和后面部分保存為head和tail

StrAssign(head,SubString(S,1,i-1));

StrAssign(tail,SubString(S,i+Strlen(T),Strlen(S)-i-Strlen(T)+l));

StrAssign(S,Concat(head,V));

StrAssign(S,Concat(S,tail));〃把head,V,tail連接為新串

i+=Strlen(V);〃當(dāng)前指針跳至I」插入串以后

n++;

}//if

returnn;

}//Replace

分析:i+=Strlen(V);這一句是必需的,也是容易忽略的.如省掉這一句,則在某些情況下,會(huì)引起不

希望的后果,雖然在大多數(shù)情況下沒有影響.請(qǐng)思考:設(shè)S^place;T士ace;V士face:則省掉

i+=Strlen(V)運(yùn)行時(shí)會(huì)出現(xiàn)什么結(jié)果?

4.13

intDelete_SubString(Stringtype&s,Stringtypet)〃從串s中刪除所有與t相同的子串,并返回刪除

次數(shù)

(

for(n=0,i=l;i<=Strlen(s)-Strlen(t)+l;i++)

if(!StrCompare(SubString(s,i,Strlen(t)),t))

(

StrAssign(head,SubString(S,1,i-1));

StrAssign(tail,SubString(S,i+Strlen(t),Strlen(s)-i-Strlen(t)+l));

StrAssign(S,Concat(head,tail));〃把head,tail連接為新串

n++;

}//if

returnn,

}//Delete_SubString

4.14

StatusNiBoLan_to_BoLan(Stringtypestr,Stringtype&new)〃把前綴表達(dá)式str轉(zhuǎn)換為后綴式new

Initstack(s);//s的元素為Stringtype類型

for(i=l;i<=Strlen(str);i++)

r=SubString(str,i,l);

if(r為字母)push(s,r);

else

(

if(StackEmpty(s))returnERROR;

pop(s,a);

if(StackEmpty(s))returnERROR;

pop(s,b);

StrAssign(t,Concat(r,b));

StrAssign(c,Concat(t,a));〃把算符r,子前綴表達(dá)式a,b連接為新子前綴表達(dá)式c

push(s,c);

}

}//for

pop(s,new);

if(!StackEmpty(s))returnERROR;

returnOK;

}//NiBoLan_to_BoLan

分析:基本思想見書后注釋3.23.請(qǐng)讀者用此程序取代作者早些時(shí)候?qū)?.23題給出的程序.

4.15

voidStrAssign(Stringtype&T,charchars&#;)〃用字符數(shù)組chars給串T賦值,Stringtype的定義見

課本

(

for(i=0,T[0]=0;chars[i];T[0]++,i++)T[i+l]=chars[i];

}//StrAssign

4.16

charStrCompare(Stringtypes,Stringtypet)〃串的比較,s>t時(shí)返回正數(shù),s=t時(shí)返回O,s<t時(shí)返回負(fù)

數(shù)

(

for(i=l;i<=s[0]&&i<=t[0]&&s[i]=t[i];i++);

if(i>s[O]&&i>t[O])return0;

elseif(i>s[O])return-t[i];

elseif(i>t[O])returns[i];

elsereturns[i]-t[i];

}//StrCompare

4.17

intString_Replace(Stringtype&S,StringtypeT,StringtypeV);〃將串S中所有子串T替換為V,并返

回置換次數(shù)

(

for(n=0,i=1;i<=S[O]-T[O]+1;i++)

(

for(j=i,k=l;T[k]&&S[j]==T[k];j++,k++);

if(k>T⑼)〃找到了與T匹配的子串:分三種情況處理

(

if(T[O]==V[O])

for(l=1;1<=T[O];1++)〃新子串長度與原子串相同時(shí):直接替換

S[i+l-l]=V[l];

elseifCHO]<V[O])//新子串長度大于原子串時(shí):先將后部右移

(

for(l=S[0];l>=i+T[0];l-)

S[1+V[O]-T[O]]=S[1];

for(l=l;l<=V[0];l++)

S[i+l-l]=V[l];

)

else〃新子串長度小于原子串時(shí):先將后部左移

(

for(l=i+V[0];l<=S[0]+V[0]-T[0];l++)

S[l]=S[l-VrO]+T[O]];

for(l=l;l<=V[0];l++)

S[i+l-l]=V[l];

)

S[O]=S[O]-T[O]+V[O];

i+=V[O];n++;

}//if

}//for

returnn;

}//String_Replace

4.18

typedefstruct{

charch;

intnum;

}mytype;

voidStrAnalyze(StringtypeS)〃統(tǒng)計(jì)串S中字符的種類和個(gè)數(shù)

(

mytypeT[MAXSIZE];〃用結(jié)構(gòu)數(shù)組T存儲(chǔ)統(tǒng)計(jì)結(jié)果

for(i=l;i<=SrO];i++)

(

c=S[i];j=O;

while(T[j].ch&&TU].ch!=c)j++;//查找當(dāng)前字符c是否已記錄過

if(T[j].ch)T[j].num++;

elseT[j]={c,l};

}//for

for(j=0;T[j].ch;j++)

printf("%c:%d\n",T[j].ch,T[j].num);

}//StrAnalyze

4.19

voidSubtract_String(Stringtypes,Stringtypet,Stringtype&r)〃求所有包含在串s中而t中沒有的字

符構(gòu)成的新串r

(

r[0]=0;

for(i=l;i<=s[0];i++)

(

c=s[i];

forO=l;j<i&&s[j]!=c;j++);//判斷s的當(dāng)前字符c是否第一次出現(xiàn)

if(i==j)

(

for(k=l;k<=t⑼&&t[k]!=c;k++);//判斷當(dāng)前字符是否包含在t中

if(k>t[O])r[++r[0]]=c;

}//for

}//Subtract_String

4.20

intSubString_Delete(Stringtype&s,Stringtypet)〃從串s中刪除所有與t相同的子串,并返回刪除

次數(shù)

(

for(n=0,i=1;i<=s[0]-t[0]+1;i++)

(

for(j=l;j<=t[0]&&s[i+j-l]==t[i];j++);

〃找到了與t匹配的子串

(

for(k=i;k<=s[0]-t[0];k++)s[k]=s[k+t⑼];〃左移刪除

s[0]-=t[0];n++;

)

}//for

returnn;

}//Delete_SubString

4.21

typedefstruct{

charch;

LStrNode*next;

}LStrNode,*LString;〃鏈串結(jié)構(gòu)

voidStringAssign(LString&s,LString?!ò汛畉賦值給串s

(

s=malloc(sizeof(LStrNode));

for(q=s,p=t->next;p;p=p->next)

(

r=(LStrNode*)malloc(sizeof(LStrNode));

r->ch=p->ch;

q->next=r;q=r;

q

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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)論