数据结构经典例题
1.设计一个算法将L拆分成两个带头节点的单链表L1和L2。
void split(LinkList *&L,LinkList *&L1,LinkList *&L2)
{ LinkList *p=L->next,*q,*r1; //p指向第1个数据节点
L1=L; //L1利用原来L的头节点
r1=L1; //r1始终指向L1的尾节点
L2=(LinkList *)malloc(sizeof(LinkList));//创建L2的头节点
L2->next=NULL; //置L2的指针域为NULL
while (p!=NULL)
{ r1->next=p; //采用尾插法将*p(data值为ai)插入L1中
r1=p;
p=p->next; //p移向下一个节点(data值为bi)
q=p->next; //由于头插法修改p的next域,故用q保存*p的后继节点
p->next=L2->next; //采用头插法将*p插入L2中
L2->next=p;
p=q; //p重新指向ai+1的节点
}
r1->next=NULL; //尾节点next置空
}
2.查找链表中倒数第k个位置上的节点(k为正整数)。若查找成功,算法输出该节点的data域的值,并返回1;否则,只返回0。
typedef struct LNode
{ int data;
struct LNode *link;
} *LinkList;
int Searchk(LinkList list,int k)
{ LinkList p,q;
int count=0;
p=q=list->link;
while (p!=NULL)
{ if (count
count++;
else
q=q->link;
p=p->link;
}
if (count
else
{ printf("%d",q->data);
return(1);
}
}
3.假定采用带头节点的单链表保存单词,当两个单词有相同的后缀时,则可共享相同的后缀存储空间。设str1和str2分别指向两个单词所在单链表的头节点请设计一个时间上尽可能高效的算法,找出由str1和str2所指向两个链表共同后缀的起始位置。
typedef struct Node
{ char data;
struct Node *next;
} SNODE;
SNODE * Findlist(SNODE *str1,SNODE *str2)
{ int m,n;
SNODE *p,*q;
m=Listlen(str1); //求单链表str1的长度m
n=Listlen(str2); //求单链表str2的长度n
for (p=str1;m>n;m--) //若m大,则str1后移m-n+1个节点
p=p->next;
for (q=str2;m
q=q->next;
while (p->next!=NULL && p->next!=q->next)
{ p=p->next; //p、q两步后移找第一个指针值相等的节点
q=q->next;
}
return p->next;
}
int Listlen(SNODE *head) //求单链表的长度
{ int len=0;
while (head->next!=NUL)
{ len++;
head=head->next;
}
return len;
}
4.设计一个算法,删除一个单链表L中元素值最大的节点。
void delmaxnode(LinkList *&L)
{ LinkList *p=L->next,*pre=L,*maxp=p,*maxpre=pre;
while (p!=NULL) //用p扫描整个单链表,pre始终指向其前驱节点
{ if (maxp->data
{ maxp=p; //更改maxp
maxpre=pre; //更改maxpre
}
pre=p; //p、pre同步后移一个节点
p=p->next;
}
maxpre->next=maxp->next; //删除*maxp节点
free(maxp); //释放*maxp节点
}
5. 有一个带头节点的单链表L(至少有一个数据节点),设计一个算法使其元素递增有序排列。
void sort(LinkList *&L)
{ LinkList *p,*pre,*q;
p=L->next->next; //p指向L的第2个数据节点
L->next->next=NULL; //构造只含一个数据节点的有序表
while (p!=NULL)
{ q=p->next; //q保存*p节点后继节点的指针
pre=L; //从有序表开头进行比较,pre指向插入*p的前驱节点
while (pre->next!=NULL && pre->next->data
pre=pre->next; //在有序表中找插入*p的前驱节点*pre
p->next=pre->next;//将*pre之后插入*p
pre->next=p;
p=q; //扫描原单链表余下的节点
}
}
6. 有一个带头节点的双链表L,设计一个算法将其所有元素逆置,即第1个元素变为最后一个元素,第2个元素变为倒数第2个元素,…,最后一个元素变为第1个元素。
void reverse(DLinkList *&L) //双链表节点逆置
{ DLinkList *p=L->next,*q; //p指向开好节点
L->next=NULL; //构造只有头节点的双链表L
while (p!=NULL) //扫描L的数据节点
{ q=p->next; //用q保存其后继节点
p->next=L->next; //采用头插法将*p节点插入
if (L->next!=NULL) //修改其前驱指针
L->next->prior=p;
L->next=p;
p->prior=L;
p=q; //让p重新指向其后继节点
}
}
7.编写出判断带头节点的双向循环链表L是否对称相等的算法。
int Equeal(DLinkList *L)
{ int same=1;
DLinkList *p=L->next; //p指向第一个数据节点
DLinkList *q=L->prior; //q指向最后数据节点
while (same==1)
if (p->data!=q->data)
same=0;
else
{
if (p==q) break; //数据节点为奇数的情况
q=q->prior;
if (p==q) break; //数据节点为偶数的情况
p=p->next;
}
return same;
}
8.假设有两个有序表LA和LB表示,设计一个算法,将它们合并成一个有序表LC。要求不破坏原有表LA和LB。
void UnionList(SqList *LA,SqList *LB,SqList *&LC)
{ int i=0,j=0,k=0;//i、j分别为LA、LB的下标,k为LC中元素个数
LC=(SqList *)malloc(sizeof(SqList)); //建立有序顺序表LC
while (i
{ if (LA->data[i]
{ LC->data[k]=LA->data[i];
i++;k++;
}
else //LA->data[i]>LB->data[j]
{ LC->data[k]=LB->data[j];
j++;k++;
}
}
while (i
{ LC->data[k]=LA->data[i];
i++;k++;
}
while (j
{ LC->data[k]=LB->data[j];
j++;k++;
}
LC->length=k;
}
9.设有4个元素a、b、c、d进栈,给出它们所有可能的出栈次序。
解:所有可能的出栈次序如下:
abcd abdc acbd acdb
adcb bacd badc bcad
bcda bdca cbad cbda
cdba dcba
10.编写一个算法利用顺序栈判断一个字符串是否是对称串。所谓对称串是指从左向右读和从右向左读的序列相同。
bool symmetry(ElemType str[])
{ int i; ElemType e;
SqStack *st;
InitStack(st); //初始化栈
for (i=0;str[i]!='\0';i++) //将串所有元素进栈
Push(st,str[i]); //元素进栈
for (i=0;str[i]!='\0';i++)
{ Pop(st,e); //退栈元素e
if (str[i]!=e) //若e与当前串元素不同则不是对称串
{ DestroyStack(st);//销毁栈
return false;
}
}
DestroyStack(st); //销毁栈
return true;
}
11.编写一个算法判断输入的表达式中括号是否配对(假设只含有左、右圆括号)
bool Match(char exp[],int n)
{ int i=0; char e; bool match=true; SqStack *st;
InitStack(st); //初始化栈
while (i
{ if (exp[i]=='(') //当前字符为左括号,将其进栈
Push(st,exp[i]);
else if (exp[i]==')') //当前字符为右括号
{ if (GetTop(st,e)==true)
{ if (e!='(') //栈顶元素不为'('时表示不匹配
match=false;
else
Pop(st,e); //将栈顶元素出栈
}
else match=false; //无法取栈顶元素时表示不匹配
}
i++; //继续处理其他字符
}
if (!StackEmpty(st)) //栈不空时表示不匹配
match=false;
DestroyStack(st); //销毁栈
return match;
}
12.在链串中,设计一个算法把最先出现的子串"ab"改为"xyz"。
void Repl(LiString *&s)
{ LiString *p=s->next,*q;
int find=0;
while (p->next!=NULL && find==0) //查找'ab'子串
{ if (p->data=='a' && p->next->data=='b')//找到子串
{ p->data='x';p->next->data='z'; //替换为xyz
q=(LiString *)malloc(sizeof(LiString));
q->data='y';q->next=p->next;p->next=q;
find=1;
}
else p=p->next;
}
}
13.含n个节点的三次树的最小高度是多少?最大高度是多少?
解:设含n个节点的(为完全三次树时高度最小)的三次树的最小高度为h,则有:
1+3+9+…+3h-2<n≤1+3+9+…+3h-1
(3h-1-1)/2 <n≤ (3h-1)/2
3h-1<2n+1≤3h
即:h= log3(2n+1)
最大高度为n-2。
14. 假设图G采用邻接表存储,设计一个算法,输出图G中从顶点u到v的所有简单路径。
void PathAll(ALGraph *G,int u,int v,int path[],int d)
//d是到当前为止已走过的路径长度,调用时初值为-1
{ int w,i; ArcNode *p;
visited[u]=1; d++; //路径长度增1
path[d]=u; //将当前顶点添加到路径中
if (u==v && d>1) //输出一条路径
{ printf(" ");
for (i=0;i<=d;i++) printf("%d ",path[i]);
printf("\n");
}
p=G->adjlist[u].firstarc; //p指向u的第一条边
while (p!=NULL)
{ w=p->adjvex; //w为u的邻接顶点
if (visited[w]==0) //若顶点未标记访问,则递归访问之
PathAll(G,w,v,path,d);
p=p->nextarc //找u的下一个邻接顶点
}
visited[u]=0; //恢复环境
}
void main()
{ int path[MAXV],u=1,v=4,i,j;
MGraph g;
ALGraph *G;
g.n=5;g.e=6;
int A[MAXV][MAXV]={ {0,1,0,1,0},{1,0,1,0,0},
{0,1,0,1,1}, {1,0,1,0,1}, {0,0,1,1,0} };
for (i=0;i
for (j=0;j
g.edges[i][j]=A[i][j];
MatToList(g,G);
for (i=0;i
visited[i]=0;
printf("图G:\n");DispAdj(G); //输出邻接表
printf("从%d到%d的所有路径:\n",u,v);
PathAll(G,u,v,path,-1);
printf("\n");
}
15.普里姆(Prim)算法如下:
#define INF 32767 //INF表示∞
void Prim(MGraph g,int v)
{ int lowcost[MAXV];
int min;
int closest[MAXV],i,j,k;
for (i=0;i
{ lowcost[i]=g.edges[v][i];
closest[i]=v;
}
for (i=1;i
{ min=INF;
for (j=0;j
if (lowcost[j]!=0 && lowcost[j]
{ min=lowcost[j];
k=j; //k记录最近顶点的编号
}
printf(" 边(%d,%d)权为:%d\n",closest[k],k,min);
lowcost[k]=0; //标记k已经加入U
for (j=0;j
if (g.edges[k][j]!=0 && g.edges[k][j]
{ lowcost[j]=g.edges[k][j];
closest[j]=k;
}
}
}
16.冒泡排序
void BubbleSort(RecType R[],int n)
{ int i,j; bool exchange;RecType temp;
for (i=0;i
{ exchange=false;
for (j=n-1;j>i;j--) //比较,找出最小关键字的记录
if (R[j].key
{ temp=R[j]; R[j]=R[j-1];R[j-1]=temp;
exchange=true;
}
if (exchange==false) return; //中途结束算法
}
}
本文来源:https://www.2haoxitong.net/k/doc/21e4ac3026fff705cd170aa2.html
文档为doc格式