关于查找
代码实现
#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
函数,从而在递归调用中正确地更新右子树。同样的逻辑也适用于左子树的更新。