数据结构4——查找
------------恢复内容开始------------
栈:后进先出
ElemType data[MaxSize];
int top;
};
以下是利用栈判断回文序列
boolsymmetry(inta[],intl){inti,e;Stack*s;InitStack(s);for(i=0;i<l;i++){Push(s,a[i]);}for(i=0;i<l;i++){Pop(s,e);if(a[i]!=e){DestroyStack(s);returnfalse;}}DestroyStack(s);returntrue;}intmain(){inta[]={1,2,3,2,1};cout<<symmetry(a,5);}
我们也可以利用链式存储完成栈的构建
#include <iostream> #include <stdlib.h> using namespace std; struct Stack//Struct Link { int data; Stack *next; }; void InitStack(Stack *&s) { s = NULL; } void DestroyStack(Stack *&s) { if(s==NULL){ return; } Stack *p=s,*q=s->next; while(q){ free(p); p=q; q=q->next; } free(p); } bool StackEmpty(Stack *s) { return(s==NULL); }//判断栈是否为空 void Push(Stack *&s,int e)//这里不是bool是因为链式存储一般不需要考虑栈满的情况 { if(s==NULL){ s=new Stack; s->next=NULL; s->data=e; return; } Stack *p=s; for(;p->next;p=p->next); p->next=new Stack; p=p->next; p->data=e; p->next=NULL; }//栈的操作只操作最后放入的元素,如果将后来的元素放在队尾部,会给后续操作带来不便 //如果只需要进行栈操作的话,入栈建议将数据放在头部 void Push2(Stack *&s,int e) { if(s==NULL){ s=new Stack; s->next=NULL; s->data=e; return; } Stack *p=new Stack; p->next=s; p->data=e; s=p; } bool Pop(Stack *&s,int &e) { if(s==NULL)return false; e=s->data; Stack *p=s; s=s->next; free(p); return true; } bool GetTop(Stack *&s,int &e) { if(s==NULL)return false; e=s->data; return true; }
队列:先进先出
(来源:mooc——数据结构——武汉大学)
队列需要有队首和队尾两个指针,其它基本操作的实现都可参考栈
将基础操作的rear++和front++改为
#include <stdlib.h> struct Queue { int data[5]; int front; int len; }; void InitStack(Queue *&s) { s=new Queue; s->front=0; s->len=0; } void DestroyStack(Queue *&s) { free(s); } bool StackEmpty(Queue *s) { return(s->len==0); } bool enQueue(Queue *&s,int e) { if(len==5)return false; s->data[(s->front+s->len)%5]=e; len++; return true; } bool deQueue(Stack *&s,int &e) { if(len==0)return false; e=s->data[s->front]; s->front=(s->front+1)%5; return true; }
------------恢复内容开始------------
一、线性表的查找
顺序查找:ASL成功=(n+1)/2 ASL不成功=n
二分查找:成功时最多的关键字比较次数为[log2(n+1)] 不成功时关键字比较次数为[log2(n+1)]
ASL成功=(n+1)/n*log2(n+1)-1≈log2{n+1)-1
分块查找:介于顺序查找和二分查找之间
二、二叉排序树
//二叉排序树 typedef struct node { int key; int data; struct node *lchild,*rchild; }BSTNode; BSTNode *SearchBST(BSTNode*bt,int k) { if(bt==NULL||bt->key==k)return bt; if(k<bt->key)return SearchBST(bt->lchild,k); else return SearchBST(bt->rchild,k); }
int InsertBST(BSTNode *&p,int k)//利用的是先序遍历的思想 { if(p==NULL) { p=new BSTNode; p->key=k;p->lchild=NULL;p->rchild=NULL; return 1; } else if(k==p->key)return 0;//存在相同关键字的节点返回0 else if(k<p->key)return InsertBST(p->lchild,k); else return InsertBST(p->rchild,k); }
可以看出二叉排序树应用了顺序遍历的思想
// 二叉排序树的删除 //查找被删除节点 int deletek(BSTNode *&bt,int k) { if(bt==NULL)return 0; if(k==bt->key) { deletep(bt); return 1; } else if(k<bt->key)deletek(bt->lchild,k); else deletek(bt->rchild,k); } //删除节点 void deletep(BSTNode *&p) { BSTNode *q; if(p->rchild==NULL) { q=p;p=p->lchild; free(q); } else if(p->lchild==NULL) { q=p;p=p->rchild; free(p); } else//左右子树都存在的情况 { for(q=p->lchild;q->rchild;q=q->rchild);//q指向p左子树最右下节点 p->key=q->key;p->data=q->data;//将要删除的节点替换为最右下的节点 BSTNode *temp=q;q=q->lchild;free(temp);//将原来最右下的节点删除 } }
平衡二叉树(AVL):一颗二叉树中每个节点的左右子树的高度至多相差1
三、哈希查找
解决冲突的方法:
开放定址法->线性探查法(堆积现象)、平方探查法(无法探查到哈希表上的全部单元)
数组形式:
#include <math.h> #include <iostream> #include <stdlib.h> using namespace std; int jp(int m)//判断是否为素数,否则返回0,是则返回最大因数 { for(int i=floor(sqrt((double)m));i<floor(m/2);i++) { if(m%i==0)return m/i; } return 0; } int maxp(int m){ int i=m; for(;jp(i);i--); return i+1; } //生成哈希表 //常见的hash函数(除留余数法) int hash(int key,int l)//l为hash表长度 { return key%maxp(l); }
class hashlist { protected: int * ListHead; int Lenth; public: hashlist(int l) { ListHead=(int*)malloc(l*sizeof(int)); Lenth=l; for(int i=0;i<Lenth;i++){ ListHead[i]=0; } } void create(int *keys) { int k,h,flag; for(int i=0;k=keys[i];i++) { for(h=hash(k,Lenth);ListHead[h%Lenth];h++)//线性探查法解决冲突 { if(ListHead[h%Lenth]==k) { cout<<"this key has already been put in:"<<k<<endl; break; } if(h-h%Lenth>=Lenth) { cout<<"this hashlist is full"<<endl; return; } }; ListHead[h%Lenth]=k; } cout<<"hashlist created"<<endl; } void show(){ cout<<Lenth<<endl; for(int i=i;i<Lenth;i++){ cout<<i<<":"<<ListHead[i]<<"\t"; } cout<<endl; } int search(int key) { int h=hash(key,Lenth),k; for(;ListHead[h%Lenth];h++) { if(ListHead[h%Lenth]==key)return h%Lenth; if(h-h%Lenth==Lenth)return 0; } return 0; } };
int main() { int a[]={1,2,3,3,4,5,0}; hashlist hash1(15); hash1.create(a); hash1.show(); cout<<hash1.search(4); }
运行结果:
this key has already been put in:3
hashlist created
0:0 1:1 2:2 3:3 4:4 5:5 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:0
4
拉链法:
//拉链法 d=hash(k); p=ha[d]; while(p!=NULL&&p->key!=k)p=p->next; if(p==NULL)return 0;//查找失败 else return p;//返回查找值所在节点
posted on 2020-05-31 14:06 crazyplayer 阅读(125) 评论(0) 编辑 收藏 举报