C语言实现顺序查找,折半查找,二叉排序树

关于查找

 代码实现

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define maxsize 5
typedef int Element;
typedef struct SSTable{
	Element *elem;
	int len;
}SSTable;

SSTable* Create(int m){
	SSTable* p = (SSTable*)malloc(sizeof(SSTable));
	if(p == NULL){
		return NULL;
	}else{
		p->elem = (Element*)malloc(sizeof(Element));
		if(p->elem){
			p->len = 0;
			return p;
		}else{
			return NULL;
		}
	}
}

void Writer(SSTable* p){
	printf("请输入查找表长度:");
	scanf("%d",&(p->len));
	printf("请输入%d个数据:",p->len);
	for(int i = 1;i <= p->len;i++){
		scanf("%d",&p->elem[i]);
	}
}

void Print(SSTable p){
	for(int i = 1;i <= p.len;i++){
		printf("%d  ",p.elem[i]);
	}
}
//顺序查找
int Search(SSTable p,Element key){
	p.elem[0] = key;//哨兵
	int i;
	for(i = p.len;p.elem[i] != key;--i);//从后往前找
	return i;//若表中不存在关键字为key的元素,将查找到i为0时退出循环
}

//折半查找(仅适用于有序的顺序表)非递归
int Binary_Search(SSTable p,Element key){
	int low = 1,high = p.len,mid;//因为顺序表从位置为1的地方开始存储
	while(low <= high){
		mid = (low + high)/2;
		if(p.elem[mid] == key){
			return 1;
		}else if(p.elem[mid] > key){
			high = mid - 1;
		}else if(p.elem[mid] < key){
			low = mid + 1;
		}
	}
	return -1;
}

//折半查找 递归

int BinarySearch(SSTable p,Element key,int low,int high){
	if(low > high){
		return 0;
	}
	int mid = (low + high)/2;
	if(p.elem[mid] == key){
		return 1;
	}
	else if(p.elem[mid] > key){
				BinarySearch(p,key,low,mid-1);
	}
	else if(p.elem[mid] < key){
				BinarySearch(p,key,mid+1,high);
	}
}

int main(){
	SSTable* p = Create(9);
	Writer(p);
	Print(*p);
	printf("\n");
	int re = Search(*p,5);
	if(re != 0)
		printf("顺序查找找到了\n");
	re = Binary_Search(*p,5);
	if(re != 0)
		printf("非递归的折半查找找到了\n");
	re = BinarySearch(*p,5,1,6);
	if(re != 0)
		printf("递归的折半查找找到了\n");
	return 0;
}

 关于二叉排序树

代码实现

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

typedef int Element;

// 二叉排序树的定义
typedef struct TNode {
    Element data;
    struct TNode* left;
    struct TNode* right;
} TNode, *Tree;

// 插入操作
void BST_Insert(Tree* tr, Element key) {
    if (*tr == NULL) {
        *tr = (TNode*)malloc(sizeof(TNode));
        (*tr)->data = key;
        (*tr)->left = (*tr)->right = NULL;
    } else if (key == (*tr)->data) {
        return;
    } else if (key > (*tr)->data) {
        BST_Insert(&((*tr)->right), key);
    } else if (key < (*tr)->data) {
        BST_Insert(&((*tr)->left), key);
    }
}

// 构造二叉排序树
void Create(Tree* tr, Element str[], int n) {
    int i = 0;
    while (i < n) {
        BST_Insert(tr, str[i]);
        i++;
    }
}

// 中序递归(二叉排序树的中序遍历为有序)
void InOrder(Tree tr) {
    if (tr) {
        InOrder(tr->left);
        printf("%d ", tr->data);
        InOrder(tr->right);
    }
}

// 非递归查找算法
TNode* BST_Search(Tree tr, Element key) {
    while (tr != NULL && key != tr->data) {
        if (key > tr->data)
            tr = tr->right;
        else
            tr = tr->left;
    }
    return tr;
}

int main() {
    Tree tr = NULL; // 将tr初始化为空指针
    Element str[] = {4, 6, 8, 3, 2, 9, 1, 0, 5}; // 声明并初始化整数数组
    int n = sizeof(str) / sizeof(str[0]); // 计算数组的长度
    Create(&tr, str, n);
    InOrder(tr);
    printf("\n");
    TNode* p = BST_Search(tr, 5);
    if (p)
        printf("结点存在");
    return 0;
}

注意: 

&((*tr)->right)是一个指针的指针的表达式,用于获取指向右子树指针的指针。在函数BST_Insert中,参数tr是一个指向指针的指针(Tree*)。为了访问指针tr所指向的结构体中的右子树指针,需要使用间接访问运算符->来解引用tr一次,并获取右子树指针的地址。

具体来说,(*tr)->right表示解引用tr一次,得到指向结构体的指针,然后使用.运算符访问该结构体中的右子树指针。而&((*tr)->right)则表示获取右子树指针的地址。

