数据结构复习题——函数题

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;
}
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、查找 1. 算法设计 :已知n元顺序表a0, a1, … , an-1按关键字递增有序存储。给定关键字值key,编写算法用对分查找求下标i,满足ai-1<key且aikey。 2. 编程:输入n个两两互不相等的整数,以这些整数为关键字建立平衡的二叉排序树。判断该二叉树是否为平衡的,输出判断结果;输出该二叉树的中序遍历关键字访问次序。 3. 从空树起连续插入以下20个关键字构建m=4的B-树。 50, 15, 09, 18, 03, 85, 33, 72, 48, 22, 91, 88, 11, 99, 06, 56, 68, 77, 43, 36。 4. 16个关键字组成的5阶B-树如下图所示,请按关键 字递减的次序删除所有结点至空树,画出每删除1个关键字后得到B-树,直至空树。 5. 12个关键字如本电子教案例1所示,设H(K)=K mod 13,地址空间范围0~15,用二次探测再散列解决冲突。画出哈希表;若各元素等概率查找,求成功查找时的平均查找长度。 二、内部排序 1.算法设计与分析:将直接插入排序的内循环改造为使用对分查找实现元素插入,请写出基于对分查找的插入排序算法并给出其时间复杂度分析。 2.算法设计:将教案给出的非递归直接插入排序和冒泡排序算法用递归算法实现。 3.算法设计:带附加头结点单链表将各数据结点按关键字升序连接。 4.编程:键盘输入n个无符号整数,用链式基数排序实现由小到大排序,输出排序结果。 提示:对于C语言32bit宽的unsigned类型,可以采用16进制形式来实现基数排序,即32bit共有8个16进制位,每个16进制位进行一趟分配和收集,共8趟。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值