第七章 查找

1.顺序查找

#include <stdio.h>
#include <stdlib.h>
# include <malloc.h>        //malloc  free函数

#define Maxsize 50

//动态顺序表
typedef struct{
    int *data;
    int length,max;
}sqlist2;

void init_list2(sqlist2* lt){
    if (lt !=NULL){
        lt->data =(int *)malloc(sizeof(int)*Maxsize); //申请空间
        lt->length=0;  //防止脏数据
        lt->max =Maxsize;
    }
}
void create_list2(sqlist2 * lt, int num){
    printf("请输入元素:");
    int i;
    for( i =1; i<num;i++){
        scanf("%d",&lt->data[i]);
    }
    lt->length+=num;
}
void extendplace(sqlist2 * lt){
    int n;
    printf("请输入要扩容的数目:");
    scanf("%d",&n);

//    int *p=lt->data; //辅助空间  方式一
      int *p; //辅助空间
      p=lt->data;

    lt->data =(int*)malloc((lt->max + n)*sizeof(int));
    int i;
    for(i=0;i<lt->length;i++){  //将原来顺序表数据复制到新空间
        lt->data[i]=p[i];
    }
    lt->max +=n;  //扩容n个
    free(p);
}
void print_list2(sqlist2 lt){
    int i;
    if (lt.length!=0){
        printf("当前表中元素有:");
        for( i=0;i<lt.length;i++)
        {
            printf("%d\t",lt.data[i]);
        }
        printf(" 表长%d:\n",lt.length);
    }
    else{
        printf("当前为空表!");
    }
    printf("\n");
}

int search(sqlist2 st,int key){ //查找key
    st.data[0] =key;    //哨兵 下标0不实际存储值便于查找
    int i;
    for( i=st.length;key!=st.data[i];i--);
    printf("%d",i);
    return i;	// 0 表示查找失败, 其余数字表示第几个数匹配成功
}
int main(){
    int num;
    printf("输入创建表长:");
    scanf("%d",&num);
    int n;
    sqlist2 lt;  //申明一个动态顺序表
    init_list2(&lt);
    create_list2(&lt,num);
    search(lt,6);
    print_list2(lt);
}

2.折半查找

#include <stdio.h>
#include <stdlib.h>
# include <malloc.h>        //malloc  free函数
#define Maxsize 50
/*
    仅适用于 有序顺序表
*/
//动态顺序表
typedef struct{
    int *data;
    int length,max;
}sqlist2;

void init_list2(sqlist2* lt){
    if (lt !=NULL){
        lt->data =(int *)malloc(sizeof(int)*Maxsize); //申请空间
        lt->length=0;  //防止脏数据
        lt->max =Maxsize;
    }
}
void create_list2(sqlist2 * lt, int num){
    printf("请输入元素:");
    int i;
    for( i =0; i<num;i++){
        scanf("%d",&lt->data[i]);
    }
    lt->length+=num;
}
void extendplace(sqlist2 * lt){
    int n;
    printf("请输入要扩容的数目:");
    scanf("%d",&n);

//    int *p=lt->data; //辅助空间  方式一
      int *p; //辅助空间
      p=lt->data;

    lt->data =(int*)malloc((lt->max + n)*sizeof(int));
    int i;
    for(i=0;i<lt->length;i++){  //将原来顺序表数据复制到新空间
        lt->data[i]=p[i];
    }
    lt->max +=n;  //扩容n个
    free(p);
}
void print_list2(sqlist2 lt){
    int i;
    if (lt.length!=0){
        printf("当前表中元素有:");
        for( i=0;i<lt.length;i++)
        {
            printf("%d\t",lt.data[i]);
        }
        printf(" 表长%d:\n",lt.length);
    }
    else{
        printf("当前为空表!");
    }
    printf("\n");

}

int search(sqlist2 lt,int key){     //折半查找 查找key
    int low=0,high=lt.length-1,mid;
    while(low <= high){
        mid =(low+high)/2;
        if(lt.data[mid] == key)
            return mid;
        else if(lt.data[mid] > key)
            high= mid-1;
        else
            low=mid+1;
    }
    return -1;
}

