1.顺序查找,折半查找,二叉排序树操作定义
SeqSearch.h
#include<stdio.h>
#define ARRAYLEN 8
int source[]={69, 65, 90, 37, 92, 6, 28, 54}; //静态查找表
int source1[ARRAYLEN + 1]={69, 65, 90, 37, 92, 6, 28, 54}; //改进顺序查找算法使用的静态查找表
int source2[]={6, 12, 28, 37, 54, 65, 69, 83}; //折半查找算法使用的静态查找表
//int source3[12]={54, 90, 6, 69, 12, 37, 92, 28, 65, 83, 91, 94};
int source3[2]={92, 12};
/*******************顺序查找start*********************/
/*
优点:对静态查找表数据顺序没有要求;若需创建动态查找表,可方便地将查找不成功数据添加到表的末尾
缺点:速度慢,复杂度为O(n)
*/
//功能:顺序查找
int SeqSearch(int s[], int n, int key){
int i;
for(i=0; i<n && s[i]!=key; i++) //循环查找关键字
;
if(i<n)
return i;
else
return -1;
}
//功能:改进的顺序查找方法(在创建静态查找表时,在该表的末端增加一个空的单元,用来保存查找的关键字;保证查找表中总能找到关键字)
int SeqSearch1(int s[], int n, int key){
int i;
for(i=0; s[i]!=key; i++) //减少比较次数
;
if(i<n)
return i;
else
return -1;
}
/*******************顺序查找end*********************/
/*******************折半查找start*********************/
/*
优点:查找速度快O(nlogn)
缺点:1)静态查找表必须是有序的,
2)将查找不成功关键字数据添加到查找表中,需要大量的移动操作
*/
//功能:顺序查找
int BinarySearch(int s[], int n, int key){
int left, mid, right;
left = 0;
right = n-1;
while(left <= right){
mid = (left + right)/2;
if(s[mid] == key)
return mid;
else if(s[mid] > key)
right = mid - 1;
else
left = mid + 1;
}
return -1;
}
/*******************折半查找end*********************/
/*******************二叉排序树查找start*********************/
/*
优点:查找速度快O(nlogn)
缺点:1)静态查找表必须是有序的,
2)将查找不成功关键字数据添加到查找表中,需要大量的移动操作
*/
//功能:定义二叉树结构
typedef struct bst{
int data;
struct bst *left;
struct bst *right;
}BSTree;
//功能:在二叉排序树中插入关键字key,插入后一定是一个叶子节点
//假设不会出现相同的数据
void InsertBSTree(BSTree *bt, int key){
BSTree *p, *head, *parent;
if(!(p=(BSTree *)malloc(sizeof(BSTree)))){
printf("申请内存出错!\n");
exit(0);
}
//初始化申请的内存空间
p->data = key;
p->left = NULL;
p->right = NULL;
//查找需要添加的父节点
head = bt;
while(head){
parent = head; //退出循环时head==NULL,所以用parent,指向前一个节点
if(head->data > key)
head = head->left;
else
head = head->right;
}
//判断添加到左子树还是右子树上
if(key < parent->data)
parent->left = p;
else
parent->right = p;
}
//功能:创建二叉排序树
void CreateBST(BSTree *t, int data[], int n){
int i;
t->data = data[0]; //初始化根节点
t->left = t->right = NULL;
for(i=1; i<n; i++)
InsertBSTree(t, data[i]);
}
//功能:中序遍历二叉排序树
void BST_LDR(BSTree *t){
if(t){
BST_LDR(t->left);
printf("%d ", t->data);
BST_LDR(t->right);
}
}
//功能:二叉排序树的查找
BSTree *searchBST(BSTree *t, int key){
if(!t || t->data == key)
return t;
else if(t->data > key)
return (searchBST(t->left, key));
else
return (searchBST(t->right, key));
}
//功能:删除二叉排序树中的节点
void BST_Delete(BSTree *t, int key){
BSTree *p, *parent, *ll, *l;
int child=0; //0表示左子树,1表示右子树
int flag = 1;
if(!t) //二叉排序树为空
return;
p = t;
parent = p;
while(flag){
//p节点数据等于关键字
if(p->data == key){
//p节点为叶节点(左右子树均为空)
if(!p->left && !p->right){
if(p==t) //被删除的是根节点
free(p);
else if(child==0){
parent->left = NULL;
free(p);
}
else{
parent->right = NULL;
free(p);
}
p = NULL;
flag = 0;
}
//p节点左子树为空,右子树不空
else if(!p->left){
if(child==0)
parent->left = p->right;
else
parent->right = p->right;
free(p);
p = NULL;
flag = 0;
}
//p节点右子树为空,左子树不空
else if(!p->right){
if(child==0)
parent->left = p->left;
else
parent->right = p->left;
free(p);
p = NULL;
flag = 0;
}
//p节点为分支节点(左右子树均不空)
else{
ll=p;
l=p->right;
if(l->left){
while(l->left){
ll = l;
l = l->left;
}
p->data = l->data;
ll->left = NULL;
}
else{
p->data = l->data;
p->right = l->right;
}
free(l);
flag = 0;
}
}
//p节点数据大于关键字
else if(p->data > key){
child = 0;
parent = p;
p = p->left;
}
//p节点数据小于关键字
else{
child = 1;
parent = p;
p = p->right;
}
}
}
/*******************二叉排序树查找end*********************/
2. 测试查找操作
BSTreeTest.cpp
#include<stdio.h>
#include<stdlib.h>
#include"SeqSearch.h"
int main(){
int key, i, pos;
BSTree bst, *pos1;
int select;
int data;
do{
printf("---------------------------\n");
printf("1.顺序查找算法 2.改进后的顺序查找算法\n");
printf("3.折半查找算法 4.创建二叉排序树\n");
printf("5.遍历二叉排序树 6.二叉排序树查找算法\n");
printf("7.删除二叉排序树的某个节点\n");
printf("0.退出\n");
printf("请选择执行的操作序号:");
//select = getch();
fflush(stdin);
scanf("%d", &select);
switch(select){
case 1:
printf("请输入查找关键字:");
fflush(stdin);
scanf("%d", &key);
//调用顺序查找算法
pos = SeqSearch(source, ARRAYLEN, key);
if(pos>=0)
printf("查找成功,该关键字位于数组的第%d个位置。\n", pos+1);
else
printf("查找失败。\n");
break;
case 2:
printf("请输入查找关键字:");
fflush(stdin);
scanf("%d", &key);
source1[ARRAYLEN]=key; //将查找关键字放入最后一个位置
//调用改进后的顺序查找算法
pos = SeqSearch1(source1, ARRAYLEN, key);
if(pos>=0)
printf("查找成功,该关键字位于数组的第%d个位置。\n", pos+1);
else
printf("查找失败。\n");
break;
case 3:
printf("请输入查找关键字:");
fflush(stdin);
scanf("%d", &key);
//调用折半查找算法
pos = BinarySearch(source1, ARRAYLEN, key);
if(pos>=0)
printf("查找成功,该关键字位于数组的第%d个位置。\n", pos+1);
else
printf("查找失败。\n");
break;
case 4:
CreateBST(&bst, source3, 2); //创建二叉排序树
break;
case 5:
printf("二叉排序树遍历结果:");
BST_LDR(&bst); //遍历二叉排序树
printf("\n");
break;
case 6:
printf("请输入查找关键字:");
fflush(stdin);
scanf("%d", &key);
pos1 = searchBST(&bst, key);
printf("原数据为:");
for(i=0; i<2; i++)
printf("%d ", source3[i]);
printf("\n");
if(pos1)
printf("查找成功,该节点的地址为:%x\n", pos1);
else
printf("查找失败。\n");
break;
case 7:
printf("请输入要删除的关键字:");
fflush(stdin);
scanf("%d", &key);
BST_Delete(&bst, key);
break;
}
}while(select != 0);
system("pause");
return 0;
}