搜索查找 - 算法学习
来源:互联网 发布:java和php全面对比 编辑:程序博客网 时间:2024/05/19 00:10
搜索是一种以集合为逻辑结构,以查找为核心的运算,同时包括其他运算的数据结构。
1.1 静态搜索 - 该方法是基于顺序表作为存储结构的,然后在这个结构上执行运算。
1.1 顺序搜索
岗哨a[0]保证while循环一定会终止,这样的话不用将i > 0写入循环条件,是循环条件简化
//len为数组的长度,x是要查找的元素值int Search(int a[], int len, int x){ int i = len; a[0] = x; while(a[i] != x) i--; return i;}
1.2 折半搜索法
在一个有序表中可以用效率更高的折半搜索法进行查找,在每一次如果未找到搜索元素,则进一步缩小搜索的范围。折半搜索的思想是:每次将搜索区间的中间元素和给定
的值K比较,若不相等就缩小范围并在新的范围内重复上述过程,直至搜索成功返回0(或者搜索不成功为止)。当然这些都是在数组元素都进行排序之后再进行的。
int Compare(int a, int b){ if(a > b) return 1; else if(a < b) return -1; else return 0;}int BinSearch(int a[], int len, int x){ int mid, low = 0; int high = len; while(low <= high) { mid = (low + high) / 2; switch(Compare(a[mid], x)) { case 0: return (mid); case -1: low += 1; break; case 1: high = mid -1; break; } } return 0;}
2 二叉搜索树
二叉搜索树定义:是空树或者满足已下性质的二叉树:
(1) 若它的左子树非空,则左子树的所有节点都小于根节点
(2) 若它的右子树非空,则右子树的所有节点都小于根节点
(3) 左右子树本身又各是二叉搜索树
(4) 每个元素都有一个关键值,且没有任何两个元素有相同的关键值,所有关键值都是唯一的。
2.1二叉搜索树的搜索:
递归算法为在指针root所指的二叉搜索树的键值是否等于key的节点,成功返回该节点的指针,否则返回空指针。改程序中以输入0为终止符
#include <stdio.h>#include <stdlib.h>typedef int datatype;typedef struct node{ datatype data; struct node *lchild, *rchild;}Tree, *pTree;pTree CreatTree(void);void ShowTree(pTree root);void FreeTree(pTree root);pTree CreatTree(void){ pTree p; int x; scanf("%d", &x); if(x == 0) p = NULL; else { p = (Tree *)malloc(sizeof(Tree)); p->data = x; p->lchild = CreatTree(); p->rchild = CreatTree(); } return p;}void ShowTree(pTree root){ if(root) { printf("%d ", root->data); ShowTree(root->lchild); ShowTree(root->rchild); }}void FreeTree(pTree root){ if(root) { FreeTree(root->lchild); FreeTree(root->rchild); free(root); }}int Compare(int a, int b){ if(a > b) return 1; else if(a < b) return -1; else return 0;}pTree TreeSearch(pTree root, datatype key){ if(root == NULL) return NULL; else { switch(Compare(root->data, key)) { case 0: return (root); case -1: return (TreeSearch(root->rchild, key)); case 1: return (TreeSearch(root->lchild, key)); } }}int main(void){ pTree root, p; root = CreatTree(); ShowTree(root); putchar('\n'); if((p = TreeSearch(root, 5)) != NULL) printf("\nthe location is %d.\n", p->data); FreeTree(root); printf("\nFree the tree is ok.\n"); return 0;}2.2 二叉搜索树的插入
二叉搜索树的插入必须保证插入一个节点后仍是一个二叉搜索树,另外,当二叉搜索树中不存在也键值相等的元素时才能插入这样一个节点。因此插入算法必须包含搜索过
程,并且当搜索不成功时实施新节点插入操作。
二叉搜索树的插入:
pTree TreeInsert(pTree root, datatype key){ pTree p; if(root == NULL) { p = (Tree *)malloc(sizeof(Tree)); p->data = key; p->lchild = NULL; p->rchild = NULL; return (p); } else { switch(Compare(root->data, key)) { case 0: return (root); case -1: root->rchild = TreeInsert(root->rchild, key); return root; case 1: root->lchild = TreeInsert(root->lchild, key); return root; //在左右子树插入后返回原根指针 } } return NULL;}
2.3 二叉树的删除
删除后仍需保持为一颗二叉搜索树,设被删节点为P,其双亲节点为F,P是F的左孩子,则有一下3中情况:
(1) P为叶节点,只需将F的左指针为空
(2) P只有一棵非空子树,则删除P并直接令P的该非空子树为F的左子树,即以P的非空子树取代P的位置
(3) P有两个非空子树,只需将该元素替换为它的左子树中的最大值或者则是右子树的最小值
二叉搜索树的删除
//返回值0为成功返回,-1为未找到int DeleteTree(pTree root, datatype key){ Tree *parent=NULL, *p = root; Tree *q, *child; while(p) { if(p->data == key) break; parent = p; p = (key < p->data) ? p->lchild : p->rchild; } if(!p) return -1; //找不到被删节点返回 q = p; if(q->lchild && q->rchild) //q的两个孩子均非空,则找q的中序后继p for(parent = q, p = q->rchild; p->lchild; parent = p, p = p->lchild) ; child = (p->lchild) ? p->lchild : p->rchild; if(!parent) root = child; else { //p不是根,则将p的孩子和p的双亲进行链接,p被删除 if(p == parent->lchild) parent->lchild = child; else parent->rchild = child; if(p != q) q->data = p->data; } free(p); return 0;}
3 AVL树
空的二叉树是AVL树,如果T是一棵非空的二叉树,TL和TR分别是左子树和右子树,则T满足以下条件时,T是一棵AVL树
(1) TL和TR是AVL树
(2) |hL-hR|<=1,TL和TR分别是左子树和右子树的高度
AVL搜索树既是二叉搜索树,也是AVL数
基本操作实现:
3.1 AVL数的搜索
因为n个元素的AVL树的高度是O(log2(n)),所以搜索所需时间是O(nlog2(n))
3.2 AVL搜索树的插入
AVL数的插入算法应在二叉搜索树的插入算法基础上扩充以下功能:
(1) 判断插入节点之后是否失平衡
(2) 若是,寻找最小失衡子树并跳转
(3) 判断失衡类型并做相应调整
#include "stdio.h"typedef struct info {int key;}element;struct tree_node {struct tree_node * left_child; element data; short int bf; struct tree_node* right_child;};typedef struct tree_node tree;typedef struct tree_node *AVL_pt;int IS_FULL(AVL_pt ptr){return (!ptr);}void left_rotation( AVL_pt parent , int *unbalanced ){ AVL_pt grand_child , child ; child = parent->left_child ; if ( child->bf == 1 ){ /* LL 转置 */ parent->left_child = child->right_child ; child->right_child = parent ; parent->bf = 0 ; parent = child ; } else { /* LR 转置 */ grand_child = child->right_child ; child->right_child = grand_child->left_child ; grand_child->left_child = child ; parent->left_child = grand_child->right_child ; grand_child->right_child = parent ; switch( grand_child->bf ){ case 1: parent->bf = -1 ; child->bf = 0 ; break ; case 0: parent->bf = child->bf = 0 ; break ; case -1: parent->bf = 0 ; child->bf = 1 ; } parent = grand_child ; } parent->bf=0; *unbalanced=0 ; } void insert( AVL_pt parent , element x , int *unbalanced ){ if ( !parent ){ /* 插入新元素 */ *unbalanced = 1 ; parent= (AVL_pt) malloc(sizeof(tree)) ; if (IS_FULL(parent) ){ printf("The memory is full\n" ) ; exit(1) ; } parent->left_child = ( parent )->right_child = NULL ; parent->bf = 0 ; parent->data = x ; } else if ( x.key < ( parent )->data.key ){ insert(parent->left_child , x , unbalanced ) ; if ( *unbalanced ) /* 左支树高 */ switch( ( parent )->bf ){ case -1: ( parent )->bf = 0 ; *unbalanced = 0 ; break ; case 0: ( parent )->bf = 1 ; break ; case 1: left_rotation( parent , unbalanced ) ; } } else if ( x.key > ( parent )->data.key ){ insert(parent->right_child , x , unbalanced ) ; if ( *unbalanced ) /*右支树高*/ switch ( parent->bf ){ case 1: parent->bf = 0 ; *unbalanced = 0 ; break ; case 0: parent->bf = -1 ; break ; case -1:// right_rotation( parent , unbalanced ) ; } } else { *unbalanced = 0 ; printf( "The key is already in the tree" ) ; }}void main(){int unbalanced=0;element x;AVL_pt root;x.key=10;root=NULL;insert (root, x, &unbalanced );}
- 搜索查找 - 算法学习
- 二分查找(折半搜索)算法
- 搜索算法之二分查找
- 搜索算法--二分查找(python)
- 查找算法之顺序搜索
- 查找算法之二分搜索
- 搜索算法----二分查找(折半查找)
- 搜索算法-顺序查找和二分查找
- 二分查找算法、折半搜索、二分搜索
- 搜索算法-二分搜索(折半查找)
- 编程珠矶学习笔记(5)--两分搜索算法(折半查找算法)
- 两分搜索算法(折半查找算法)
- 查找算法之折半搜索算法
- 算法查找学习笔记
- 查找算法学习笔记
- 算法学习--二分法查找
- 算法学习-二分查找
- 二分搜索算法(折半查找)
- 数据结构实验一(类模板与多文件结构) 终于补上...
- DFA+dp+zoj2337
- C++经典面试题--单例模式
- U-boot源码解析
- Mahout 第一章 学习笔记 思维导图
- 搜索查找 - 算法学习
- fedora 20 可用的键盘快捷键(官方帮助文档)
- mbed OS - ARM关于物联网(IoT)的战略布局
- Populating Next Right Pointers in Each Node
- PAT 3-05 求链式线性表的倒数第K项(C语言实现)
- hdu Paint Pearls 5009
- spring mvc整合easyui菜单栏目树点击顶级菜单问题
- Linux下置空文件的方法小结
- php Laravel框架学习(四) 之 表单与HTML