int main(){
    int num;
    printf("输入创建表长:");
    scanf("%d",&num);
    int n;
    sqlist2 lt;  //申明一个动态顺序表
    init_list2(&lt);
    create_list2(&lt,num);
    printf("%d",search(lt,3));      //输出如果结果小于0 失败
    print_list2(lt);
}

习题

3.6判定是否 二叉排序树

bool isBSTUtil(Tree node, int* prev) {
    // 递归终止条件:空树是 BST
    if (node == NULL)
        return true;
    // 递归检查左子树  // 检查当前节点的值是否大于前一个节点的值
    if (!isBSTUtil(node->left, prev) || node->data <= *prev)
        return false;
    // 更新前一个节点的值
    *prev = node->data;
    // 递归检查右子树
    return isBSTUtil(node->right, prev);
}

3.8判定平衡二叉树

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

// 定义二叉树节点结构体
typedef struct TreeNode {
    int data;
    struct TreeNode* left, *right;
} TreeNode, *Tree;

// 计算树的高度
int height(Tree root) {
    if (root == NULL) {
        return 0;
    }
    int left_height = height(root->left);
    int right_height = height(root->right);
    return (left_height > right_height) ? (left_height + 1) : (right_height + 1);
}

// 判断是否是平衡二叉树
bool isBalanced(Tree root) {
    if (root == NULL) {
        return true; // 空树是平衡二叉树
    }
    int left_height = height(root->left);
    int right_height = height(root->right);
    // 检查当前节点是否满足平衡条件
    if (abs(left_height - right_height) <= 1 &&
        isBalanced(root->left) &&
        isBalanced(root->right)) {
        return true;
    }

    return false;
}
/*
abs 函数接受一个整数作为参数,并返回该整数的绝对值,
即如果参数为正数,则返回参数本身;如果参数为负数,则返回其相反数(去掉负号)。
绝对值函数的返回值始终是非负整数。
*/
int main() {
    Tree root = (Tree)malloc(sizeof(TreeNode));
    root->data = 1;
    root->left = (Tree)malloc(sizeof(TreeNode));
    root->left->data = 2;
    root->left->left = root->left->right = NULL;
    root->right = (Tree)malloc(sizeof(TreeNode));
    root->right->data = 3;
    root->right->left = root->right->right = NULL;

    if (isBalanced(root)) {
        printf("是平衡二叉树 (Balanced Binary Tree)。\n");
    } else {
        printf("不是平衡二叉树 (Balanced Binary Tree)。\n");
    }
    return 0;
}

3.10 二叉排序树 从大到小输出不小于k关键字

#include <stdio.h>
#include <stdlib.h>
// 定义二叉树节点结构体
typedef struct TreeNode {
    int data;
    struct TreeNode* left, *right;
} TreeNode, *Tree;

// 中序遍历的变种,从大到小输出
void reverseInOrder(Tree root, int k) {
    if (root == NULL)
        return;
    // 遍历右子树
    reverseInOrder(root->right, k);

    // 输出节点值大于等于 k 的节点
    if (root->data >= k)
        printf("%d ", root->data);

    // 遍历左子树
    reverseInOrder(root->left, k);
}

// 插入新节点到二叉排序树
Tree insert(Tree root, int data) {
    if (root == NULL) {
        Tree newNode = (Tree)malloc(sizeof(TreeNode));
        newNode->data = data;
        newNode->left = newNode->right = NULL;
        return newNode;
    }
    if (data < root->data) {
        root->left = insert(root->left, data);
    } else if (data > root->data) {
        root->right = insert(root->right, data);
    }
    return root;
}

// 打印节点
void printTree(Tree root) {
    if (root == NULL) {
        return;
    }
    printTree(root->left);
    printf("%d ", root->data);
    printTree(root->right);
}

int main() {
    Tree root = NULL;
    int k = 3; // 用于过滤节点的关键字
    // 插入节点到二叉排序树
    int values[] = {5, 2, 8, 1, 3, 7, 9};
    for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
        root = insert(root, values[i]);
    }

    // 从大到小输出不小于 k 的节点
    reverseInOrder(root, k);
    printf("\n");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值