查找
来源:互联网 发布:java怎么定义数组 编辑:程序博客网 时间:2024/04/30 16:38
1. 顺序查找:
对线性表顺序扫描进行查找,顾名思义,无需多言。其时间代价为O(n).
2. 二分查找:
要求线性表中元素是有序的。其时间代价为O(lgn).
缺点:不能用链表作存储结构,因此,当表的插入或删除操作频繁时,为维护表的有序性,需要移动表中很多记录。这种由移动记录引起的额外时间开销,就会抵消二分查找的优点。
int BinSearch(LineList R[],int n,KeyType k){int i,low=0,high=n-1,mid; //注意这里有些是从1到n,要谨慎处理int find=0; //=0表示未找到,=1表示已找到while(low<=high && !find){mid=(low+high)/2;if(k < R[mid].key)high=mid-1;else if(k > R[mid].key)low=mid+1;else{i=mid;find=1;}}if(find==0)return -1;elsereturn i;}
3. 二叉查找树:
弥补二分查找关于动态查找的缺点,用二叉树作为表的组织形式。时间代价为O(lgn)它或者是一棵空树,或者是一棵具有以下特点的非空二叉树:
(1)若左子树非空,则左子树所有节点关键字均小于根结点的关键字;
(2)若右子树非空,则右子树所有节点关键字均大于(大于等于)根结点关键字;
(3)左右子树本身又各是一棵二叉查找树。
其链式存储结构节点类型为:
typedef struct tnode{ KeyType key; ElemType data; struct tnode *lchild,*rchild;}BSTNode;
基本运算如下所示:
//查找BSTNode *BSTSearch(BSTNode *bt,KeyType k){BSTNode *p=bt;while(p!=NULL && p->key!=k){if(k < p->key)p=p->lchild;elsep=p->rchild}return p;}
//插入int BSTInsert(BSTNode *&bt,KeyType k){BSTNode *f,*p=bt;while(p!=NULL){if(p->key==k) return 0;f=p; //f指向*p节点的双亲节点if(p->key > k)p=p->lchild;elsep=p->rchild;}p=(BSTNode *)malloc(sizeof(BSTNode));p->key=k;p->lchild=p->rchild=NULL;if(bt==NULL)bt=p;else if(k < f->key)f->lchild=p;else f->rchild=p;return 1;}
//创建二叉查找树void CreateBST(BSTNode *&bt,KeyType str[],int n){bt=NULL;int i=0;while(i<n){BSTInsert(bt,str[i]);i++;}}
//删除int BSTDelete(BSTNode *&bt,KeyType k){BSTNode *p=bt,*f,*r,*f1;f=NULL; //p指向待比较节点,f指向*p的双亲节点while(p!=NULL && p->key!=k){ //查找值域为k的节点f=p;if(p->key > k)p=p->lchild;elsep=p->rchild;}if(p==NULL) //未找到值域为k的节点return 0;else if(p->lchild==NULL){ //*p为被删节点,若他无左子树。都是用右孩子代替if(f==NULL)bt=p->rchild;else if(f->lchild==p){f->lchild=p->rchild;free(p);}else if(f->rchild==p){f->rchild=p->rchild;free(p);}}else if(p->rchild==NULL){ //*p为被删节点,若他无右子树。都是用左孩子代替if(f==NULL) bt=p->lchild;else if(f->lchild==p){f->lchild=p->lchild;free(p);}else if(f->rchild==p){f->rchild=p->lchild;free(p);}}else{ //*p为被删节点,若他有左子树和右子树f1=p;r=p->lchild; //查找*p的左子树中的最右下节点*r.它一定是无右子树的节点,*f1作为r的双亲while(r->rchild!=NULL){f1=r;r=r->rchild;}if(f1->lchild==r) //无论是左孩子还是右孩子,都删除*r,用它代替*pf1->lchild=r->rchild;else if(f1->rchild==r)f1->rchild=r->lchild;r->lchild=p->lchild;r->rchild=p->rchild;if(f==NULL)bt=r;else if(f->lchild==p)f->lchild=r;elsef->rchild=r;free(p);}return 1;}
还是那句话,画个图就清晰了。
4. 红黑树(二叉平衡树):待续
5. hash查找:
最关键的就是找到一个好的hash函数,然后有好的解决冲突的方法。
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- 查找
- linux多线程
- 排序算法的稳定性
- cookie
- DIV覆盖DIV
- 解决VC中图像缩小失真的问题:利用CDC::SetStretchBltMode
- 查找
- Linux的Netfilter框架深度思考-对比Cisco的ACL-
- 今晚计划
- 【转】2011年最佳的 Linux 发行版
- 36.VC(custom)-SetWindowRgn注意点
- J2EE-RBAC权限管理
- 孩子,我首先希望你自始至终都是一个理想主义者
- Linux平台VPN技术概论
- Hypertable 简介 (Hypertable一个 C++ 的Bigtable开源实现)