数据结构作业C语言版习题.docx
《数据结构作业C语言版习题.docx》由会员分享,可在线阅读,更多相关《数据结构作业C语言版习题.docx(17页珍藏版)》请在冰豆网上搜索。
数据结构作业C语言版习题
数据结构作业(C语言版)习题
1.4,试仿照三元组的抽象数据类型分别写出抽象数据类型复数和有理数的定义(有理数是其分子、分母均为自然数且分母不为零的分数)。
复数:
ADTTriplet
{
D={r,i|r,i为实数}
R={}
InitComplex(&C,re,im)
}ADTComplex
有理数:
ADTTriplet
{
D={c1,c2,c3|c1,c2,c3∈Z,c3≠0};
R={};
C3=c1/c2;
}ADTTriplet
1.9假设n为2的乘幂,并且n>2,试求下列算法的时间复杂度及变量count的值(以n的函数形式表示)。
intTime(intn){
count=0;x=2;
while(x<n/2){
x*=2;count++;
}
return(count)
}//Time
解:
count=
1.16试写一算法,自大至小依次输出顺序读入的三个整数X,Y和Z的值。
Voidbubble-sort(inta[X,Y,Z],inti){
for(i=n-1,change=TRUE;i≥&&change;--i){
change=FALSE;
for(j=0;j
if(a[j]>a[j+1]){a[j+1]←→a[j]change=TRUE;}
}
}//bubble-sort
解:
intmax3(intx,inty,intz)
{
if(x>y)
if(x>z)returnx;
elsereturnz;
else
if(y>z)returny;
elsereturnz;
}
2.1描述以下三个概念的区别:
头指针,头结点,首元结点(第一个元素结点)。
头结点:
在单链表的第一个结点之前附设一个结点,即称之为头结点
头指针:
链表中第一个结点的存储位置即称之为头指针
首元结点:
首元结点是指链表中存储线性表中第一个数据元素a1的结点
(1)在顺序表中插入或删除一个元素,需要平均移动表中一半元素,具体移动的元素个数与表长和该元素在表中的位置有关。
(2)顺序表中逻辑上相邻的元素的物理位置必定相邻。
单链表中逻辑上相邻的元素的物理位置不一定相邻。
(3)在单链表中,除了首元结点外,任一结点的存储位置由其直接前驱结点的链域的性指示。
(40在单链表中设置头结点的作用是插入或删除首元素不必进行特殊处理。
2.4对以下单链表分别执行下列各程序段,并画出结果示意图。
2
5
7
3
8
6
4
(1)Q=P->next;
(2)L=P->next;
(3)R->data=P->data;
(4)R->data=P->next->data;
(5)P->next->next->next->data=P->data;
(6)T=P;
While(T!
=NULL){T->data=T->data*2;T=t->next;}
(7)T=P
While(T->next!
=NULL){T->data=T->data*2;T=T->next;}
2.5画出执行下列各行语句后各指针及链表的示意图。
L=(LinkList)malloc(sizeof(LNode));P=L
For(i=1;i<=4;i++){
p->next=(LinkList)malloc(sizeof(LNode));
P=P->next;p->data=i*2-1;
}
P->next=NULL;
for(i=4;i>=1;i--;)Ins-LinkList(L,i+1,i*2);
for(i=1;i<=3;i++)Del-LinkList(L,i);
解:
2.6已知L是无表头结点的单链表,且P结点既不是首元结点,也不是尾元结点,试从下列提供的答案中选择合适的语句序列。
A.在P结点后S结点的语句序列是:
(4)
(1)
B.在P结点前S结点的语句序列是:
(7)(11)(8)(4)
(1)
C.在表首S结点的语句序列是:
(5)(12)
D.在表尾S结点的语句序列是:
(9)
(1)(6)
(1)P->next=S;
(2)P->next=P->next->next;
(3)P->next=S->next;
(4)S->next=P->next;
(5)S->next==L;
(6)S->next=NULL;
(7)Q=P
(8)while(P->next!
=Q)P=P->next;
(9)while(P->next!
=NULL)P=P->next;
(10)P=Q
(11)P=L;
(12)L=S;
(13)L=P;
a.(11)(3)(14)
b.(10)(12)(8)(11)(3)(14)
c.(10)(12)(7)(3)(14)
d.(12)(11)(3)(14)
e(9)(11)(3)(14)
a.(7)(12)(6)(3)
b.(8)(13)(5)(4)
c.(15)
(1)(11)(18)
d.(16)
(2)(10)(18)
e.(9)(14)(17)
StatusDeleteK(SqList&a,inti,intk)
{
intj;
if(i<0||i>a.length-1||k<0||k>a.length-i)returnINFEASIBLE;
for(j=0;j<=k;j++)
a.elem[j+i]=a.elem[j+i+k];
a.length=a.length-k;
returnOK;
}
2.13.解:
intLocateElem_L(LinkList&L,ElemTypex)
{
inti=0;
LinkListp=L;
while(p&&p->data!
=x)
{
p=p->next;
i++;
}
if(!
p)return0;
elsereturni;
}
2.14.解:
intListLength_L(LinkList&L)
{
inti=0;
LinkListp=L;
if(p)p=p-next;
while(p){
p=p->next;
i++;
}
returni;
}
3.1.解:
(1)123231321213132
(2)可以得到135426的出站序列,但不能得到435612的出站序列。
因为4356出站说明12已经在栈中,1不可能先于2出栈。
3.3.解:
stack
3.4.解:
(1)栈中的数据元素逆置
(2)如果栈中存在元素e,将其从栈中清除
3.12.解:
char
3.13解:
队列逆置
StatusInsert_SqList(SqList&va,intx)//把x插入递增有序表va中
{
if(va.length+1>va.listsize)returnERROR;
va.length++;
for(i=va.length-1;va.elem[i]>x&&i>=0;i--)
va.elem[i+1]=va.elem[i];
va.elem[i+1]=x;
returnOK;
}//Insert_SqList
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后面形成链表hc
{
hc=ha;p=ha;
while(p->next)p=p->next;
p->next=hb->next;
free(hb);
}//ListConcat
2.22
voidLinkList_reverse(Linklist&L)//利用头插法实现链表的就地逆置;为简化算法,假设表长大于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的元素逐个插入新表表头
}
q->next=p;s->next=q;L->next=s;
}//LinkList_reverse
分析:
本算法的思想是,利用头插法,逐个地把L的当前元素q插入新的链表头部,p为新表的首元结点.
补充题:
(是题2.14的扩充)
intnumber(LinkedNodehead)//计算带头结点的单循环链表的结点个数
{
p=head;
i=0;
while(p->next!
=head)
{
i++;
p=p->next;
}
returni;
}
3.16
voidTrain_arrange(char*train)//这里用字符串train表示火车,'H'表示硬席,'S'表示软席
{
p=train;q=train;
InitStack(s);
while(*p)
{
if(*p=='H')push(s,*p);//把'H'存入栈中
else*(q++)=*p;//把'S'调到前部
p++;
}
while(!
StackEmpty(s))
{
pop(s,c);
*(q++)=c;//把'H'接在后部
}
}//Train_arrange
3.17
intIsReverse()//判断输入的字符串中'&'前和'&'后部分是否为逆串,是则返回1,否则返回0
{
InitStack(s);
while((e=getchar())!
='&')
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)//判别表达式中小括号是否匹配
{
count=0;
for(p=str;*p;p++)
{
if(*p=='(')count++;
elseif(*p==')')count--;
if(count<0)returnERROR;
}
if(count)returnERROR;//注意括号不匹配的两种情况
returnOK;
}//Bracket_Test
3.19
StatusAllBrackets_Test(char*str)//判别表达式中三种括号是否匹配
{
InitStack(s);
for(p=str;*p;p++)
{
if(*p=='('||*p=='['||*p=='{')push(s,*p);
elseif(*p==')'||*p==']'||*p=='}')
{
if(StackEmpty(s))returnERROR;
pop(s,c);
if(*p==')'&&c!
='(')returnERROR;
if(*p==']'&&c!
='[')returnERROR;
if(*p=='}'&&c!
='{')returnERROR;//必须与当前栈顶括号匹配
}
}//for
if(!
StackEmpty(s))returnERROR;
returnOK;
}//AllBrackets_Test
3.24
Statusg(intm,intn,int&s)//求递归函数g的值s
{
if(m==0&&n>=0)s=0;
elseif(m>0&&n>=0)s=n+g(m-1,2*n);
elsereturnERROR;
returnOK;
}//g
3.25
StatusF_recursive(intn,int&s)//递归算法
{
if(n<0)returnERROR;
if(n==0)s=n+1;
else
{
F_recurve(n/2,r);
s=n*r;
}
returnOK;
}//F_recursive
3.31
intPalindrome_Test()//判别输入的字符串是否回文序列,是则返回1,否则返回0
{
InitStack(S);InitQueue(Q);
while((c=getchar()!
='@')
{
Push(S,c);EnQueue(Q,c);//同时使用栈和队列两种结构
}
while(!
StackEmpty(S))
{
Pop(S,a);DeQueue(Q,b));
if(a!
=b)returnERROR;
}
returnOK;
}//Palindrome_Test
6.36
intBitree_Sim(BitreeB1,BitreeB2)//判断两棵树是否相似的递归算法
{
if(!
B1&&!
B2)return1;
elseif(B1&&B2&&Bitree_Sim(B1->lchild,B2->lchild)&&Bitree_Sim(B1->rchild,B2->rchild))
return1;
elsereturn0;
}//Bitree_Sim
6.41
intc,k;//这里把k和计数器c作为全局变量处理
voidGet_PreSeq(BitreeT)//求先序序列为k的结点的值
{
if(T)
{
c++;//每访问一个子树的根都会使前序序号计数器加1
if(c==k)
{
printf("Valueis%d\n",T->data);
exit
(1);
}
else
{
Get_PreSeq(T->lchild);//在左子树中查找
Get_PreSeq(T->rchild);//在右子树中查找
}
}//if
}//Get_PreSeq
6.42
intLeafCount_BiTree(BitreeT)//求二叉树中叶子结点的数目
{
if(!
T)return0;//空树没有叶子
elseif(!
T->lchild&&!
T->rchild)return1;//叶子结点
elsereturnLeaf_Count(T->lchild)+Leaf_Count(T->rchild);//左子树的叶子数加上右子树的叶子数
}//LeafCount_BiTree
6.43
voidBitree_Revolute(BitreeT)//交换所有结点的左右子树
{
T->lchild<->T->rchild;//交换左右子树
if(T->lchild)Bitree_Revolute(T->lchild);
if(T->rchild)Bitree_Revolute(T->rchild);//左右子树再分别交换各自的左右子树
}//Bitree_Revolute
6.44
intGet_Sub_Depth(BitreeT,intx)//求二叉树中以值为x的结点为根的子树深度
{
if(T->data==x)
{
printf("%d\n",Get_Depth(T));//找到了值为x的结点,求其深度
exit1;
}
else
{
if(T->lchild)Get_Sub_Depth(T->lchild,x);
if(T->rchild)Get_Sub_Depth(T->rchild,x);//在左右子树中继续寻找
}
}//Get_Sub_Depth
intGet_Depth(BitreeT)//求子树深度的递归算法
{
if(!
T)return0;
else
{
m=Get_Depth(T->lchild);
n=Get_Depth(T->rchild);
return(m>n?
m:
n)+1;
}
}//Get_Depth
6.45
voidDel_Sub_x(BitreeT,intx)//删除所有以元素x为根的子树
{
if(T->data==x)Del_Sub(T);//删除该子树
else
{
if(T->lchild)Del_Sub_x(T->lchild,x);
if(T->rchild)Del_Sub_x(T->rchild,x);//在左右子树中继续查找
}//else
}//Del_Sub_x
voidDel_Sub(BitreeT)//删除子树T
{
if(T->lchild)Del_Sub(T->lchild);
if(T->rchild)Del_Sub(T->rchild);
free(T);
}//Del_Sub
6.47
voidLayerOrder(BitreeT)//层序遍历二叉树
{
InitQueue(Q);//建立工作队列
EnQueue(Q,T);
while(!
QueueEmpty(Q))
{
DeQueue(Q,p);
visit(p);
if(p->lchild)EnQueue(Q,p->lchild);
if(p->rchild)EnQueue(Q,p->rchild);
}
}//LayerOrder
9.26
intSearch_Bin_Recursive(SSTableST,intkey,intlow,inthigh)//折半查找的递归算法
{
if(low>high)return0;//查找不到时返回0
mid=(low+high)/2;
if(ST.elem[mid].key==key)returnmid;
elseif(ST.elem[mid].key>key)
returnSearch_Bin_Recursive(ST,key,low,mid-1);
elsereturnSearch_Bin_Recursive(ST,key,mid+1,high);
}
}//Search_Bin_Recursive
10.23
voidInsert_Sort1(SqList&L)//监视哨设在高下标端的插入排序算法
{
k=L.length;
for(i=k-1;i;--i)//从后向前逐个插入排序
if(L.r[i].key>L.r[i+1].key)
{
L.r[k+1].key=L.r[i].key;//监视哨
for(j=i+1;L.r[j].key>L.r[i].key;++j)
L.r[j-1].key=L.r[j].key;//前移
L.r[j-1].key=L.r[k+1].key;//插入
}
}//Insert_Sort1
10.27
voidBubble_Sort2(inta[],intn)//相邻两趟是反方向起泡的冒泡排序算法
{
low=0;high=n-1;//冒泡的上下界
change=1;
while(low{
change=0;
for(i=low;iif(a[i]>a[i+1])
{
a[i]<->a[i+1];
change=1;
}
high--;//修改上界
for(i=high;i>low;i--)//从下向上起泡
if(a[i]{
a[i]<->a[i-1];
change=1;
}
low++;//修改下界
}//while
}//Bubble_Sort2
10.29
voidOE_Sort(inta[],intn)//奇偶交换排序的算法
{
change=1;
while(change)
{
change=0;
for(i=1;iif(a[i]>a[i+1])
{
a[i]<->a[i+1];
change=1;
}
for(i=0;iif(a[i]>a[i+1])
{
a[i]<->a[i+1];
change=1;
}
}//while
}//OE_Sort
分析:
本算法的结束条件是连续两趟比较无交换发生