编程题
6-1 删除顺序表中的偶数
本题要求实现一个函数,可删除顺序表中的偶数元素。
函数接口定义:
void Del_even(SqList *L);
答案:
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;}}
}
舞伴问题
假设男士和女士的记录存放在一个数组中,设计算法实现舞伴配对,要求输出配对的舞伴,并输出没有配对的队头元素的姓名。
函数接口定义:
void DancePartner(DataType dancer[], int num) ;
答案:
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不是回文。
#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的结点的数值之和。
函数接口定义:
int sumDCNodes(struct BinTree *bt);
答案:
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.计算二叉树的叶子数
本题是计算二叉树中叶子结点的个数。
函数接口定义:
在这里描述函数接口。例如:
int num (Bptr p);
答案:
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.二叉树的递归遍历
要求使用递归算法实现二叉树的先序遍历、中序遍历和后序遍历。
函数接口定义:
void PreorderTraversal(BinTree BT) /* 二叉树的先序遍历 */
void InorderTraversal(BinTree BT) /* 二叉树的中序遍历 */
void PostorderTraversal(BinTree BT) /* 二叉树的后序遍历 */
答案:
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.求二叉树高度
本题要求给定二叉树的高度。
函数接口定义:
int GetHeight( BinTree BT );
答案:
/*递归法求二叉树的高度*/
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;elsereturn h2+1;}
}
1. 叶结点求和
对给定的有N
个节点(N>=0
)的二叉树,求叶节点元素之和。
输入格式:
第一行是一个非负整数N
,表示有N
个节点
第二行是一个整数k
,是树根的元素值
接下来有N-1
行,每行是一个新节点,格式为 r d e
三个整数,
r
表示该节点的父节点元素值(保证父节点存在);d
是方向,0
表示该节点为父节点的左儿子,1
表示右儿子;e
是该节点的元素值。
#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.最小生成树(普里姆算法)
试实现普里姆最小生成树算法。
函数接口定义:
void Prim(AMGraph G, char u);
答案:
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.统计无向图中各顶点的度
本题要求实现一个函数,统计无向图中各顶点的度。
函数接口定义:
void degree(MGraph Graph,int *num);
答案:
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.基于邻接矩阵表示的广度优先遍历
实现基于邻接矩阵表示的广度优先遍历。
函数接口定义:
void BFS(Graph G, int v);
答案:
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.实现基于邻接矩阵表示的深度优先遍历
实现基于邻接矩阵表示的深度优先遍历。
函数接口定义:
void DFS(Graph G, int v);
答案:
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.最小生成树(克鲁斯卡尔算法)
试实现克鲁斯卡尔最小生成树算法。
函数接口定义:
void Kruskal(AMGraph G);
答案:
/*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
提交系统,完成题目要求的功能。
int Search_Seq (SSTable T,ElemType k)
{ int i;T.R[0]= ____ ;for ( i=____ ; T.R[ ____ ]!= k ; ____ );return ____ ;
}
答案:
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
提交系统,完成题目要求的功能。
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 ;
}
答案:
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 折半插入排序
实现折半插入排序。
函数接口定义:
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;}}}
}