查找

来源:互联网 发布: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函数,然后有好的解决冲突的方法。


 

原创粉丝点击