数据结构之查找
散列查找
首先我们来考虑一下散列表,散列表最核心的思想就是计算要查找的内存位置,看清楚,是位置,也就是说我们可以在O(1)的时间内找到我们需要的东西。这相对于普通查找来说,从O(N)到O(1),是多么大的一个提升,原理我就不讲了,直接看实现,这里采用开放定址法来实现散列查找。
#include<stdio.h>
#include<stdlib.h>
#define SUCCESS 1
#define UNSUCCESS 0
#define HASHSIZE 12
#define NULLKEY -32768
typedef struct{
int *elem;
int count;
}HashTable;
int m = 0;
int InitHashTable(HashTable *H)
{
int i;
m = HASHSIZE;
H->count = m;
H->elem=(int *)malloc(m*sizeof(int));
for(i=0;i<m;i++)
H->elem[i]= NULLKEY;
return 1;
}
int Hash(int key)
{
return key%m;
}
void InsertHash(HashTable *H,int key)
{
int addr = Hash(key);
while(H->elem[addr] != NULLKEY)
addr = (addr+1) % m;
H->elem[addr] = key;
}
int SearchHash(HashTable H,int key,int *addr)
{
*addr = Hash(key);
while(H.elem[*addr]!=key)
{
*addr = (*addr+1) % m;
if(H.elem[*addr]==NULLKEY || *addr==Hash(key))
return 0;
}
return 1;
}
int main()
{
int A[]={12,67,56,16,25,37,22,39,15,47,48,34};
int i=0,key=39, result,addr;
HashTable H;
InitHashTable(&H);
for(i=0;i<12;i++)
InsertHash(&H,A[i]);
result = SearchHash(H,key,&addr);
for(i=0;i<12;i++)
{
SearchHash(H,A[i],&addr);
printf("%d %d\n",A[i],addr);
}
return 0;
}
二叉查找树
#include<stdio.h>
#include<stdlib.h>
#include<stack>
#include<queue>
using namespace std;
typedef struct TreeNode *Tree;
struct TreeNode{
int v;
Tree Left,Right;
};
Tree NewNode(int V)
{
Tree T = (Tree)malloc(sizeof(struct TreeNode));
T->v = V;
T->Left = T->Right = NULL;
return T;
}
Tree Insert(Tree T,int V)
{
if(!T)
T = NewNode(V);
else{
if(V>T->v)
T->Right = Insert(T->Right,V);
else
T->Left = Insert(T->Left,V);
}
return T;
}
Tree MakeTree(int N)
{
Tree T;
int i,V;
scanf("%d",&V);
T = NewNode(V);
for(i=1;i<N;i++){
scanf("%d",&V);
T = Insert(T,V);
}
return T;
}
//递归遍历
void preOrder(Tree T)
{
if(!T)
return ;
preOrder(T->Left);
preOrder(T->Right);
printf("%d",T->v);
}
//层次遍历
void LevelOrder(Tree T)
{
Tree t;
if(!T)
return ;
queue<Tree> q;
q.push(T);
while(!q.empty()){
t = q.front();
q.pop();
printf("%d",t->v);
if(t->Left)
q.push(t->Left);
if(t->Right)
q.push(t->Right);
}
}
//非递归遍历 前序
void PreRecusion(Tree T)
{
Tree t = T;
stack<Tree> s;
while(t || !s.empty()){
while(t){
printf("%d",t->v);
s.push(t);
t = t->Left;
}
if(!s.empty()){
t = s.top();
s.pop();
t = t->Right;
}
}
}
//非递归遍历 中序
void InRecusion(Tree T)
{
stack<Tree> s;
Tree t = T;
while(t || !s.empty()){
while(t){
s.push(t);
t = t->Left;
}
if(!s.empty()){
t = s.top();
printf("%d",t->v);
s.pop();
t = t->Right;
}
}
}
int main()
{
Tree T;
T = MakeTree(5);
preOrder(T);
return 0;
}
这段代码是关于二叉搜素树的部分,其中还包含了递归,非递归的遍历方式,非常值得一读。