查找

一.静态查找顺序表 : 从表的一端开始,顺序扫描线性表,依次将扫描到的结点关键宇和给定值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();
}

二.静态二分查找: 虽然二分查找的效率高,但是要将表按关键字排序。而排序本身是一种很费时的运算。既使采用高效率的排序方法也要花费O(nlgn)的时间。 二分查找只适用顺序存储结构。为保持表的有序性,在顺序结构里插入和删除都必须移动大量的结点。因此,二分查找特别适用于那种一经建立就很少改动、而又经常需要查找的线性表。 对那些查找少而又经常需要改动的线性表,可采用链表作存储结构,进行顺序查找。链表上无法实现二分查找。
#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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值