通过传递&((*tr)->right)作为参数,我们可以将指向右子树指针的指针传递给BST_Insert函数,从而在递归调用中正确地更新右子树。同样的逻辑也适用于左子树的更新。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,以下是顺序查找折半查找二叉排序树和平衡二叉树的 C 语言实现顺序查找: ```c #include <stdio.h> int sequential_search(int arr[], int n, int target) { for (int i = 0; i < n; i++) { if (arr[i] == target) { return i; } } return -1; } int main() { int arr[] = {3, 7, 1, 9, 2, 5}; int n = sizeof(arr) / sizeof(int); int target = 9; int index = sequential_search(arr, n, target); if (index == -1) { printf("未找到 %d\n", target); } else { printf("找到 %d,下标为 %d\n", target, index); } return 0; } ``` 折半查找: ```c #include <stdio.h> int binary_search(int arr[], int n, int target) { int left = 0, right = n - 1; while (left <= right) { int mid = (left + right) / 2; if (arr[mid] == target) { return mid; } else if (arr[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; } int main() { int arr[] = {1, 2, 3, 5, 7, 9}; int n = sizeof(arr) / sizeof(int); int target = 5; int index = binary_search(arr, n, target); if (index == -1) { printf("未找到 %d\n", target); } else { printf("找到 %d,下标为 %d\n", target, index); } return 0; } ``` 二叉排序树: ```c #include <stdio.h> #include <stdlib.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; void insert(struct TreeNode **root, int val) { if (*root == NULL) { *root = (struct TreeNode *) malloc(sizeof(struct TreeNode)); (*root)->val = val; (*root)->left = NULL; (*root)->right = NULL; return; } if (val < (*root)->val) { insert(&((*root)->left), val); } else { insert(&((*root)->right), val); } } void inorder_traversal(struct TreeNode *root) { if (root == NULL) { return; } inorder_traversal(root->left); printf("%d ", root->val); inorder_traversal(root->right); } int main() { struct TreeNode *root = NULL; insert(&root, 3); insert(&root, 1); insert(&root, 5); insert(&root, 2); insert(&root, 4); inorder_traversal(root); return 0; } ``` 平衡二叉树: ```c #include <stdio.h> #include <stdlib.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; int height; // 节点高度 }; struct TreeNode *new_node(int val) { struct TreeNode *node = (struct TreeNode *) malloc(sizeof(struct TreeNode)); node->val = val; node->left = NULL; node->right = NULL; node->height = 1; return node; } int max(int a, int b) { return a > b ? a : b; } int get_height(struct TreeNode *node) { if (node == NULL) { return 0; } return node->height; } int get_balance_factor(struct TreeNode *node) { if (node == NULL) { return 0; } return get_height(node->left) - get_height(node->right); } struct TreeNode *left_rotate(struct TreeNode *node) { struct TreeNode *new_root = node->right; node->right = new_root->left; new_root->left = node; node->height = 1 + max(get_height(node->left), get_height(node->right)); new_root->height = 1 + max(get_height(new_root->left), get_height(new_root->right)); return new_root; } struct TreeNode *right_rotate(struct TreeNode *node) { struct TreeNode *new_root = node->left; node->left = new_root->right; new_root->right = node; node->height = 1 + max(get_height(node->left), get_height(node->right)); new_root->height = 1 + max(get_height(new_root->left), get_height(new_root->right)); return new_root; } void insert(struct TreeNode **root, int val) { if (*root == NULL) { *root = new_node(val); return; } if (val < (*root)->val) { insert(&((*root)->left), val); } else { insert(&((*root)->right), val); } (*root)->height = 1 + max(get_height((*root)->left), get_height((*root)->right)); int balance_factor = get_balance_factor(*root); if (balance_factor > 1 && val < ((*root)->left)->val) { // LL *root = right_rotate(*root); } else if (balance_factor > 1 && val > ((*root)->left)->val) { // LR (*root)->left = left_rotate((*root)->left); *root = right_rotate(*root); } else if (balance_factor < -1 && val > ((*root)->right)->val) { // RR *root = left_rotate(*root); } else if (balance_factor < -1 && val < ((*root)->right)->val) { // RL (*root)->right = right_rotate((*root)->right); *root = left_rotate(*root); } } void inorder_traversal(struct TreeNode *root) { if (root == NULL) { return; } inorder_traversal(root->left); printf("%d ", root->val); inorder_traversal(root->right); } int main() { struct TreeNode *root = NULL; insert(&root, 3); insert(&root, 1); insert(&root, 5); insert(&root, 2); insert(&root, 4); inorder_traversal(root); return 0; } ``` 以上四种算法的时间复杂度分别为: - 顺序查找:最坏时间复杂度为 O(n),平均时间复杂度为 O(n); - 折半查找:最坏时间复杂度为 O(log n),平均时间复杂度为 O(log n); - 二叉排序树:最坏时间复杂度为 O(n),平均时间复杂度为 O(log n); - 平衡二叉树:最坏时间复杂度为 O(log n),平均时间复杂度为 O(log n)。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摩尔曼斯克的海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值