一、基础知识
二、代码要求
三、算法思路分析
四、算法反思
五、代码实现
顺序查找
#include<stdio.h>
int search(int a[], int y, int x); /*对自定义的函数search进行声明*/
int main(void)
{
int i, x, n, num; /*变量定义*/
int a[100];
printf("请输入数组的长度:");
scanf("%d",&num);
printf("请输入%d个数字!\n",num);
for(i = 0; i < num; i++)
{
scanf("%d", &a[i]); /*接收输入的数组*/
}
printf("请输入要查找的数:");
scanf("%d", &x); /*接收关键字*/
n = search(a, 10, x); /*调用函数search()完成顺序查找*/
if(n < 0) /*输出要找的数的位置*/
{
printf("没找到您要找的数,您要找的数可能不在数组中。\n");
}
else
{
printf("您要找的数%d在数组中第%d个元素处。\n", x, n);
}
}
//顺序查找
int search(int a[], int y, int x) /*被调用的函数search()*/
{
int i, f = -1;
for(i = 0; i < 10; i++)
{
if(x == a[i])//查找到所需的元素,跳出循环
{
f = i + 1;
break;
}
}
return(f);
}
折半查找
#include <stdio.h>
int binary_search(int key,int a[],int n) //自定义函数binary_search()
{
int low,high,mid,count=0,count1=0;
low=0;
high=n-1;
while(low<high) //査找范围不为0时执行循环体语句
{
count++; //count记录査找次数
mid=(low+high)/2; //求中间位置
if(key<a[mid]) //key小于中间值时
high=mid-1; //确定左子表范围
else if(key>a[mid]) //key 大于中间值时
low=mid+1; //确定右子表范围
else if(key==a[mid]) //当key等于中间值时,证明查找成功
{
printf("查找成功!\n 查找 %d 次!a[%d]=%d",count,mid,key); //输出査找次数及所査找元素在数组中的位置
count1++; //count1记录查找成功次数
break;
}
}
if(count1==0) //判断是否查找失敗
printf("查找失敗!"); //査找失敗输出no found
return 0;
}
int main()
{
int i,key,a[100],n;
printf("请输入数组的长度:\n");
scanf("%d",&n); //输入数组元素个数
printf("请输入数组元素:\n");
for(i=0;i<n;i++)
scanf("%d",&a[i]); //输入有序数列到数组a中
printf("请输入你想查找的元素:\n");
scanf("%d",&key); //输入要^找的关键字
binary_search(key,a,n); //调用自定义函数
printf("\n");
return 0;
}
二叉排序树
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int key;
struct node *lchild, *rchild;
}BSTNode, *BSTree;
//插入
int InsertBST(BSTree *bst, int k)
{
BSTree r, s, pre;
r = (BSTree)malloc(sizeof(BSTNode));
r->key = k;
r->lchild = NULL;
r->rchild = NULL;
if(*bst == NULL)
{
*bst = r;
return 1;
}
pre = NULL;
s = *bst;
while(s)
{
if(k == s->key)
return 0;
else if(k < s->key)
{
pre = s;
s = s->lchild;
}
else
{
pre = s;
s = s->rchild;
}
}
if(k < pre->key)
pre->lchild = r;
else
pre->rchild = r;
return 1;
}
void CreateBST(BSTree *bst)
{
int key;
*bst = NULL;
scanf("%d", &key);
while(key != -1)
{
InsertBST(bst, key);
scanf("%d", &key);
}
}
/*
*打印二叉树:
*中序遍历
*/
void InOrder(BSTree root)
{
if(root != NULL)
{
InOrder(root->lchild);
printf(" %d ", root->key);
InOrder(root->rchild);
}
}
/*
*搜索
*/
BSTree SearchBST(BSTree bst, int key)
{
BSTree q;
q = bst;
//递归
while(q)
{
if(q->key == key)
return q;
if(q->key > key)
q=q->lchild;
else
q=q->rchild;
}
return NULL; //查找失败
}
int main()
{
BSTree T;
int tag = 1;
int m, n;
printf("建立二叉排序树,请输入序列以-1结束:\n");
CreateBST(&T);
printf("中序遍历二叉树,序列为:\n");
InOrder(T);
printf("\n");
while(tag != 0)
{
printf("请输入你要查找的元素:\n");
scanf("%d", &n);
if(SearchBST(T, n) == NULL)
printf("抱歉查找失败!\n");
else
printf("查找成功!查找的数字为%d\n", SearchBST(T,n)->key);
printf("是否继续查找 是 :请按 1 否则按 0:\n");
scanf("%d", &tag);
}
return 0;
}
平衡二叉树
#include<stdio.h>
#include<stdlib.h>
#define MAX 50
#define nul -32768
typedef struct Node //树中结点的定义
{
int key; //关键字
struct Node *pleft; //指向左子树的指针
struct Node *pright; //指向右子树的指针
int bf; //表示该结点的平衡因子
}Node;
typedef struct Hash
{
int *e; //数据元素存储基地址,动态分配数组
int count; //当前数据元素个数
}Hash;
int l=0; //散列表长,全局变量
void menu();
//顺序查找
int SeqSearch(int a[],int n,int k)
{
int i;
for(i=0;i<n;i++)
{
if(a[i]==k)
{
return i;
}
}
return -1;
}
//折半查找,要求查找表有序
int BinarySearch(int a[],int n,int k)
{
int l=0,h=n-1,m;
while(l<=h)
{
m=(l+h)/2;
if(k==a[m])
{
return m;
}
if(k<a[m])
{
h=m-1;
}
else
{
l=m+1;
}
}
return -1;
}
//二叉排序树
//查找
int SearchBS(Node *BT,int key)
{
if(BT==NULL)
{
return 0;
}
if(key==BT->key)
{
return 1;
}
else if(key<BT->key)
{
return SearchBS(BT->pleft,key);
}
else
{
return SearchBS(BT->pright,key);
}
}
int SearchBST(Node *BT,int key,Node **k,Node **parent)
{
*k=BT;
while(*k)
{
if(key>(*k)->key)
{
*parent=*k;
*k=(*k)->pright;
}
else if(key<(*k)->key)
{
*parent=*k;
*k=(*k)->pleft;
}
}
*k=*parent;
return 0;
}
//插入和创建
int InsertBST(Node **BT,int key)
{
Node *s; //定义存放新的关键字的结点
Node *k,*parent=NULL;
if(SearchBST(*BT,key,&k,&parent)==1) //若关键字已在树中,则插入失败
{
return 0;
}
//关键字不在树中,首先为新结点分配空间
s=(Node *)malloc(sizeof(Node));
s->key=key;
s->pleft=s->pright=NULL;
if(k==NULL) //若树为空树,则新结点为插入后的根结点
{
(*BT)=s;
}
else if(key<k->key)
{
k->pleft=s;
}
else
{
k->pright=s;
}
return 1;
}
//平衡二叉树
int SearchBalanceBST(Node *BT,int key)
{
int f=0;
Node *p=BT;
while(p)
{
if(key>p->key)
{
p=p->pright;
}
else if(key<p->key)
{
p=p->pleft;
}
}
return 0;
}
//插入
void RightRotate(Node **BT) //右旋
{
Node *p=(*BT)->pleft;
(*BT)->pleft=p->pright;
p->pright=*BT;
*BT=p;
}
void LeftRotate(Node **BT)
{
Node *p=(*BT)->pright;
(*BT)->pright=p->pleft;
p->pleft=*BT;
*BT=p;
}
void LL_LR_Balance(Node **BT)
{
Node *pleft=(*BT)->pleft;
Node *pright;
switch(pleft->bf)
{
case 1: //LL
(*BT)->bf=pleft->bf=0;
RightRotate(BT);
break;
case -1: //LR
pright=pleft->pright;
switch(pright->bf)
{
case 0:
(*BT)->bf=pleft->bf=0;
break;
case 1:
pright->bf=pleft->bf=0;
(*BT)->bf=-1;
break;
case -1:
(*BT)->bf=pright->bf=0;
pleft->bf=1;
break;
}
LeftRotate(&(*BT)->pleft);
RightRotate(BT);
break;
}
}
void RR_RL_Balance(Node **BT)
{
Node *pright=(*BT)->pright;
Node *pleft;
switch(pright->bf)
{
case -1: //RR
(*BT)->bf=pright->bf=0;
LeftRotate(BT);
break;
case 1: //RL
pleft=pright->pleft;
switch(pleft->bf)
{
case 0:
(*BT)->bf=pright->bf=0;
break;
case 1:
(*BT)->bf=pleft->bf=0;
pright->bf=-1;
break;
case -1:
pright->bf=pleft->bf=0;
(*BT)->bf=1;
break;
}
RightRotate(&(*BT)->pright);
LeftRotate(BT);
break;
}
}
/*平衡二叉树是二叉搜索树的优化版本,在算法内部他要比 二叉搜索树更加的高效.但是输出这里体现不出来*/
int InsertBalanceBST(Node **BT,int key,int *chain)
{
if((*BT)==NULL) //表示未在树中找到key,直接生成新的结点,用于存储key
{
*BT=(Node *)malloc(sizeof(Node));
(*BT)->bf=0;
(*BT)->pleft=(*BT)->pright=NULL;
(*BT)->key=key;
*chain=1; //插入新结点引起树的高度变化
}
else
{
if(key==(*BT)->key) //树中含相同关键字,插入失败
{
*chain=0;
return 0;
}
if(key<(*BT)->key)
{
if(!InsertBalanceBST(&(*BT)->pleft,key,chain))
{
return 0;
}
if(*chain)
{
switch((*BT)->bf)
{
case 0:
(*BT)->bf=1;
*chain=1;
break;
case 1:
LL_LR_Balance(BT);
*chain=0;
break;
case -1:
(*BT)->bf=0;
*chain=0;
break;
}
}
}
else
{
if(!InsertBalanceBST(&(*BT)->pright,key,chain))
{
return 0;
}
if(*chain)
{
switch((*BT)->bf)
{
case 0:
(*BT)->bf=-1;
*chain=1;
break;
case 1:
(*BT)->bf=0;
*chain=0;
break;
case -1:
RR_RL_Balance(BT);
*chain=0;
break;
}
}
}
}
return 1;
}
int main()
{
int s,n,i,x,m;
int a[MAX];
Node *BT=NULL;
int chain;
while(1)
{
menu();
scanf("%d",&s);
switch(s)
{
case 1:
printf("请输入数据个数:\n");
scanf("%d",&n);
printf("请输入数据:(中间以空格分开)\n");
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(i=0;i<n;i++)
{
InsertBST(&BT,a[i]);
}
printf("请输入要查找的数:\n");
scanf("%d",&x);
m=SearchBS(BT,x);
if(m==0)
{
printf("在数组中找不到%d。\n",x);
}
else
{
printf("在数组中找到%d。\n",x);
}
break;
case 2:
printf("请输入数据个数:\n");
scanf("%d",&n);
printf("请输入数据:(中间以空格分开)\n");
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(i=0;i<n;i++)
{
InsertBalanceBST(&BT,a[i],&chain);
}
printf("请输入要查找的数:\n");
scanf("%d",&x);
m=SearchBS(BT,x);
if(m==0)
{
printf("找不到%d。\n",x);
}
else
{
printf("找到%d。下标为%d\n",x);
}
break;
case 0:
return 0;
default:printf("输入格式非法,请重新输入选项,(0-2含)内的整数\n");break;
}
}
return 0;
}
void menu()
{
printf("1.二叉排序树查找\n2.平衡二叉树查找\n0.退出\n");
}
哈希表
#include<stdio.h>
#define LEN 10
#define N 11
int data[100]; //原始数据;
int hash[LEN]={0}; //哈希表,初始化为0;
void Create()
{
int i=0;
for(i=0;i<N;i++) //循环将原始数据保存到哈希表中;
{
//将关键字插入到哈希表hash中;
int j=data[i]%10; //计算哈希地址;
while(hash[j]) //元素位置已被占用;
j=(++j)%LEN; //线性探测法解决冲突;
hash[j]=data[i];
}
}
int Haxi_Sou(int key)
{
int i=key%LEN; //计算哈希地址;
while(hash[i]&&hash[i]!=key) //判断是否冲突;
i=(++i)%LEN; //线性探测法解决冲突;
if(hash[i]==0) //查找到开放单元,表示查找失败;
return -1; //返回失败值;
else
return i; //返回对应的元素下标;
}
int main()
{
int key, i=0, num;
printf("请输入数据数量:");
scanf("%d",&num);
int j;
printf("请输入数据:\n");
for(j=0; j<num; j++)
{
scanf("%d",&data[j]);
}
Create(); //调用函数创建哈希表;
printf("哈希表中各元素的值:");
for(i=0;i<LEN;i++)
printf("%d ",hash[i]);
printf("\n");
printf("输入查找的关键字;");
scanf("%d",&key);
int pos=Haxi_Sou(key); //调用函数在哈希表中查找;
if(pos>0)
printf("查找成功,该关键字在数组中的下标为 %d !!!\n是第%d个元素",pos,pos+1);
else
printf("查找失败!!!");
printf("\n");
return 0;
}