6-1 递增的整数序列链表的插入
本题要求实现一个函数,在递增的整数序列链表(带头结点)中插入一个新整数,并保持该序列的有序性。
函数接口定义:
List Insert( List L, ElementType X );
其中List结构定义如下:
typedefstructNode *PtrToNode;structNode { ElementType Data; /* 存储结点数据 */ PtrToNode Next; /* 指向下一个结点的指针 */};
typedef PtrToNode List; /* 定义单链表类型 */
L是给定的带头结点的单链表,其结点存储的数据是递增有序的;函数Insert要将X插入L,并保持该序列的有序性,返回插入后的链表头指针。
裁判测试程序样例:
#include<stdio.h>#include<stdlib.h>typedefint ElementType;
typedefstructNode *PtrToNode;structNode { ElementType Data;
PtrToNode Next;
};
typedef PtrToNode List;
List Read(); /* 细节在此不表 */voidPrint( List L ); /* 细节在此不表 */List Insert( List L, ElementType X );
intmain(){
List L;
ElementType X;
L = Read();
scanf("%d", &X);
L = Insert(L, X);
Print(L);
return0;
}
/* 你的代码将被嵌在这里 */
输入样例:
5
1 2 4 5 6
3
输出样例:
1 2 3 4 5 6
List Insert( List L, ElementType X ){
List t=(List)malloc(sizeof(struct Node));
t->Data=X;
t->Next=NULL;
List head=L;
while(L->Next!=NULL&&L->Next->Data<=X){
L=L->Next;
}
t->Next=L->Next;
L->Next=t;
return head;
}
6-61 求二叉树高度
本题要求给定二叉树的高度。
函数接口定义:
int GetHeight( BinTree BT );
其中BinTree结构定义如下:
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
要求函数返回给定二叉树BT的高度值。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef char ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
BinTree CreatBinTree(); /* 实现细节忽略 */
int GetHeight( BinTree BT );
int main()
{
BinTree BT = CreatBinTree();
printf("%d\n", GetHeight(BT));
return 0;
}
/* 你的代码将被嵌在这里 */
输出样例(对于图中给出的树):
4
int GetHeight( BinTree BT )
{
int HL,HR,MaxH;
if(BT)
{
HL=GetHeight(BT->Left);
HR=GetHeight(BT->Right);
MaxH=HL>HR? HL:HR;
return (MaxH+1);
}
else return 0;
}
6-2 先序输出叶结点
本题要求按照先序遍历的顺序输出给定二叉树的叶结点。
函数接口定义:
void PreorderPrintLeaves( BinTree BT );
其中BinTree结构定义如下:
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
函数PreorderPrintLeaves应按照先序遍历的顺序输出给定二叉树BT的叶结点,格式为一个空格跟着一个字符。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef char ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
BinTree CreatBinTree(); /* 实现细节忽略 */
void PreorderPrintLeaves( BinTree BT );
int main()
{
BinTree BT = CreatBinTree();
printf("Leaf nodes are:");
PreorderPrintLeaves(BT);
printf("\n");
return 0;
}
/* 你的代码将被嵌在这里 */
输出样例(对于图中给出的树):
Leaf nodes are: D E H I
void PreorderPrintLeaves( BinTree BT ){
if(BT==NULL){
printf("");
}
else{
if(BT->Left==NULL&&BT->Right==NULL){
printf(" %c",BT->Data);
}
PreorderPrintLeaves( BT->Left );
PreorderPrintLeaves( BT->Right );
}
}
6-3 中序输出度为1的结点
本题要求实现一个函数,按照中序遍历的顺序输出给定二叉树中度为1的结点。
函数接口定义:
void InorderPrintNodes( BiTree T);
T是二叉树树根指针,InorderPrintNodes按照中序遍历的顺序输出给定二叉树T中度为1的结点,格式为一个空格跟着一个字符。
其中BiTree结构定义如下:
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;
typedef struct BiTNode
{
ElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
BiTree Create();/* 细节在此不表 */
void InorderPrintNodes( BiTree T);
int main()
{
BiTree T = Create();
printf("Nodes are:");
InorderPrintNodes(T);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
输入为由字母和'#'组成的字符串,代表二叉树的扩展先序序列。例如对于如下二叉树,输入数据:
ACG#H###BEF###D##
输出样例(对于图中给出的树):
Nodes are: G C E
void InorderPrintNodes( BiTree T)
{
if(T==NULL) return ;
if(!T->lchild&&!T->rchild) return ;
else if(T)
{
InorderPrintNodes(T->lchild);
if(!T->lchild||!T->rchild)
printf(" %c",T->data);
InorderPrintNodes(T->rchild);
}
}
6-95 二叉排序树查找操作
本题要求实现二叉排序树的查找操作。
函数接口定义:
BSTree SearchBST(BSTree T,ElemType e);
其中BSTree结构定义如下:
typedef int ElemType;
typedef struct BSTNode
{
ElemType data;
struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct BSTNode
{
ElemType data;
struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
BSTree CreateBST();/* 二叉排序树创建,由裁判实现,细节不表 */
BSTree SearchBST(BSTree T,ElemType e);
void Inorder(BSTree T);/* 中序遍历,由裁判实现,细节不表 */
int main()
{
BSTree T,result;
ElemType n,e;
T = CreateBST();
printf("Inorder:"); Inorder(T); printf("\n");
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&e);
result = SearchBST(T,e);
if(result) printf("%d is found\n",result->data);
else printf("%d is not found\n",e);
}
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
输入第一行以-1结束的整数,为二叉排序树中元素初始序列,第二行为一个整数n,代表要查询的元素个数,第三行为n个整数,代表要查询的元素值。
例如创建如下二叉排序树,输入为:
4 3 5 1 2 7 6 8 -1
4
1 8 0 9
输出样例:
Inorder: 1 2 3 4 5 6 7 8
1 is found
8 is found
0 is not found
9 is not found
BSTree SearchBST(BSTree T,ElemType e){
if(!T || T->data == e)
return T;
else if(e < T->data)
return SearchBST(T->lchild,e);
else
return SearchBST(T->rchild,e);
}
6-98 二叉搜索树的操作集
本题要求实现给定二叉搜索树的5种常用操作。
函数接口定义:
BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );
其中BinTree结构定义如下:
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
函数Insert将X插入二叉搜索树BST并返回结果树的根结点指针;
函数Delete将X从二叉搜索树BST中删除,并返回结果树的根结点指针;如果X不在树中,则打印一行Not Found并返回原树的根结点指针;
函数Find在二叉搜索树BST中找到X,返回该结点的指针;如果找不到则返回空指针;
函数FindMin返回二叉搜索树BST中最小元结点的指针;
函数FindMax返回二叉搜索树BST中最大元结点的指针。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
void PreorderTraversal( BinTree BT ); /* 先序遍历,由裁判实现,细节不表 */
void InorderTraversal( BinTree BT ); /* 中序遍历,由裁判实现,细节不表 */
BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );
int main()
{
BinTree BST, MinP, MaxP, Tmp;
ElementType X;
int N, i;
BST = NULL;
scanf("%d", &N);
for ( i=0; i<N; i++ ) {
scanf("%d", &X);
BST = Insert(BST, X);
}
printf("Preorder:"); PreorderTraversal(BST); printf("\n");
MinP = FindMin(BST);
MaxP = FindMax(BST);
scanf("%d", &N);
for( i=0; i<N; i++ ) {
scanf("%d", &X);
Tmp = Find(BST, X);
if (Tmp == NULL) printf("%d is not found\n", X);
else {
printf("%d is found\n", Tmp->Data);
if (Tmp==MinP) printf("%d is the smallest key\n", Tmp->Data);
if (Tmp==MaxP) printf("%d is the largest key\n", Tmp->Data);
}
}
scanf("%d", &N);
for( i=0; i<N; i++ ) {
scanf("%d", &X);
BST = Delete(BST, X);
}
printf("Inorder:"); InorderTraversal(BST); printf("\n");
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
10
5 8 6 2 4 1 0 10 9 7
5
6 3 10 0 5
5
5 7 0 10 3
输出样例:
Preorder: 5 2 1 0 4 8 6 7 10 9
6 is found
3 is not found
10 is found
10 is the largest key
0 is found
0 is the smallest key
5 is found
Not Found
Inorder: 1 2 4 6 8 9
Position Find(BinTree BST, ElementType X) {
BinTree curNode = BST;
while (curNode) {
if (curNode->Data == X) {
return curNode;
}
else if (X < curNode->Data) {
curNode = curNode->Left;
}
else {
curNode = curNode->Right;
}
}
return NULL;
}
Position FindMin( BinTree BST ) {
if(BST) {
while(BST->Left) {
BST=BST->Left;
}
}
return BST;
}
Position FindMax( BinTree BST ) {
if(BST) {
while(BST->Right) {
BST=BST->Right;
}
}
return BST;
}
BinTree Insert(BinTree BST, ElementType X) {
if (!BST) {
BinTree root = (BinTree)malloc(sizeof(struct TNode));
root->Data = X;
root->Left = NULL;
root->Right = NULL;
return root;
}
BinTree parent = NULL;
BinTree curNode = BST;
while (curNode) {
if (X < curNode->Data) {
parent = curNode;
curNode = curNode->Left;
}
else {
parent = curNode;
curNode = curNode->Right;
}
}
BinTree newNode = (BinTree)malloc(sizeof(struct TNode));
newNode->Data = X;
newNode->Left = NULL;
newNode->Right = NULL;
if (parent->Data > X) {
parent->Left = newNode;
}
else {
parent->Right = newNode;
}
return BST;
}
BinTree Delete( BinTree BST, ElementType X ) {
if(!BST) {
printf("Not Found\n");
} else {
if(BST->Data>X) {
BST->Left=Delete(BST->Left,X);
} else if(BST->Data<X) {
BST->Right=Delete(BST->Right,X);
} else {
if(BST->Left&&BST->Right) {
BinTree tmp=FindMin(BST->Right);
BST->Data=tmp->Data;
BST->Right=Delete(BST->Right,tmp->Data);
free(tmp);
} else {
if(!BST->Left) {
BST=BST->Right;
} else if(!BST->Right) {
BST=BST->Left;
}
}
}
}
return BST;
}
6-141 邻接表存储图的广度优先遍历
分数 20
全屏浏览题目
切换布局
作者 DS课程组单位 浙江大学
试实现邻接表存储图的广度优先遍历。
函数接口定义:
void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) );
其中LGraph是邻接表存储的图,定义如下:
/* 邻接点的定义 */
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
Vertex AdjV; /* 邻接点下标 */
PtrToAdjVNode Next; /* 指向下一个邻接点的指针 */
};
/* 顶点表头结点的定义 */
typedef struct Vnode{
PtrToAdjVNode FirstEdge; /* 边表头指针 */
} AdjList[MaxVertexNum]; /* AdjList是邻接表类型 */
/* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv; /* 顶点数 */
int Ne; /* 边数 */
AdjList G; /* 邻接表 */
};
typedef PtrToGNode LGraph; /* 以邻接表方式存储的图类型 */
函数BFS应从第S个顶点出发对邻接表存储的图Graph进行广度优先搜索,遍历时用裁判定义的函数Visit访问每个顶点。当访问邻接点时,要求按邻接表顺序访问。题目保证S是图中的合法顶点。
裁判测试程序样例:
#include <stdio.h>
typedef enum {false, true} bool;
#define MaxVertexNum 10 /* 最大顶点数设为10 */
typedef int Vertex; /* 用顶点下标表示顶点,为整型 */
/* 邻接点的定义 */
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
Vertex AdjV; /* 邻接点下标 */
PtrToAdjVNode Next; /* 指向下一个邻接点的指针 */
};
/* 顶点表头结点的定义 */
typedef struct Vnode{
PtrToAdjVNode FirstEdge; /* 边表头指针 */
} AdjList[MaxVertexNum]; /* AdjList是邻接表类型 */
/* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv; /* 顶点数 */
int Ne; /* 边数 */
AdjList G; /* 邻接表 */
};
typedef PtrToGNode LGraph; /* 以邻接表方式存储的图类型 */
bool Visited[MaxVertexNum]; /* 顶点的访问标记 */
LGraph CreateGraph(); /* 创建图并且将Visited初始化为false;裁判实现,细节不表 */
void Visit( Vertex V )
{
printf(" %d", V);
}
void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) );
int main()
{
LGraph G;
Vertex S;
G = CreateGraph();
scanf("%d", &S);
printf("BFS from %d:", S);
BFS(G, S, Visit);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:给定图如下
2
输出样例:
BFS from 2: 2 0 3 5 4 1 6
void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) )
{
Visited[S]=true;//标记起始点
Visit(S);
int queue[1000],front=0,rear=0;
queue[rear++]=S;//起始点入队列
PtrToAdjVNode temp;//temp就代表当前点的邻接点的下标
while(front<rear){//队伍不为空
temp=Graph->G[queue[front++]].FirstEdge;
while(temp){
int p=temp->AdjV;//把temp中的下标提取出来
if(!Visited[p]){//如果p点没有被标记的话
Visited[p]=true;
Visit(p);
queue[rear++]=p;//储存在队列中
}
temp=temp->Next;//指向下一个邻接点
}
}
}
6-144 邻接矩阵存储图的深度优先遍历
试实现邻接矩阵存储图的深度优先遍历。
函数接口定义:
void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) );
其中MGraph是邻接矩阵存储的图,定义如下:
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv; /* 顶点数 */
int Ne; /* 边数 */
WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */
函数DFS应从第V个顶点出发递归地深度优先遍历图Graph,遍历时用裁判定义的函数Visit访问每个顶点。当访问邻接点时,要求按序号递增的顺序。题目保证V是图中的合法顶点。
裁判测试程序样例:
#include <stdio.h>
typedef enum {false, true} bool;
#define MaxVertexNum 10 /* 最大顶点数设为10 */
#define INFINITY 65535 /* ∞设为双字节无符号整数的最大值65535*/
typedef int Vertex; /* 用顶点下标表示顶点,为整型 */
typedef int WeightType; /* 边的权值设为整型 */
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv; /* 顶点数 */
int Ne; /* 边数 */
WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */
bool Visited[MaxVertexNum]; /* 顶点的访问标记 */
MGraph CreateGraph(); /* 创建图并且将Visited初始化为false;裁判实现,细节不表 */
void Visit( Vertex V )
{
printf(" %d", V);
}
void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) );
int main()
{
MGraph G;
Vertex V;
G = CreateGraph();
scanf("%d", &V);
printf("DFS from %d:", V);
DFS(G, V, Visit);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:给定图如下
5
输出样例:
DFS from 5: 5 1 3 0 2 4 6
void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) )
{
Vertex j;
Visited[V] = true;//表示从V开始访问
Visit(V);//访问V,其实抛开题来讲这里一般都是打印V
for(j = 0;j < Graph->Nv;j++)
{
if(Graph->G[V][j] == 1 && !Visited[j])//邻接矩阵等于1代表有边,此时如果还没被访问就递归调用
DFS(Graph,j,Visit);
}
}
6-175 是否二叉搜索树
本题要求实现函数,判断给定二叉树是否二叉搜索树。
函数接口定义:
bool IsBST( BinTree T );
其中BinTree结构定义如下:
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
函数IsBST须判断给定的T是否二叉搜索树,即满足如下定义的二叉树:
定义:一个二叉搜索树是一棵二叉树,它可以为空。如果不为空,它将满足以下性质:
非空左子树的所有键值小于其根结点的键值。
非空右子树的所有键值大于其根结点的键值。
左、右子树都是二叉搜索树。
如果T是二叉搜索树,则函数返回true,否则返回false。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef enum { false, true } bool;
typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};
BinTree BuildTree(); /* 由裁判实现,细节不表 */
bool IsBST ( BinTree T );
int main()
{
BinTree T;
T = BuildTree();
if ( IsBST(T) ) printf("Yes\n");
else printf("No\n");
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例1:如下图
输出样例1:
Yes
输入样例2:如下图
输出样例2:
No
bool IsBST ( BinTree T ){
BinTree p;
if(!T) return true;//空树是二叉搜索树
if(!T->Left&&!T->Right)//只有一个结点的树是二叉搜索树
return true;
if(!(IsBST(T->Left)&&IsBST(T->Right)))//左右子树只要有一棵不是,就不是
return false;
//左右子树都是二叉搜索树了,
//只要左子树的最大值小于根的值且右子树的最小值大于根的值
//就能确定是一棵二叉搜索树
p=T->Left;
if(p){
while(p->Right) //左子树的最大值在最右边
p=p->Right;
if(p->Data>T->Data)
return false;
}
p=T->Right;
if(p){
while(p->Left) //右子树的最小值在最左边
p=p->Left;
if(p->Data<T->Data)
return false;
}
return true;
}
6-180 弹球距离
设有一个球从高度为h米的地方落下,碰到地面后又弹到高度为原来p倍的位置,然后又落下,再弹起,再落下…。请编写函数求初始高度为h的球下落后到基本停下来(高度小于给定阈值TOL)时在空中所经过的路程总和。
函数接口定义:
doubl edist( double h, double p );
其中h是球的初始高度,p是球弹起高度与弹起前落下高度的比值;函数dist要返回球下落后到基本停下来时在空中所经过的路程总和。注意:当弹起的高度小于裁判程序定义的常数TOL时,弹起的距离不计算在内。
裁判测试程序样例:
#include <stdio.h>
#define TOL 1E-3
double dist( double h, double p );
int main()
{
double h, p, d;
scanf("%lf %lf", &h, &p);
d = dist(h, p);
printf("%.6f\n", d);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
1.0 0.4
输出样例:
2.331149
double dist( double h, double p )//右一个注意点两次触地时走过的距离为 h+2*h*p
{
double mix=h*p;
double sum = h;//第一次落下走过的距离是h
while(mix>=TOL)
{
sum+= 2*mix;//第二次落下走过的是 h+2*h*p,依次类推
mix = mix*p;
}
return sum;
}
6-232 冒泡排序
编程实现冒泡排序函数。void bubbleSort(int arr[], int n);。其中arr存放待排序的数据,n为数组长度(1≤n≤1000)。
函数接口定义如下:
/* 对长度为n的数组arr执行冒泡排序 */
void bubbleSort(int arr[], int n);
请实现bubbleSort函数,使排序后的数据从小到大排列。
裁判测试程序样例:
#include <stdio.h>
#define N 1000
int arr[N];
/* 对长度为n的数组arr执行冒泡排序 */
void bubbleSort(int arr[], int n);
/* 打印长度为n的数组arr */
void printArray(int arr[], int n);
void swap(int *xp, int *yp) {
int temp = *xp;
*xp = *yp;
*yp = temp;
}
int main() {
int n, i;
scanf("%d", &n);
for (i = 0; i < n; ++i) {
scanf("%d", &arr[i]);
}
bubbleSort(arr, n);
printArray(arr, n);
return 0;
}
/* 打印长度为n的数组arr */
void printArray(int arr[], int n) {
int i;
for (i = 0; i < n; i++) {
printf("%d", arr[i]);
if (i < n - 1) /* 下标0..n-2每个元素后面有个空格 */
printf(" "); /*下标n-1,也就是最后一个元素后面没有空格*/
}
printf("\n"); /* 一行打印完后换行 */
}
/* 你的代码将嵌在这里 */
输入样例:
10
1 19 9 11 4 3 5 8 10 6
输出样例:
1 3 4 5 6 8 9 10 11 19
void bubbleSort(int arr[], int n){
int t,flag=1;
int m=n-1;
while((m>0)&&(flag==1)){
flag=0;
for(int i=0;i<m;i++){
if(arr[i]>arr[i+1]){
flag=1;
t=arr[i];
arr[i]=arr[i+1];
arr[i+1]=t;
}
}
m--;
}
}
6-265 另类堆栈
在栈的顺序存储实现中,另有一种方法是将Top定义为栈顶的上一个位置。请编写程序实现这种定义下堆栈的入栈、出栈操作。如何判断堆栈为空或者满?
函数接口定义:
bool Push( Stack S, ElementType X );
ElementType Pop( Stack S );
其中Stack结构定义如下:
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode {
ElementType *Data; /* 存储元素的数组 */
Position Top; /* 栈顶指针 */
int MaxSize; /* 堆栈最大容量 */
};
typedef PtrToSNode Stack;
注意:如果堆栈已满,Push函数必须输出“Stack Full”并且返回false;如果队列是空的,则Pop函数必须输出“Stack Empty”,并且返回ERROR。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
typedef int ElementType;
typedef enum { push, pop, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode {
ElementType *Data; /* 存储元素的数组 */
Position Top; /* 栈顶指针 */
int MaxSize; /* 堆栈最大容量 */
};
typedef PtrToSNode Stack;
Stack CreateStack( int MaxSize )
{
Stack S = (Stack)malloc(sizeof(struct SNode));
S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
S->Top = 0;
S->MaxSize = MaxSize;
return S;
}
bool Push( Stack S, ElementType X );
ElementType Pop( Stack S );
Operation GetOp(); /* 裁判实现,细节不表 */
void PrintStack( Stack S ); /* 裁判实现,细节不表 */
int main()
{
ElementType X;
Stack S;
int N, done = 0;
scanf("%d", &N);
S = CreateStack(N);
while ( !done ) {
switch( GetOp() ) {
case push:
scanf("%d", &X);
Push(S, X);
break;
case pop:
X = Pop(S);
if ( X!=ERROR ) printf("%d is out\n", X);
break;
case end:
PrintStack(S);
done = 1;
break;
}
}
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
4
Pop
Push 5
Push 4
Push 3
Pop
Pop
Push 2
Push 1
Push 0
Push 10
End
输出样例:
Stack Empty
3 is out
4 is out
Stack Full
0 1 2 5
bool Push( Stack S, ElementType X){
if(S->MaxSize == S->Top){
puts("Stack Full");
return false;
}
S->Data[(S->Top)++]=X;
return 1;
}
ElementType Pop( Stack S ){
if(!S->Top){
puts("Stack Empty");
return ERROR;
}
return S->Data[--(S->Top)];
}
6-270 循环队列入队出队
本题要求实现队列的顺序存储表示,包括入队、出队和取队头操作
函数接口定义:
void EnQueue_seq(SeqQueue squeue, DataType x) ;
void DeQueue_seq(SeqQueue squeue) ;
DataType FrontQueue_seq(SeqQueue squeue) ;
其中,squeue 是操作的队列,x是入队的元素
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
typedef char DataType;
struct Queue
{
int Max;
int f;
int r;
DataType *elem;
};
typedef struct Queue *SeqQueue;
SeqQueue SetNullQueue_seq(int m)
{
SeqQueue squeue;
squeue = (SeqQueue)malloc(sizeof(struct Queue));
if (squeue == NULL)
{
printf("Alloc failure\n");
return NULL;
}
squeue->elem = (char*)malloc(sizeof(DataType)*m);
if (squeue->elem != NULL)
{
squeue->Max = m;
squeue->f = 0;
squeue->r = 0;
return squeue;
}
}
int IsNullQueue_seq(SeqQueue squeue)
{
return (squeue->f == squeue->r);
}
void EnQueue_seq(SeqQueue squeue, DataType x)
{
@@
}
void DeQueue_seq(SeqQueue squeue)
{
@@
}
DataType FrontQueue_seq(SeqQueue squeue)
{
@@
}
int main()
{
char ch;
SeqQueue queueA = SetNullQueue_seq(5);
ch = getchar();
while (ch != '#')
{
EnQueue_seq(queueA, ch);
ch = getchar();
}
DeQueue_seq(queueA);
printf("%c" ,FrontQueue_seq(queueA));
return 0;
}
输入样例:
ABCD#
输出样例:
B
输入样例:
A#
输出样例:
It is empty queue!
输入样例:
ABCDEF#
输出样例:
It is FULL Queue!It is FULL Queue!B
void EnQueue_seq(SeqQueue squeue, DataType x) {
if((squeue->r+1)%squeue->Max!=squeue->f){
squeue->r=(squeue->r+1)%squeue->Max;
squeue->elem[squeue->r]=x;
}
else printf("It is FULL Queue!");
}
void DeQueue_seq(SeqQueue squeue){
if(squeue->r!=squeue->f){
squeue->f=(squeue->f+1)%squeue->Max;
}
}
DataType FrontQueue_seq(SeqQueue squeue){
if(squeue->r==squeue->f)printf("It is empty queue!");
return squeue->elem[(squeue->f+1)%squeue->Max];
}
6-14 另类循环队列
如果用一个循环数组表示队列,并且只设队列头指针Front,不设尾指针Rear,而是另设Count记录队列中元素个数。请编写算法实现队列的入队和出队操作。
函数接口定义:
bool AddQ( Queue Q, ElementType X );
ElementType DeleteQ( Queue Q );
其中Queue结构定义如下:
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode {
ElementType *Data; /* 存储元素的数组 */
Position Front; /* 队列的头指针 */
int Count; /* 队列中元素个数 */
int MaxSize; /* 队列最大容量 */
};
typedef PtrToQNode Queue;
注意:如果队列已满,AddQ函数必须输出“Queue Full”并且返回false;如果队列是空的,则DeleteQ函数必须输出“Queue Empty”,并且返回ERROR。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
typedef int ElementType;
typedef enum { addq, delq, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode {
ElementType *Data; /* 存储元素的数组 */
Position Front; /* 队列的头、尾指针 */
int Count; /* 队列中元素个数 */
int MaxSize; /* 队列最大容量 */
};
typedef PtrToQNode Queue;
Queue CreateQueue( int MaxSize )
{
Queue Q = (Queue)malloc(sizeof(struct QNode));
Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
Q->Front = 0;
Q->Count = 0;
Q->MaxSize = MaxSize;
return Q;
}
bool AddQ( Queue Q, ElementType X );
ElementType DeleteQ( Queue Q );
Operation GetOp(); /* 裁判实现,细节不表 */
int main()
{
ElementType X;
Queue Q;
int N, done = 0;
scanf("%d", &N);
Q = CreateQueue(N);
while ( !done ) {
switch( GetOp() ) {
case addq:
scanf("%d", &X);
AddQ(Q, X);
break;
case delq:
X = DeleteQ(Q);
if ( X!=ERROR ) printf("%d is out\n", X);
break;
case end:
while (Q->Count) printf("%d ", DeleteQ(Q));
done = 1;
break;
}
}
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
4
Del
Add 5
Add 4
Add 3
Del
Del
Add 2
Add 1
Add 0
Add 10
End
输出样例:
Queue Empty
5 is out
4 is out
Queue Full
3 2 1 0
bool AddQ(Queue Q,ElementType X)
{
//判断队列是否满
if(Q->Count>=Q->MaxSize)
{
printf("Queue Full\n");
return false;
}
Q->Data[(Q->Front+Q->Count)%Q->MaxSize]=X;
//元素个数增加
Q->Count++;
return true;
}
ElementType DeleteQ(Queue Q)
{
//判断队列是否为空
if(Q->Count==0)
{
printf("Queue Empty\n");
return ERROR;
}
ElementType X = Q->Data[Q->Front];
//改变队头指针
Q->Front = (Q->Front+1)%Q->MaxSize;
//改变元素数量
Q->Count--;
return X;
}