C++查找实验

1.顺序查找

运行结果如图所示:
在这里插入图片描述
seqSearch.cpp

#include <stdio.h>
//定义表中最多记录个数
#define MAXL 100
typedef int KeyType;
typedef char InfoType[10];

typedef struct {
    //KeyType为关键字的数据类型
    KeyType key;
    //其他数据
    InfoType data;
} NodeType;
//顺序表类型
typedef NodeType SeqList[MAXL];

//顺序查找算法
int SeqSearch(SeqList R, int n, KeyType k) {
    int index = 0;
    for (int i = 0; i < n; i++) {
        if (R[i].key == k) {
            index = i;
        }
        printf("%d ", R[i].key);
    }
    return index;
}

int main() {
    SeqList R;
    int n = 10;
    KeyType k = 5;

    int a[] = {3, 6, 2, 10, 1, 8, 5, 7, 4, 9};
    int i;
    //建立顺序表
    for (i = 0; i < n; i++) {
        R[i].key = a[i];
    }
    printf("\n");

    if ((i = SeqSearch(R, n, k)) != -1) {
        printf("\n元素%d的位置是%d\n", k, i);
    } else {
        printf("\n元素%d不在表中\n", k);
    }
    printf("\n");
}

运行截图
在这里插入图片描述

2. 折半查找

运行结果如图所示:
在这里插入图片描述
binSearch.cpp

#include <stdio.h>
//定义表中最多记录个数
#define MAXL 100                    

typedef int KeyType;
typedef char InfoType[10];

typedef struct {
    //KeyType为关键字的数据类型
    KeyType key;
    //其他数据
    InfoType data;
} NodeType;

//顺序表类型
typedef NodeType SeqList[MAXL];

//二分查找算法
int BinSearch(SeqList R, int n, KeyType k) {
    int low = 1;
    int high = n;
    int count = 1;
    int res = 0;
    while (low <= high && count < 4) {
        int mid = (low + high) / 2;
        if (count < 3) {
            printf("第%d次查找:在[%d,%d]中查找到元素R[%d]:%d\n", count, low - 1, high - 1, mid - 1, R[mid - 1].key);
        }
        if (k == R[mid].key) {
            res = mid;
            high = n;
            low = R[mid].key;
            count++;
            printf("第%d次查找:在[%d,%d]中查找到元素R[%d]:%d\n", count, low - 1, high - 1, res, R[res].key);
        } else if (k < R[mid].key) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
        count++;
    }
    return res;
}

int main() {
    SeqList R;
    KeyType k = 9;
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, i, n = 10;
    //建立顺序表
    for (i = 0; i < n; i++) {
        R[i].key = a[i];
    }
    printf("\n");

    if ((i = BinSearch(R, n, k)) != -1) {
        printf("元素%d的位置是%d\n", k, i);
    } else {
        printf("元素%d不在表中\n", k);
    }
    printf("\n");
}

运行截图
在这里插入图片描述

3. 二叉排序树的基本运算

运行结果如图所示:
在这里插入图片描述
BST.cpp

#include <stdio.h>
#include <malloc.h>

#define MaxSize 100
//定义关键字类型
typedef int KeyType;
typedef char InfoType;
//记录类型
typedef struct node {
    //关键字项
    KeyType key;
    //其他数据域
    InfoType data;
    //左右孩子指针
    struct node *lchild;
    struct node *rchild;
} BSTNode;
//全局变量,用于存放路径
int path[MaxSize];

//函数说明
void DispBST(BSTNode *b);

//在以*p为根结点的BST中插入一个关键字为k的结点
int InsertBST(BSTNode *&p, KeyType k) {
    //原树为空, 新插入的记录为根结点
    if (p == nullptr) {
        p = (BSTNode *) malloc(sizeof(BSTNode));
        p->key = k;
        p->lchild = p->rchild = nullptr;
        return 1;
    } else if (k == p->key) {
        return 0;
    } else if (k < p->key) {
        //递归调用,插入到*p的左子树中
        return InsertBST(p->lchild, k);
    } else {
        //递归调用,插入到*p的右子树中
        return InsertBST(p->rchild, k);
    }
}

//由数组A中的关键字建立一棵二叉排序树
BSTNode *CreatBST(KeyType A[], int n) {
    //初始时bt为空树
    BSTNode *bt = nullptr;
    int i = 0;
    while (i < n)
        //将A[i]插入二叉排序树T中
        if (InsertBST(bt, A[i]) == 1) {
            printf("    第%d步,插入%d: ", i + 1, A[i]);
            DispBST(bt);
            printf("\n");
            i++;
        }
    //返回建立的二叉排序树的根指针
    return bt;
}

