数据结构例题.docx
《数据结构例题.docx》由会员分享,可在线阅读,更多相关《数据结构例题.docx(31页珍藏版)》请在冰豆网上搜索。
![数据结构例题.docx](https://file1.bdocx.com/fileroot1/2023-6/18/75faddc4-d64b-4ce4-8414-985bcb79a382/75faddc4-d64b-4ce4-8414-985bcb79a3821.gif)
数据结构例题
第二章
在线性表L中第i个数据元素之前插入数据元素x
intsqinsert(v,pn,i,x)
intv[],*pn,i,x;
{intj;
if(*pn<0)
{printf(“表长错误\n”);
return(-1);
}
if(i<1||i>*pn+1)
{printf(“插入位置i不恰当\n”);
return(-1);
}
for(j=*pn;j>=i;j--)
v[j+1]=v[j];
v[i]=x;
(*pn)++;
printf(“插入成功\n”)
return(0);
}
将线性表L中第i个数据元素删除
intsqdelete(v,pn,i)
intv[],*pn,i;
{intj;
if(*pn<0)
{printf(“表长错误\n”);
return(-1);
}
if(i<1||i>*pn)
{printf(“删除位置i不恰当\n”);
return(-1);
}
for(j=i;j<*pn;j++)
v[j]=v[j+1];
(*pn)--;
printf(“删除成功\n”);
return(0);
}
插入操作的子程序用函数inlink给出
NODE*inlink(head,a,b)
NODE*head;inta,b;
{NODE*p,*q,*s;
s=(NODE*)malloc(sizeof(NODE));
s->data=b;
if(head==NULL)
{head=s;
s->next=NULL;
}
else
if(head->data==a)
{s->next=head;
head=s;
}
else
{p=head;
while((p->data!
=a)&&(p->next!
=NULL))
{q=p;
p=p->next;
}
if(p->data==a)
{q->next=s;
s->next=p;
}
else
{p->next=s;
s->next=NULL;
}
}
return(head);
}
NODE*dellink(NODE*head,inta)
{NODE*p,*q;
if(head==NULL)printf(“空链表\n”);
elseif(head->data==a)
{p=head;
head->next=head;
}
else
{p=head;
while((p->data!
=a)&&(p->next!
=NULL))
{q=p;
p=p->next;
}
if(p->data!
=a)
printf(“没有结点%d\n”,a);
else
q->next=p->next;
}
free(p);
}
栈的链式存储结构在C语言中可用下列类型定义实现:
#defineNULL0
structnode{
intdata;
structnode*next
};
typedefstructnodeNODE
2.入栈
NODE*pushlinkNODE*top,intx)
{NODE*p;
p=(NODE*)malloc(sizeof(NODE));
p->data=x;
p->next=top;
top=p;
return(top);
}
3.出栈
NODE*poplink(NODE*top,int*py)
{NODE*p;
if(top==NULL)
printf(“下溢\n”);
else
{p=top;
top=top->next;
*py=p->data;
free(p);
}
return(top);
}
下面我们给出有关队列的说明及实现队列运算的C函数:
#defineM100
charq[M];
intf,r;
(1)置空队列(初始化队列)
voidsetnull(int*front,int*rear)
{*front=-1;
*rear=-1;
}
(2)判空队列
intempty(int*front,int*rear)
{
if((*front+1)==*rear)
return
(1);
elsereturn(0);
}
(3)入队
intenqueue(charq[],charx,int*front,int*rear)
{*rear=(*rear+1)%M;
if(*rear==*front)
{printf(“上溢\n”);
return(-1);
}
else
{q[*rear]=x;
return(0);
}
}
(4)出队
intdequeue(charq[],char*y,int*front,int*rear)
{if((*front+1)==*rear)
{printf(“下溢\n”);
return(-1);
}
else{*front=(*front+1)%M;
*y=q[*front];
return(0);
}
}
设有10个队列共享内存空间,下面是其中第i各队列的入队和出队操作。
设有如下定义:
#defineN11
#defineNULL0
structnode{
chardata;
structnode*next
};
typedefstructnodeNODE;
NODE*front[N],*rear[N];
第i个队列中入队操作,x为入队元素。
voidaddqulink(inti,charx)
{NODE*q;
q=(NODE*)malloc(sizeof(NODE));
q->data=x;
q->next=NULL;
if(front[i]==NULL)
{front[i]=q;
rear[i]=q;
}
else
{rear[i]->next=q;
rear[i]=q;
}
}
第i各队列的出队操作。
voiddelqulink(inti)
{NODE*q;
if(front[i]==NULL)
printf(“队列空\n”);
else
{q=front[i];
front[i]=q->next;
printf(“%c”,q->data);
free(q);
}
}
在双向循环链表中,在数据域值为x的数据元素之之后插入数据域值为y的数据元素。
voidindouble(NODE*head,charx,chary)
{NODE*p,*q;
p=head->rlink;
while((p!
=head)&&(p->data!
=x))
p=p->rlink;
if(p==head)printf(“没找到插入位置x\n”);
else{q=(NODE*)malloc(sizeof(NODE));
q->data=y;
q->rlink=p->rlink;
q->llink=p;
p->rlink=q;
q->rlink->llink=q;
}
}
假设有7个人,编号从1到7,他们手中的密码分别是3,1,7,2,4,8,4,最初的m=2,通过报数,这7个人离开桌旁的顺序应该是:
2,3,5,4,7,6,1。
一、用顺序存储结构实现
#defineLIST_MAX_LENGTH7
#definenLIST_MAX_LENGTH
typedefintEntryType;
//将EntryType定义为int类型
voidJoseph(intcode[],intn)
{//通过一维数组code带入n个人手中的密码,n是开始就坐在桌旁的人数
SQ_LISTpeople;
inttemp,m;//m是报数的上限值
scanf(“%d”,&m);//输入最初的m
if(InitList(&people)==ERROR)exitERROR;
for(i=1;i<=n;i++)
if(ListInsert(&people,i,code[i-1])==ERROR)exitERROR;
position=0;//记录当前报数人的编号
count=0;//记录当前所报的数目
for(i=1;i<=n;i++)
{
do{//报数
position=(position+1)%n;
GetElem(people,position,&temp);
if(temp>0)count++;
}while(count!
=m);
printf(“%d”,position);
//输出当前离开桌旁人的编号
GetElem(people,position,&m);
people.item[position-1]=-people.item[position-1];
//将密码变为负值
}
}
二、链式存储结构
typedefstruct{
//循环链表中每个结点的数据域部分的类型
intNo;//编号
intcode;//密码
}INFO;
typedefINFOEntryType
voidJoseph(intcode[],intn)
{
LINK_LISTpeople;
NODE*position,*pre;//position指向当前报数的结点
if(InitList(&people)==ERROR)exitERROR;//初始化链表people
for(i=1;i<=n;i++)//以n个人的信息为数据域内容向链表插入n个结点
if(ListInsert(&people,i,code[i-1])==ERROR)exitERROR;
position=people.head;
//让position指向最后一个结点,以便报数从第一个开始
while(position->next!
=people.head)
position=NextElem(people,position);
scanf(“%d”,&m);//输入最初的m
for(i=1;icount=0;//报数处理
do{
position=NextElem(people,position);
count++;
}while(count!
=m);
printf(“%d”,position->item.No);//离开桌子处理
m=position->item.code;
pre=PriorElem(people,position);
pre->next=position->next;
free(position);
position=pre;
}
printf(“%d”,position->item.No);//处理最后一个人
free(position);
}
第三章
1.串的初始化
voidclear(STRING*s)
{inti;
for(i=0;i(*s).ch[i]=‘\0’;
(*s).len=0;
}
2.求串的长度
intlength(STRING*s)
{return((*s).len);
}
3.从文本文件f读入的内容建立串s
voidreading(STRING*S,charf[])
{FILE*fp;
inti=1;
clear(s);
if((fp=fopen(f,”r”))==NULL)
{printf(“不能打开此文件\n”);
exit(0);
}
while((((*s).ch[i]=fgetc(fp))!
=EOF)&&(i{(*s).len++;
i++;
}
(*s).ch[i]=‘\0’;
close(fp);
}
3.2.1串的连接
设t=“ABC”.s=“123”
t连接到s上后,s=“123ABC”,length(s)=6
s连接到t上后,t=“ABC123”,length(t)=6
voidconcatenate(STRING*s,STRING*t)
{intj,k;
if((*t).len+(*s).len>(STRINGMAX-1))printf(“串太长\n”);
else{k=(*s).len;
for(j=1;j<=(*t).len;j++)
(*s).ch[k+j]=(*t).ch[j];
(*s).ch[k+j]=‘\0’;
(*s).len=(*s).len+(*t).len;
}
}
求子串
voidsubstring(STRING*s,STRING*t,intstart,intspan)
{inti;
if(start+span>(*s).len+1)
span=(*s).len-start+1;
if((start<1)||(span<1))
clear(t);
else{for(i=1;i<=span;i++)
(*t).ch[i]=(*s).ch[start+i-1];
(*t).ch[i]=‘\0’;
(*t).len=span;
}
}
子串的插入与删除
voidinsert(STRING*s,STRING*t,intstart)
{inti,j;
if((*t).len>0)
if((start>0)||(start<=(*s).len+1))
if((*s).len+(*t).len{for(i=(*s).len+1;i>=start;i--)
(*s).ch[i+(*t).len]=(*s).ch[i];
(*s).len=(*s).len+(*t).len;
j=start+(*t).len-1;
for(i=start;i<=j;i++)
(*s).ch[i]=(*t).ch[i-start+1];
}
elseprintf(“t串太长\n”);
elseprintf(“插入位置start不合适\n”);
elseprintf(“t串是空串\n”);
}
例如:
a=“abbcbbdbb”,b=“bb”,c=“*”,则替换后a=“a*c*d*”.
voidreplace(STRING*a,STRING*b,STRING*c)
{intindex,p,m,n,s;
n=(*a).len;m=(*b).len;s=(*c).len;
p=1;
do{index=index1(a,b,p);
if(index!
=0)
{delete(a,index,m);
insert(a,c,index);
p=index+s;
n=(*a).len;
}
}while((p<=n-m+1)&&(index!
=0));
}
第四章
矩阵的转置
structnode
{inti,j;
floatval;
};
typedefstructnodeNODE;
voidtrans1(NODEa[],NODEb[])
{intcol,k,q,n,t;
n=a[0].j;t=(int)a[0].val;
b[0].i=a[0].j;b[0].j=a[0].i;b[0].val=a[0].val;
if(t>0)
{q=1;
for(col=1;col<=n;col++)
for(k=1;k<=t;k++)
if(a[k].j==col)
{b[q].i=a[k].j;
b[q].j=a[k].i;
b[q].val=a[k].val;
q++;
}
}
}
数组结点类型定义如下:
structnode
{introw,col;
structnode*right,*down;
union
{floatval;
structnode*next;
}same;
};
第五章
按层次遍历方法来建立二叉树的算法,
#defineMAX61
structnode
{chardata;
structnode*lc,*rc;
};
typedefstructnodeNODE;
NODE*nar[MAX];/*存放结点的数组*/
NODE*setuptree(NODE*t)
{NODE*p;charx;intf,i,j,n;
scanf(“%d”,&n);
for(i=1;i<=n;i++)
{scanf(“%d%c”,&j,&x);
p=(NODE*)malloc(sizeof(NODE));
p->lc=NULL;
p->rc=NULL;
p->data=x;
nar[j]=p;
if(j==1)
t=p;
else
{f=j/2;
if(j%2==0)
nar[f]->lc=p;
else
nar[f]->rc=p;
}
}
return(t);
}
中序遍历的非递归算法
voidinorder(NODE*p)
{NODE*q;inttop;
enum{false,true}finish;
NODE*s[MAX];
top=-1;q=p;
finish=false;
do
if(q!
=NULL)
{top++;
if(top>MAX-1)
{finish=true;
printf(“栈上溢\n”);
}
else{s[top]=q;
q=q->lc
}
}
else
if(top==-1)
finish=true;
else
{q=s[top--];
printf(“%c”,q->data);
q=q->rc;
}
while(finish==false);
}
面给出中序线索树算法。
voidinthread(THRENODE*t)
{THRENODE*p,*pr;*s[MAX];inttop;
pr=NULL;top=-1;p=t;
do
while(p!
=NULL)
{s[++top]=p;
p=p->lc;
}
if(top!
=-1)
{p=s[top--];
printf(“%c”,p->data);
if(p->lc==NULL)
{p->lt=1;
p->lc=pr;
}
else
p->lt=0;
if(pr!
=NULL)
{if(pr->rc==NULL)
{pr->rc=p;
pr->rt=1;
}
elsepr->rt=0;
}
pr=p;
p=p->rc
}
while((p!
=NULL))||(tpo!
=-1));
printf(“\n”);
pr->rt=1;
}
时间复杂度:
O(n);空间复杂度:
O(k)
建立二叉排序树,其类型说明如下:
structnode
{intdata;
structnode*lc,*rc;
};
typedefstructnodeNODE;
例如:
给出K={10,18,3,8,19,2,7,8},按上述原则构造二叉排序树,非递归算法:
NODE*sortree(NODE*t)
{NODE*p,*q;
intx;
enum{false,true}bool;
printf(“readkeywordx:
”);
scanf(“%d”,&x);
q=(NODE*)malloc(sizeof(NODE));
q->lc=NULL;
q->rc=NULL;
q->data=x;
if(t=NULL)
t=q;
else
{p=t;bool=true;
do
if(p->data>x)
if(p->lc!
=NULL)
p=p->lc;
else
{p->lc=q;
bool=false;
}
else
if(p->rc!
=NULL)
p=p->rc;
else
{p->rc=q;
bool=false;
}
while(bool==true);
}
return(t);
}
用C语言描述哈夫曼算法。
类型定义及C函数如下:
structnode
{inttag,data,lc,rc;
};
typedefstructnodeNODE;
inthuffman(NODEr[])
{inty,n,m1,m2,x1,x2,i,j,t;
scanf(“%d”,&n);
for(i=1;i<=n;i++)
{scanf(“%d”,&y);
r[i].data=y;
r[i].tag=0;
r[i].lc=0;
r[i].rc=0;
}
i=0;
while(i<=n-1)
{m1=32767;
m2=32767;
x1=0;
x2=0;
for(j=1;j<=n+i;j++)
if((r[j].data{m2=m1;
x2=x1;
m1=r[j].data;
x1=j;
}
else
if((r[j].data{m2=r[j].data;
x2=j;
}
r[x1].tag=1;r[x2].tag=1;
i++;
r[n+i].data=r[x1].data+r[x2].data;
r[n+i].lc=x1;
r[n+i].rc=x2;
r[n+i].tag=0;
}
t=2*n-1;
return(t);
}
其时间复杂度:
(n-1)(n-i)→O(n2)
第六章
深度优先搜索算法。
structgnode
{intvex;
structgnode*next;
};
typedefstructgnodeGNODE;
voiddfs(GNODEadl[],intv)
{GNODE*p;
printf(“%d”,v);
adl[v].vex=1;
p=adl[v].next;
while(p!
=NULL)
{if(adl[p->vex].vex==0)
dfs(adl,p->vex);
p=p->next;
}
}
拓扑排序的具体函数如下:
#include“stdio.h”
typedefstructnode
{intvex;
structnode*next;
}NODE;
voidtoporder(NODEal[],intn)
{inti,j,k,top;
NODE*q;
top=0;/*初识化栈*/
for(i=1;i<=n;i++)
if(al[i].vex==0)/*判断i位置的顶点入度是否