一.静态查找顺序表
:
从表的一端开始,顺序扫描线性表,依次将扫描到的结点关键宇和给定值K相比较。若当前扫描到的结点关键字与K相等,则查找成功;若扫描结束后,仍未找到关键字等于K的结点,则查找失败。算法简单,且对表的结构无任何要求,无论是用向量还是用链表来存放结点,也无论结点之间是否按关键字有序,它都同样适用。查找效率低,因此,当n较大时不宜采用顺序查找。
#include<stdio.h>
int Search_seq(int R[],int length,int key)
{
int i;
R[0]=key;
for(i=length-1;R[i]!=key;--i);//找不到时i为0,否则R[i]就是要找的结点;
return i;
}
int main()
{
int R[11]={0,13,29,18,27,6,15,34,33,2,1};
int k=Search_seq(R,11,15);
printf("%d ",k);
getchar();
}
#include<stdio.h>
int BinSearch(int R[],int length,int key)
{
int low=1;
int high=length;
int mid;
while(low<=high)
{
mid=(low+high)/2;
if(key==R[mid])
return mid;
else if(key>R[mid])
low=mid+1;
else
high=mid-1;
}
return 0;
}
int main()
{
int a[]={10,3,5,7,9,10,24,35,44,56,78};//a[0]存数组长度
int k=BinSearch(a,a[0],78);
printf("%d ",k);
getchar();
return 0;
}
三.静态分块查找: http://www.cnblogs.com/foreverking/articles/2322853.html
题目描述:
输入一系列整数,建立二叉排序数,并进行前序,中序,后序遍历。
输入:
输入第一行包括一个整数n(1<=n<=100)。
接下来的一行包括n个整数。
输出:
可能有多组测试数据,对于每组数据,将题目所给数据建立一个二叉排序树,并对二叉排序树进行前序、中序和后序遍历。
每种遍历结果输出一行。每行最后一个数据之后有一个空格。
样例输入:
5
1 6 5 9 8
样例输出:
1 6 5 9 8
1 5 6 8 9
5 8 9 6 1
提示:
输入中可能有重复元素,但是输出的二叉树遍历序列中重复元素不用输出。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 101
struct btree
{
struct btree *lchild, *rchild;
int data;
};
struct stack
{
struct btree* arr[N];
int top;
};
struct btree* create_sortree(struct btree* t, int d);
void pre_traverse(struct btree *t);
void order_traverse(struct btree *t);
void post_traverse(struct btree *t);
void clean_tree(struct btree *t);
int main()
{
int i, n, d;
struct btree *t;
while (scanf("%d", &n) != EOF) {
//接收客户端输入,构建二叉排序树
for (i = 0, t = NULL; i < n; i ++) {
scanf("%d", &d);
t = create_sortree(t, d);
}
// 前序遍历
pre_traverse(t);
// 中序遍历
order_traverse(t);
// 后序遍历
post_traverse(t);
// 清理
clean_tree(t);
}
return 0;
}
struct btree* create_sortree(struct btree *t, int d)
{
if (t == NULL) {
t = (struct btree*)malloc(sizeof(struct btree) * 1);
t->data = d;
t->lchild = NULL;
t->rchild = NULL;
}else if(t->data > d) { // 插入到左子树
t->lchild = create_sortree(t->lchild, d);
}else if(t->data < d) { // 插入到右子树
t->rchild = create_sortree(t->rchild, d);
}else {
// 相同元素不进行任何操作
}
return t;
}
void pre_traverse(struct btree *t)
{
struct btree *p = t;
struct stack *s = (struct stack*)malloc(sizeof(struct stack) * 1);
s->top = 0;
while (s->top || p) {
if (p) {
printf("%d ", p->data);
s->arr[s->top ++] = p;
p = p->lchild;
}else {
p = s->arr[-- s->top];
p = p->rchild;
}
}
printf("\n");
}
void order_traverse(struct btree *t)
{
struct btree *p = t;
struct stack *s = (struct stack*)malloc(sizeof(struct stack) * 1);
s->top = 0;
while (s->top || p) {
if (p) {
s->arr[s->top ++] = p;
p = p->lchild;
}else {
p = s->arr[-- s->top];
printf("%d ", p->data);
p = p->rchild;
}
}
printf("\n");
}
void post_traverse(struct btree *t)
{
struct btree *p, *pre;
struct stack *s = (struct stack*)malloc(sizeof(struct stack) * 1);
s->top = 0;
pre = NULL;
p = t;
while (p || s->top) {
if (p) {
s->arr[s->top ++] = p;
p = p->lchild;
}else {
p = s->arr[-- s->top];
if (p->rchild == NULL || p->rchild == pre) {
printf("%d ", p->data);
pre = p;
p = NULL;
}else {
s->arr[s->top ++] = p;
p = p->rchild;
}
}
}
printf("\n");
}
void clean_tree(struct btree *t)
{
if (t) {
clean_tree(t->lchild);
clean_tree(t->rchild);
free(t);
}
}
/**************************************************************
Problem: 1201
User: wangzhengyi
Language: C
Result: Accepted
Time:70 ms
Memory:3284 kb
****************************************************************/
http://poj.org/problem?id=2418
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 10001
//二叉查找树,中序输出
int root=0;//根索引,0表示NULL
int curr_size=0;//当前树中结点的个数
int num_trees=0;//树的数目
//树节点的定义,下标从1开始,0表示NULL
char key[MAXSIZE][31];
int value[MAXSIZE];
int left_child[MAXSIZE];
int right_child[MAXSIZE];
//查找二叉排序树,如果树为空,返回0,号码已经存在(计数器加1),返回-1,否则返回最后查找的位置
int search(int node, char* k)
{
int parent=0;
int current=node;
while(current!=0)
{
parent=current;
int tmp = strcmp(key[current],k);
if(tmp == 0)
{
value[current]++;
return -1;
}else if(tmp<0)
{
current = right_child[current];
}else
{
current = left_child[current];
}
}
return parent;
}
//插入新节点
int insert(int node,char* k)
{
//判断一下插在左子树,还是右子树
int tmp = strcmp(key[node],k);
if(tmp==0)
return 0;
int new_node = ++curr_size;//分配新位置
strcpy(key[new_node],k);
value[new_node]=1;
left_child[new_node]=0;
right_child[new_node]=0;
if(new_node==1)//树为空
root = 1;
if(tmp>0)
left_child[node] = new_node;
else
right_child[node] = new_node;
return 1;
}
void build_tree()
{
//freopen("in.txt","r",stdin);
char buf[31];
while(gets(buf))
{
num_trees++;
int index = search(root,buf);
if(index>=0)
{
insert(index,buf);
}
}
}
//中序遍历
void inorder_tree(int root)
{
if(!root)
return ;
inorder_tree(left_child[root]);
printf("%s %.4f/n",key[root] ,value[root]*100.0/num_trees);
inorder_tree(right_child[root]);
}
int main()
{
build_tree();
inorder_tree(root);
return 0;
}
五.hash查找:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//#define DEBUG
#ifdef DEBUG
#define debug(...) printf( __VA_ARGS__)
#else
#define debug(...)
#endif
struct trie_node {
struct trie_node *child[256]; /* 分支节点的孩子指针 */
int count; /* 用于记录单词出现的次数,若count大于0,说明
从根节点到此节点的父节点构成了一个单词,这个
单词的次数就是count */
};
int n; /* 树的总数 */
struct trie_node *init_trie_tree()
{
return (struct trie_node *)calloc(1, sizeof(struct trie_node));
}
void insert(struct trie_node *root, char *word)
{
struct trie_node *node;
char *p;
node = root;
debug("%s.......\n", word);
for (p = word; *p; p++) {
debug("开始插入%c\n", *p);
if (node->child[*p] == 0) {
debug("%c不存在,创建新节点\n", *p);
node->child[*p] = (struct trie_node *)calloc(1, sizeof(struct trie_node));
}
else {
debug("%c存在\n", *p);
}
node = node->child[*p];
}
//到达记录统计单词次数的节点
node->count++;
debug("%s有%d个\n\n", word, node->count);
}
/* 借助pos指针来遍历每个单词,初始时pos指向worddump的第一个位置
* 若往孩子节点走,则pos后移,若往兄弟节点走,则pos保持不动
*/
void dfs_travel(struct trie_node *root)
{
static char worddump[31];
static int pos;
int i;
if (root->count) { /* 如果count不为0,则肯定找到了一个单词 */
worddump[pos] = '\0';
if (worddump[0]) {
printf("%s %0.4f\n", worddump, ((float)root->count*100)/(float)n);
}
}
for (i = 0; i < 256; i++) {
if (root->child[i]) {
debug("找到%c\n", i);
worddump[pos++] = i; /* 往下遍历,pos跟着后移,供孩子节点使用 */
dfs_travel(root->child[i]);
pos--; /* 恢复位置,供下一个兄弟节点使用 */
debug("回退1个位置\n");
}
}
}
int main()
{
char line[31];
struct trie_node *root;
n = 0;
root = init_trie_tree();
while (gets(line)) {
insert(root, line);
n++;
}
dfs_travel(root);
return 0;
}
http://poj.org/problem?id=3349
//POJ3349
//Hash Table 开散列法 总结poj discuss的tips
// 1. 直接相加, 总和%大质数为key.
// 2. 平方和相加, 总和%大质数为key.
// 3. 从小到大的顺序, 对v[i]<<(i*3)依次异或, 然后模一个大质数作为key.
// 4. 六个数中非零数的积再乘上一个大质数,然后模一个100w上下的数。
// 自己拿随机数据测下来110w左右的效果最好,随机情况下数据量是10w的时候hash值相同的情况只有6k多个,几乎可以忽略。
// 5. 依次对每个数异或所得的数作为key. (by archerstarlee)
// 6. (a[0]+a[2]+a[4])&(a[1]+a[3]+a[5]), 再模一个大质数. &还可改成'|' 或'^'.非常巧妙!(只对本题适用的hash方法)
// 最后就是用getchar和gets来进行输入转换更为快速. G++比GCC快一些.
#include<iostream>
#include<cstdio>
#include<string>
#define M 99991
#define max 100000
using namespace std;
struct flake{
long arm[6];
bool value;
flake *next;
};
struct flake sonw[max];
void initialize(flake a){
a.value=0;
a.next=NULL;
}
long hash(long arm[]){//平方和相加, 总和%大质数为key.
long long h;
for(int i=0;i<6;i++)
h+= (arm[i]*arm[i]);
return h%M;
}
void insert(struct flake *p,long arm[6]){
if(p->value==0){
for(int i=0;i<6;i++)
(p->arm[i])=arm[i];
p->value = 1;
p->next = new flake;
p->next->value = 0;
}
else{
p = p->next;
insert(p,arm);
}
}
bool judge(long a[6],long b[6]){//一共六个元素,就这样好了。。。囧。。。
if (a[0]==b[0]&&a[1]==b[1]&&a[2]==b[2]&&a[3]==b[3]&&a[4]==b[4]&&a[5]==b[5]) return 1;
else if(a[0]==b[1]&&a[1]==b[2]&&a[2]==b[3]&&a[3]==b[4]&&a[4]==b[5]&&a[5]==b[0]) return 1;
else if(a[0]==b[2]&&a[1]==b[3]&&a[2]==b[4]&&a[3]==b[5]&&a[4]==b[0]&&a[5]==b[1]) return 1;
else if(a[0]==b[3]&&a[1]==b[4]&&a[2]==b[5]&&a[3]==b[0]&&a[4]==b[1]&&a[5]==b[2]) return 1;
else if(a[0]==b[4]&&a[1]==b[5]&&a[2]==b[0]&&a[3]==b[1]&&a[4]==b[2]&&a[5]==b[3]) return 1;
else if(a[0]==b[5]&&a[1]==b[0]&&a[2]==b[1]&&a[3]==b[2]&&a[4]==b[3]&&a[5]==b[4]) return 1;
else return 0;
}
bool search(struct flake *q,long arm[6]){
long c[6];//arm的倒置
for(int i=0;i<6;i++)
c[i]=arm[5-i];
while(q->value){
long stand[6];
for(int i=0;i<6;i++)
stand[i]=(q->arm[i]);
if(judge(stand,arm)==1||judge(stand,c)==1) return 1;
else q=q->next;
}
if(q->value==0) return 0;
}
int main(){
for(int i=0;i<max;i++)
initialize(sonw[i]);
long n,arm[6];
cin >> n;
while(n--){
for(int i=0;i<6;i++)
scanf("%ld",&arm[i]);
int k=hash(arm);
struct flake *p;
p=&sonw[k];
//多路判定。。。。。。不能 if...if....if...的啊啊啊啊啊啊啊啊啊
if(search(p,arm)==0)
insert(p,arm);
else if(search(p,arm)==1){
printf("Twin snowflakes found.\n");
return 0;
}
}
printf("No two snowflakes are alike.\n");
return 0;
}
http://blog.csdn.net/lyy289065406/article/details/6647351