//以括号表示法输出二叉排序树bt
void DispBST(BSTNode *bt) {
    if (bt != nullptr) {
        printf("%d", bt->key);
        if (bt->lchild != nullptr || bt->rchild != nullptr) {
            printf("(");
            DispBST(bt->lchild);
            if (bt->rchild != nullptr) {
                printf(",");
            }
            DispBST(bt->rchild);
            printf(")");
        }
    }
}

//以递归方式输出从根结点到查找到的结点的路径
int SearchBST(BSTNode *bt, KeyType k) {
    printf("%d ", bt->key);
    if (k == bt->key) {
        return bt->key;
    } else if (k < bt->key) {
        return SearchBST(bt->lchild, k);
    } else if (k > bt->key) {
        return SearchBST(bt->rchild, k);
    }
}

//当被删*p结点有左右子树时的删除过程
void Delete1(BSTNode *p, BSTNode *&r) {
    BSTNode *s;
    BSTNode *q;
    q = p;
    s = p->lchild;
    while (s->rchild) {
        q = s;
        s = s->rchild;
    }
    p->key = s->key;
    if (q != p) {
        q->rchild = s->lchild;
    } else {
        q->lchild = s->lchild;
    }
    delete s;
    /*
    if (r->rchild != nullptr)
        Delete1(p, p->lchild);    //递归找最右下结点
    else                        //找到了最右下结点*r
    {
        p->key = r->key;            //将*r的关键字值赋给*p
        q = r;
        r = r->lchild;            //将*r的双亲结点的右孩子结点改为*r的左孩子结点
        free(q);                //释放原*r的空间
    }
     */
}

//从二叉排序树中删除*p结点
void Delete(BSTNode *&p) {
    BSTNode *q;
    //*p结点没有右子树的情况
    if (p->rchild == nullptr) {
        q = p;
        p = p->lchild;
        free(q);
    } else if (p->lchild == nullptr) { //*p结点没有左子树的情况
        q = p;
        p = p->rchild;
        free(q);
    } else { //*p结点既有左子树又有右子树的情况
        Delete1(p, p->lchild);
    }
}

//在bt中删除关键字为k的结点
int DeleteBST(BSTNode *&bt, KeyType k) {
    //空树删除失败
    if (bt == nullptr) {
        return 0;
    } else {
        //小于说明在左边
        if (k < bt->key) {
            //递归在左子树中删除关键字为k的结点
            return DeleteBST(bt->lchild, k);
        } else if (k > bt->key) {
            //递归在右子树中删除关键字为k的结点
            return DeleteBST(bt->rchild, k);
        } else { //k=bt->key的情况
            //调用Delete(bt)函数删除*bt结点
            Delete(bt);
            return 1;
        }
    }
}

int flag = true;
int prev=-256;
bool isBinaryTree(BSTNode *&bt) {
    if (bt->lchild != nullptr && flag) {
        isBinaryTree(bt->lchild);
    }
    if(bt->data<prev){
        flag= false;
    }
    if(bt->rchild!= nullptr&&flag){
        isBinaryTree(bt->rchild);
    }
    return flag;
}


//predt为全局变量,保存当前结点中序前趋的值,初值为-∞
KeyType predt = -32767;

int main() {
    BSTNode *bt;
    KeyType k = 6;
    int a[] = {4, 9, 0, 1, 8, 6, 3, 5, 2, 7}, n = 10;
    /*
    4
   / \
  0   9
   \ /
   1 8
   \  /
   3 6
  /  /\
  2  5 7
     */
    printf(" 创建一棵BST树:");
    printf("\n");
    bt = CreatBST(a, n);

    printf("\n\n BST: ");
    DispBST(bt);
    printf("\n\n");

    printf(" 查找%d关键字: ", k);
    SearchBST(bt, k);
    printf("\n\n");

    printf(" 是否是二叉排序树: \n");
    if(isBinaryTree(bt)){
        printf(" 是二叉排序树 \n");
    } else{
        printf(" 不是二叉排序树 \n");
    }

    printf("\n\n 删除操作:\n");
    printf("   原BST: ");
    DispBST(bt);
    printf("\n");

    printf("   删除结点4: ");
    DeleteBST(bt, 4);
    DispBST(bt);
    printf("\n");

    printf("   删除结点5: ");
    DeleteBST(bt, 5);

    DispBST(bt);
    printf("\n\n");
}

运行截图
在这里插入图片描述

4.自行设计一个算法,判别给定的一棵二叉树是否为二叉排序树

根据第三题结构,添加如下算法代码

#include <stdio.h>
#include <malloc.h>

