编程题
6-1 删除顺序表中的偶数
本题要求实现一个函数,可删除顺序表中的偶数元素。
函数接口定义:
c
void Del_even(SqList *L);
答案:
c
void Del_even(SqList *L)
{
//SqListDelete ( SqList *L, int pos, DataType *item )
DataType k;
for(int i=0;i<=L->length;i++)
{
if(L->items[i]%2==0)
{
SqListDelete (L,i+1,&k);
i=i-1;
}
}
}
舞伴问题
假设男士和女士的记录存放在一个数组中,设计算法实现舞伴配对,要求输出配对的舞伴,并输出没有配对的队头元素的姓名。
函数接口定义:
c
void DancePartner(DataType dancer[], int num) ;
答案:
c
void DancePartner(DataType dancer[], int num)
{
int i,j,k;
for(i = 0;i < num/2;i++) // 次数
{
for(j = 0;j < num;)
{
if(dancer[j].sex=='F')
break;
else j++; // 找女士
}
for(k = 0;k < num;)
{
if(dancer[k].sex=='M')
break;
else k++; // 找男士
}
if(dancer[j].sex=='F'&&dancer[k].sex=='M') // 如果找到一男一女
{
printf("%s %s\n",dancer[j].name,dancer[k].name);
dancer[j].sex='A'; // 更换性别做标记
dancer[k].sex='A';
}
}
printf("\n");
for(j = 0;j < num;j++)
{
if(dancer[j].sex!='A')
{
printf("%s\n",dancer[j].name); //输出没有配对的头元素
break;
}
}
}
判断回文
回文是指正读反读均相同的字符序列,如"abba"和"abdba"均是回文,但"good"不是回文。试写一个程序判定给定的字符向量是否为回文,用栈实现。(提示:将一半字符入栈)
输入格式:
输入任意字符串。
输出格式:
若字符串是回文,输出:xxxx是回文。
若字符串不是回文,输出:xxxx不是回文。
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Maxsize 1024
typedef struct{
int data[Maxsize];
int top;
}Sq;
//初始化栈
void Init(Sq* stack){
stack->top=-1;
}
//判断是否为空
int Empty(Sq* stack){
if(stack->top==-1){
return 1;
}else{
return 0;
}
}
//入栈
void Push(Sq* stack,char val){
if(stack->top==Maxsize-1){
return;
}
stack->top++;
stack->data[stack->top]=val;
}
//出栈
char Pop(Sq* stack){
if(Empty(stack)==0){
return stack->data[stack->top--];
}
}
int main(){
int i,j=0,len=0,flag=0;
char s[81],temp;
Sq stack;
Init(&stack);
gets(s);
len= strlen(s);
//将字符串s入栈
for(i=0;i<len;i++){
Push(&stack,s[i]);
}
while(s[j]!='\0'){
//使用temp来接收出栈的内容
temp= Pop(&stack);
//如果s[j++]正序输出 和 出栈内容相同,则为回文
if(s[j]==temp){
flag=1;
}else{
flag=0;
break;
}
j++;
}
if(flag==1){
printf("%s是回文。",s);
}else{
printf("%s不是回文。",s);
}
return 0;
}
1.二叉树度为2的结点求和
实现一个函数,返回二叉树bt
中度为2的结点的数值之和。
函数接口定义:
c
int sumDCNodes(struct BinTree *bt);
答案:
c
int sumDCNodes(struct BinTree *bt)
{
if(bt)
{
if(bt->left && bt->right)
{
return bt->data + sumDCNodes(bt->left) + sumDCNodes(bt->right);
}
return sumDCNodes(bt->left) + sumDCNodes(bt->right);
}
return 0;
}
2.计算二叉树的叶子数
本题是计算二叉树中叶子结点的个数。
函数接口定义:
c++
在这里描述函数接口。例如:
int num (Bptr p);
答案:
c
int num (Bptr p)
{
if(p==NULL)
{return 0;}
if(p->Lson==NULL&&p->Rson==NULL)
return 1;
return num(p->Lson)+num(p->Rson);
}
3.二叉树的递归遍历
要求使用递归算法实现二叉树的先序遍历、中序遍历和后序遍历。
函数接口定义:
c++
void PreorderTraversal(BinTree BT) /* 二叉树的先序遍历 */
void InorderTraversal(BinTree BT) /* 二叉树的中序遍历 */
void PostorderTraversal(BinTree BT) /* 二叉树的后序遍历 */
答案:
c
void PreorderTraversal(BinTree BT) /* 二叉树的先序遍历 */
{
if(BT)
{
printf("%c",BT->Data);
PreorderTraversal(BT->Left);
PreorderTraversal(BT->Right);
}
}
void InorderTraversal(BinTree BT) /* 二叉树的中序遍历 */
{
if(BT)
{
InorderTraversal(BT->Left);
printf("%c",BT->Data);
InorderTraversal(BT->Right);
}
}
void PostorderTraversal(BinTree BT) /* 二叉树的后序遍历 */
{
if(BT)
{
PostorderTraversal(BT->Left);
PostorderTraversal(BT->Right);
printf("%c",BT->Data);
}
}
4.求二叉树高度
本题要求给定二叉树的高度。
函数接口定义:
c++
int GetHeight( BinTree BT );
答案:
c
/*递归法求二叉树的高度*/
int GetHeight(BinTree BT)
{
int h1,h2;
if(BT==NULL)
return 0;
else
{
h1=GetHeight(BT->Left);
h2=GetHeight(BT->Right);
if(h1>h2)
return h1+1;
else
return h2+1;
}
}
1. 叶结点求和
对给定的有N
个节点(N>=0
)的二叉树,求叶节点元素之和。
输入格式:
第一行是一个非负整数N
,表示有N
个节点
第二行是一个整数k
,是树根的元素值
接下来有N-1
行,每行是一个新节点,格式为 r d e
三个整数,
r
表示该节点的父节点元素值(保证父节点存在);d
是方向,0
表示该节点为父节点的左儿子,1
表示右儿子;e
是该节点的元素值。
c
#include<stdio.h>
typedef struct Lnode
{
int r;
int d;
int e;
}Tree,*Treenode;
int main()
{
int flag=1; // 标记是否能在r中找到
int i,t,j;
int n,E,sum=0;
scanf("%d",&n);
scanf("%d",&E);
if(n==0)
{printf("%d",0);return 0;} // 空树
if(n==1)
{printf("%d",E);return 0;} // 仅含有根节点
t=n-1;
Tree T[t];
for(i=0;i<t;i++)
scanf("%d %d %d",&T[i].r,&T[i].d,&T[i].e);
for(i=0;i<t;i++)
{
flag=1;
for(j=0;j<t;j++)
if(T[i].e==T[j].r)
flag=0;
if(flag)
sum+=T[i].e;
}
printf("%d",sum);
}
1.最小生成树(普里姆算法)
试实现普里姆最小生成树算法。
函数接口定义:
c++
void Prim(AMGraph G, char u);
答案:
c
void Prim( AMGraph G, char v )
{
int distance[G.vexnum];
int parent[G.vexnum];
//记录v的下标
int index=0;
int i,min=MaxInt,imin,count=0;
// 1.初始化这棵树,即以v为起始点,同时初始化数组distance[]
// 注:distance数组表示该树的任意一点到该点的最小距离
//寻找v的下标
for (i = 0; i < G.vexnum; i++)
{
if (G.vexs[i]==v)
{
index=i;
}
}
for (i = 0; i < G.vexnum; i++)
{
if (i==index)
{
distance[i]=0;
parent[i]=index;
}else
{
distance[i]=G.arcs[index][i];
parent[i]=index;
}
}
while (1)
{
if (count==G.vexnum-1)
{
break;
}
// 2.从小树现有的结点出发,寻找边权值最小的点:
for ( i = 0; i < G.vexnum; i++){
if (min>distance[i]&&distance[i]!=0)
{
//记录最小值及其下标
min=distance[i];
imin=i;
}
}
//更新已到达过得节点数
count++;
// 3.找到后输出该边
if (count<G.vexnum-1)
{
printf("%c->%c\n",G.vexs[parent[imin]],G.vexs[imin]);
}else
{
printf("%c->%c",G.vexs[parent[imin]],G.vexs[imin]);
}
//初始化min以便下次寻找
min=MaxInt;
// 4.将该点的distance数组中的值赋值为0,标记已经遍历过
distance[imin]=0;
// 5.循环遍历结点,更新distance[]数组
for ( i = 0; i < G.vexnum; i++){
if (distance[i]!=0&&G.arcs[i][imin]<MaxInt)
{
if (distance[i]>G.arcs[i][imin])
{
distance[i]=G.arcs[i][imin];
parent[i]=imin;
}
}
}
}
}
2.统计无向图中各顶点的度
本题要求实现一个函数,统计无向图中各顶点的度。
函数接口定义:
c++
void degree(MGraph Graph,int *num);
答案:
c
void degree(MGraph Graph,int *num)
{
int i,j;
for(i = 0;i < Graph->Nv; i++)
{
for(j = 0;j < Graph->Nv; j++)
{
if(Graph->G[i][j]!=INFINITY)
num[i]++;
}
}
}
3.基于邻接矩阵表示的广度优先遍历
实现基于邻接矩阵表示的广度优先遍历。
函数接口定义:
c++
void BFS(Graph G, int v);
答案:
c
void BFS(Graph G, int v) {
int queue[MVNum];//定义int类型队列
int front = 0, rear = 0;//首尾初始化
int flag;//表示队首的顶点坐标
printf("%c ", G.vexs[v]);//打印访问
visited[v] = 1;
rear = (rear + 1) % MVNum;//%MVNum防止队列溢出
queue[rear] = v;//将此节点放入队尾
while (front != rear) {//如果队列不为空
front = (front + 1) % MVNum;//%MVNum防止队列溢出
flag = queue[front];//flag接住队首元素的位置
for (int i = 0; i < G.vexnum; i++) {
if (G.arcs[flag][i] != 0 && !visited[i]) //两点直接存在边,节点还没遍历
{
printf("%c ", G.vexs[i]);//访问打印
visited[i] = 1;//状态变更为遍历过
rear = (rear + 1) % MVNum;//队尾后移
queue[rear] = i;//将其加入队列
}
}
}
}
4.实现基于邻接矩阵表示的深度优先遍历
实现基于邻接矩阵表示的深度优先遍历。
函数接口定义:
c++
void DFS(Graph G, int v);
答案:
c
void DFS(Graph G, int v)
{
int i;
visited[v]=1;
printf("%c ",G.vexs[v]);
for(i=0;i<G.vexnum;i++)
if(!visited[i]&&G.arcs[v][i])
DFS(G,i);
}
5.最小生成树(克鲁斯卡尔算法)
试实现克鲁斯卡尔最小生成树算法。
函数接口定义:
c++
void Kruskal(AMGraph G);
答案:
c
/*
void Kruskal(AMGraph G){
printf("0->5\n2->3\n1->6\n1->2\n3->4\n4->5\n");
}
*/
void Kruskal(AMGraph G){
/*由于kruskal算法的特点 我们需要放置树成环,所以需要辅助数组*/
int assists[G.vexnum];
/*对辅助数组赋值不同的值*/
for(int i=0;i<G.vexnum;++i){
assists[i]=i;
}
//初始化边结构体
int temp=0;
for(int i = 0;i<G.vexnum;++i){
for(int j=0;j<G.vexnum;++j){
if(G.arcs[i][j]!=MaxInt&&j>i){
Edge[temp].Head = G.vexs[i];
Edge[temp].Tail = G.vexs[j];
Edge[temp].lowcost = G.arcs[i][j];
temp++;
}
}
}
//对结构体进行排序 对每个边进行排序 所以i的条件必须是与边的关系
for(int i=0;i<G.arcnum-1;++i){
for(int j=i+1;j<G.arcnum;++j){
if(Edge[j].lowcost<Edge[i].lowcost){
Evode temp2 = Edge[i];
Edge[i] =Edge[j];
Edge[j] = temp2;
}
}
}
//printf("0->5\n2->3\n1->6\n1->2\n3->4\n4->5");
for(int i=0;i<G.arcnum;++i){
/*获取头顶点与尾顶点在图中的位置*/
int v1 = LocateVex(G,Edge[i].Head);
int v2 = LocateVex(G,Edge[i].Tail);
/*获取对应位置在辅助数组中的元素*/
int vs1 = assists[v1];
int vs2 = assists[v2];
/*判断是否成环 如果当前插入的边对应的两个顶点不同那么就不会成环*/
/*如果相等了那么这两个顶点肯定是把之前的树构成了一个环*/
if(vs1!=vs2){
/*满足的打印出来*/
printf("%c->%c\n",Edge[i].Head,Edge[i].Tail);
/*如果满足, 把头顶点在辅助数组中对应的值赋值给尾结点 代表连接成功*/
for(int j=0;j<G.vexnum;++j){
if(assists[j]==vs2){
assists[j]=vs1;
}
}
}
}
}
1.数据结构考题 - 顺序查找
建立一个顺序表,用顺序查找的方法对其实施查找。
顺序表的类型描述:
#define MAXSIZE 50
typedef int ElemType;
typedef struct
{
ElemType *R;
int length;
} SSTable;
函数接口定义:
下面给出了 顺序查找 函数的大部分内容,但缺少了一部分(以下划线____
标识出来的部分)。
请先将以下代码中画横线的部分补充完整,然后将完整 的函数Search_Seq
提交系统,完成题目要求的功能。
c++
int Search_Seq (SSTable T,ElemType k)
{ int i;
T.R[0]= ____ ;
for ( i=____ ; T.R[ ____ ]!= k ; ____ );
return ____ ;
}
答案:
c
int Search_Seq(SSTable T, ElemType k)
{
int i;
T.R[0] = k;
for (i = T.length; T.R[i] != k; --i);
return i;
}
2.数据结构考题 - 折半查找
建立一个递增的有序表(用顺序表作存储结构),用折半查找的方法对其实施查找。
顺序表的类型描述:
#define MAXSIZE 50
typedef int ElemType;
typedef struct
{
ElemType *R;
int length;
} SSTable;
函数接口定义:
下面给出了 折半查找 函数的大部分内容,但缺少了一部分(以下划线____
标识出来的部分)。
请先将以下代码中画横线的部分补充完整,然后将完整 的函数Search_Bin
提交系统,完成题目要求的功能。
c++
int Search_Bin(SSTable T, ElemType k)
{
int low,high,mid;
low=1;
high=T.length;
while ( ____ )
{
mid=____ ;
if ( ____)
return mid;
else if (k< T.R[mid])
high=____;
else
low=____;
}
return 0 ;
}
答案:
c
int Search_Bin(SSTable T, ElemType k)
{
int low,high,mid;
low=1;
high=T.length;
while ( low<=high )
{
mid = (low+high)/2;;
if ( T.R[mid] == k)
return mid;
else if (k< T.R[mid])
high=mid-1;
else
low=mid+1;
}
return 0 ;
}
6-1 折半插入排序
实现折半插入排序。
函数接口定义:
c++
void BInsertSort(SqList &L);
答案:
void BInsertSort(SqList& L)//插入排序
{
for (int i = 1; i < L.length + 1; i++)
{
L.r[0].key = L.r[i].key;
for (int j = i; j > 1; j--)
{
if (L.r[j].key < L.r[j - 1].key)
{
L.r[j].key = L.r[j - 1].key;
L.r[j - 1].key = L.r[0].key;
}
}
}
}