scanf(“%f”,&a[i]);/*执行次数:
n次*/
p=a[0];
for(i=1;i<=n;i++)
{p=p+a[i]*x;/*执行次数:
n次*/
x=x*x;}
printf(“%f”,p);
}
算法的时间复杂度:
T(n)=O(n)
通过参数表中的参数显式传递
floatPolyValue(floata[],floatx,intn)
{
floatp,s;
inti;
p=x;
s=a[0];
for(i=1;i<=n;i++)
{s=s+a[i]*p;/*执行次数:
n次*/
p=p*x;}
return(p);
}
算法的时间复杂度:
T(n)=O(n)
[techer's]
#include
#defineMAXSIZE10
floatpnx(floata[],floatx,intn)
{intj;
floatsum=0.0;
for(j=n;j>0;j--)/*a[0]=a0,[a1]=a1,...*/
sum=(sum+a[j])*x;
sum=sum+a[0];
return(sum);
}
voidmain()
{
intn,i;
floata[MAXSIZE],x,result;
printf("Inputthevalueofx:
\n");
scanf("%f",&x);
printf("\n");
printf("InputThen:
\n");
scanf("%d",&n);
printf("\n");
printf("Inputa0,a1,...an:
");
for(i=0;i<=n;i++)scanf("%f",&a[i]);
printf("\n");
result=pnx(a,x,n);
printf("Theresultis:
%f\n",result);
}
2.4已知线性表L递增有序。
试写一算法,将X插入到L的适当位置上,以保持线性表L的有序性。
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
[teacher's]
intInsList_Sort(SeqList*L,elemtypee)
{
inti;
if(L->last>=MAXSIZE-1){
printf("表已满无法插入!
");
return(0);
}
i=L->last;
while((i>=0)&&(eelem[i]))/*寻找插入位置并移动元素*/
{L->elem[i+1]=L->elem[i];
i--;
}
L->elem[i+1]=e;/*即使L为空,处理也相同*/
L->last++;
return
(1);
}
2.5写一算法,从顺序表中删除自第i个元素开始的k个元素。
[提示]:
注意检查i和k的合法性。
(集体搬迁,“新房”、“旧房”)
<方法1>以待移动元素下标m(“旧房号”)为中心,
计算应移入位置(“新房号”):
for(m=i-1+k;m<=L->last;m++)
L->elem[m-k]=L->elem[m];
<方法2>同时以待移动元素下标m和应移入位置j为中心:
<方法2>以应移入位置j为中心,计算待移动元素下标:
[teacher's]
intDelList_k(SeqList*L,inti,intk)
{/*假定从i往后的元素个数不足k个时,仅删除其后的所有元素*/
intcount,j;
if((i>L->last+1)||(k<1))return(0);
count=L->last-i+1;/*计算i后的元素个数*/
j=i+k-1;
while(j<=L->last)/*将i+k位置以后的元素向前移动*/
{L->elem[j-k]=L->elem[j];
j++;/*原算法中的count--;去掉*/
}
if(count>=k)L->last=L->last-k;/*改变指向尾元的位置值*/
elseL->last=L->last-count;/*被删元素数少于k个时*/
return
(1);
}
2.6已知线性表中的元素(整数)以值递增有序排列,并以单链表作存储结构。
试写一高效算法,删除表中所有大于mink且小于maxk的元素(若表中存在这样的元素),分析你的算法的时间复杂度(注意:
mink和maxk是给定的两个参变量,它们的值为任意的整数)。
StatusDelete_Between(Linklist&L,intmink,intmaxk)//删除元素递增排列的链表L中值大于mink且小于maxk的所有元素
{
p=L;
while(p->next->data<=mink)p=p->next;//p是最后一个不大于mink的元素
if(p->next) //如果还有比mink更大的元素
{
q=p->next;
while(q->datanext;//q是第一个不小于maxk的元素
p->next=q;
}
}//Delete_Between
2.7试分别以不同的存储结构实现线性表的就地逆置算法,即在原表的存储空间将线性表(a1,a2...,an)逆置为(an,an-1,...,a1)。
(1)以一维数组作存储结构,设线性表存于a(1:
arrsize)的前elenum个分量中。
(2)以单链表作存储结构。
[方法1]:
在原头结点后重新头插一遍
[方法2]:
可设三个同步移动的指针p,q,r,将q的后继r改为p
[teacher's]
#include//2.7.1
#defineMAXSIZE10
voidcreatedata(intx[],intn)
{
inti;
if(n>=MAXSIZE){printf("ERROR!
");
exit();
}
for(i=0;i}
voidreverse1(intx[],intn)
{inttmp,i,k;
if(n>=MAXSIZE){printf("OverFlow!
");
exit();
}
k=0;
for(i=n-1;i>=n/2;i--)
{tmp=x[i];
x[i]=x[k];
x[k]=tmp;
k++;
}
}
voiddisparray(intx[],intn)
{
inti;
if(n>=MAXSIZE){printf("ERROR!
");
exit();
}
for(i=0;i}
voidmain()
{inta[MAXSIZE];
createdata(a,8);
reverse1(a,8);
disparray(a,8);
}
#include//2.7.2
typedefstructnode
{intx;
structnode*next;
}snode,*Linklist;
Linklistcreate()
{snode*head,*rear,*s;
inty;
head=(Linklist)malloc(sizeof(snode));
rear=head;
scanf("%d",&y);
while(y!
=-1)
{s=(Linklist)malloc(sizeof(snode));
s->x=y;
rear->next=s;
rear=s;
scanf("%d",&y);
}
rear->next=NULL;
return(head);
}
Linklistreverse2(snode*head)
{Linklistp,q;
p=head->next;
head->next=NULL;
while(p)
{q=p;/*采用头插法,q指向待插节点,p指向下一个*/
p=p->next;
q->next=head->next;
head->next=q;
}
return(head);
}
main()
{Linklisth,p;
h=create();
p=h->next;
while(p)
{printf("%5d",p->x);
p=p->next;
}
h=reverse(h);
printf("\n");
p=h->next;
while(p)
{printf("%5d",p->x);
p=p->next;
}
}
2.8假设两个按元素值递增有序排列的线性表A和B,均以单链表作为存储结构,请编写算法,将A表和B表归并成一个按元素值递减有序的排列的线性表C,并要求利用原表(即A表和B表的)结点空间存放表C.
[teacher's]
/*ch2_8合并并逆置链表*/
#include
typedefstructnode
{intx;
structnode*next;
}snode,*Linklist;
Linklistcreate()
{snode*head,*rear,*s;
inty;
head=(Linklist)malloc(sizeof(snode));
rear=head;
scanf("%d",&y);
while(y!
=-1)
{s=(Linklist)malloc(sizeof(snode));
s->x=y;
rear->next=s;
rear=s;
scanf("%d",&y);
}
rear->next=NULL;
return(head);
}
Linklistmerge(snode*head1,snode*head2)
{Linklisthead,p,q,s;
p=head1->next;/*指向A的首元节点*/
q=head2->next;/*指向B的首元节点*/
head=head1;/*以链表A的头节点做C的头节点*/
head->next=NULL;
free(head2);/*释放B的头节点*/
while(p!
=NULL&&q!
=NULL)/*用头插法挑选元素插入*/
{if(p->xx)
{s=p;p=p->next;}
else
{s=q;q=q->next;}
s->next=head->next;head->next=s;
}
if(p==NULL)p=q;
while(p)
{s=p;p=p->next;s->next=head->next;head->next=s;}
return(head);
}
main()
{Linklisth,h1,h2,p,q;
h1=create();
h2=create();
printf("\n******************************\n");
p=h1->next;
while(p)/*显示链表A的数据*/
{printf("%5d",p->x);
p=p->next;
}
printf("\n******************************\n");
q=h2->next;
while(q)/*显示链表B的数据*/
{printf("%5d",q->x);
q=q->next;
}
h=merge(h1,h2);
p=h->next;
printf("\n******************************\n");
while(p)/*显示链表C的数据*/
{printf("%5d",p->x);
p=p->next;
}
}
2.9假设有一个循环链表的长度大于1,且表中既无头结点也无头指针。
已知s为指向链表某个结点的指针,试编写算法在链表中删除指针s所指结点的前趋结点。
[提示]:
设指针p指向s结点的前趋的前趋,则p与s有何关系?
StatusDelete_Pre(CiLNode*s)//删除单循环链表中结点s的直接前驱
{
p=s;
while(p->next->next!
=s)p=p->next;//找到s的前驱的前驱p
p->next=s;
returnOK;
}//Delete_Pre
2.10已知有单链表表示的线性表中含有三类字符的数据元素(如字母字符、数字字符和其它字符),试编写算法来构造三个以循环链表表示的线性表,使每个表中只含同一类的字符,且利用原表中的结点空间作为这三个表的结点空间,头结点可另辟空间。
[teacher's]
/*CH2_10拆分链表并重构循环链表*/
#include
typedefstructnode
{charx;
structnode*next;
}snode,*Linklist;
Linklistcreate()
{snode*head,*rear,*s;
chary;
head=(Linklist)malloc(sizeof(snode));
rear=head;
clrscr();
printf("\nPleasebuildthelinklist(Fromtheend):
(!
=$)\n");
scanf("%c",&y);
getchar();/*将键盘缓冲区中的回车符取出以腾空*/
while(y!
='$')
{s=(Linklist)malloc(sizeof(snode));
s->x=y;
rear->next=s;
rear=s;
scanf("%c",&y);
getchar();
}
rear->next=NULL;
return(head);
}
LinklistLinklist_divide(snode*head,snode*A,snode*B,snode*C)
{Linklists,p,q,r;/*拆分链表并重构循环链表*/
s=head->next;
p=A;/*alphabet*/
q=B;/*digit*/
r=C;/*other*/
while(s)
{if((s->x>='a'&&s->x<='z')||(s->x>='A'&&s->x<='Z'))
{p->next=s;p=s;}
elseif(s->x>='0'&&s->x<='9')
{q->next=s;q=s;}
else
{r->next=s;r=s;}
s=s->next;
}
p->next=A;q->next=B;r->next=C;/*将尾元节点的next指向头节点*/
}
main()
{Linklisth,A,B,C,p,q,r;
h=create();
/*准备三个空链表*/
A=(Linklist)malloc(sizeof(snode));/*alphabet*/
B=(Linklist)malloc(sizeof(snode));/*digit*/
C=(Linklist)malloc(sizeof(snode));/*other*/
Linklist_divide(h,A,B,C);
p=A->next;
printf("\n*****************************************\n");
while(p!
=A)
{printf("%5c",p->x);
p=p->next;
}
printf("\n*****************************************\n");
q=B->next;
while(q!
=B)
{printf("%5c",q->x);
q=q->next;
}
printf("\n*****************************************\n");
r=C->next;
while(r!
=C)
{printf("%5c",r->x);
r=r->next;
}
printf("\n*****************************************\n");
}
2.13建立一个带头结点的线性链表,用以存放输入的二进制数,链表中每个结点的data域存放一个二进制位。
并在此链表上实现对二进制数加1的运算。
[提示]:
可将低位放在前面。
[teacher's]
/*ch2_13*/
#defineNULL0
typedefstructnode
{intx;
structnode*next;
}snode,*Linklist;
Linklistcreate()
{snode*head,*rear,*s;
inty;
head=(Linklist)malloc(sizeof(snode));
rear=head;
clrscr();
printf("\nPleasebuildthelinklist:
(!
=-1)\n");
scanf("%d",&y);
while(y!
=-1)
{s=(Linklist)malloc(sizeof(snode));
s->x=y;
rear->next=s;
rear=s;
scanf("%d",&y);
}
rear->next=NULL;
return(head);
}
Linklistreverse(snode*head)
{Linklistp,q;
p=head->next;
head->next=NULL;
while(p)
{q=p;
p=p->next;
q->next=head->next;
head->next=q;
}
return(head);
}
Linklistaddition(snode*head)
{intflag=1;
snode*s,*p,*q;
p=head->next;
while(p&&flag)
{q=p;p=p->next;
if(q->x==0){q->x=1;flag=0;}
else
q->x=0;
}
if(!
p)
{s=(Linklist)malloc(sizeof(snode));
s->x=1;
q->next=s;
s->next=NULL;
}
return(head);
}
main()
{Linklisth,h1,h2,h3,p;
h=create();
p=h->next;
printf("\n*****************************************\n");
while(p)
{printf("%5d",p->x);
p=p->next;
}
printf("\n*****************************************\n");
h1=addition(h);
printf("\n");
p=h1->next;
while(p)
{printf("%5d",p->x);
p=p->next;
}
printf("\n*****************************************\n");
}