#define MaxSize 100
//定义关键字类型
typedef int KeyType;
typedef char InfoType;
//记录类型
typedef struct node {
    //关键字项
    KeyType key;
    //其他数据域
    InfoType data;
    //左右孩子指针
    struct node *lchild;
    struct node *rchild;
} BSTNode;
//全局变量,用于存放路径
int path[MaxSize];

//函数说明
void DispBST(BSTNode *b);

//在以*p为根结点的BST中插入一个关键字为k的结点
int InsertBST(BSTNode *&p, KeyType k) {
    //原树为空, 新插入的记录为根结点
    if (p == nullptr) {
        p = (BSTNode *) malloc(sizeof(BSTNode));
        p->key = k;
        p->lchild = p->rchild = nullptr;
        return 1;
    } else if (k == p->key) {
        return 0;
    } else if (k < p->key) {
        //递归调用,插入到*p的左子树中
        return InsertBST(p->lchild, k);
    } else {
        //递归调用,插入到*p的右子树中
        return InsertBST(p->rchild, k);
    }
}

//由数组A中的关键字建立一棵二叉排序树
BSTNode *CreatBST(KeyType A[], int n) {
    //初始时bt为空树
    BSTNode *bt = nullptr;
    int i = 0;
    while (i < n)
        //将A[i]插入二叉排序树T中
        if (InsertBST(bt, A[i]) == 1) {
            printf("    第%d步,插入%d: ", i + 1, A[i]);
            DispBST(bt);
            printf("\n");
            i++;
        }
    //返回建立的二叉排序树的根指针
    return bt;
}

//以括号表示法输出二叉排序树bt
void DispBST(BSTNode *bt) {
    if (bt != nullptr) {
        printf("%d", bt->key);
        if (bt->lchild != nullptr || bt->rchild != nullptr) {
            printf("(");
            DispBST(bt->lchild);
            if (bt->rchild != nullptr) {
                printf(",");
            }
            DispBST(bt->rchild);
            printf(")");
        }
    }
}

int flag = true;
int prev=-256;
bool isBinaryTree(BSTNode *&bt) {
    if (bt->lchild != nullptr && flag) {
        isBinaryTree(bt->lchild);
    }
    if(bt->data<prev){
        flag= false;
    }
    if(bt->rchild!= nullptr&&flag){
        isBinaryTree(bt->rchild);
    }
    return flag;
}


//predt为全局变量,保存当前结点中序前趋的值,初值为-∞
KeyType predt = -32767;

int main() {
    BSTNode *bt;
    KeyType k = 6;
    int a[] = {4, 9, 0, 1, 8, 6, 3, 5, 2, 7}, n = 10;
    /*
    4
   / \
  0   9
   \ /
   1 8
   \  /
   3 6
  /  /\
  2  5 7
     */
    printf(" 创建一棵BST树:");
    printf("\n");
    bt = CreatBST(a, n);
    printf("\n");
    printf(" 是否是二叉排序树: \n");
    if(isBinaryTree(bt)){
        printf(" 是二叉排序树 \n");
    } else{
        printf(" 不是二叉排序树 \n");
    }
} 

运行截图
在这里插入图片描述

数据结构查找实验代码 (1) 对下列数据表,分别采用二分查找算法实现查找,给出查找过程依次所比较的元素(的下标),并以二分查找的判定树来解释。 第一组测试数据: 数据表为 (1,2,3,4,6,7,8,9,10,11,12,13,17,18,19,20,24,25,26,30,35,40,45,50,,100) 查找的元素分别为: 2,8,20, 30,50,5,15,33,110 第二组数据: 数据表为 (2,3,5,7,8,10,12,15,18,20,22,25,30,35,40,45,50,55,60, 80,100) 查找的元素分别为: 22,8,80,3,100,1,13,120 (2) 设计出在二叉排序树中插入结点的算法,在此基础上实现构建二叉排序树的算法。 测试数据:构建二叉排序树的输入序列如下: 第一组数据: 100,150,120,50,70,60,80,170,180,160,110,30,40,35,175 第二组数据: 100,70,60,80,150,120,50,160,30,40,170,180,175,35 (3) 设计算法在二叉排序树中查找指定值的结点。 测试数据:在任务中第一组测试数据所构造的二叉排序树中,分别查找下列元素: 150,70,160,190,10,55,175 (4) 设计算法在二叉排序树中删除特定值的结点。 测试数据:在任务(1)中第一组测试数据所构造的二叉排序树中,分别删除下列元素:30,150,100 (5) 已知整型数组A[1..26]递增有序,设计算法以构造一棵平衡的二叉排序树来存放该数组中的所有元素。 测试数据:数组元素分别为: 第一组数据: (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26) 第二组数据: (1,3,6,10,15,21,28,36,45,55,66,78,91,105,120,136,153,171,190,210,231,253,277,302,328)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值