常用查找算法原理总结

一、静态查找表

1、顺序查找表:设置界(0~n),然后从头比到尾,有则返回!
  顺序查找表plus:把原来的界(0~n)改为设置哨兵R[0]或者R[n],当比较到R[0](从后往前比)或者R[n](从前往后比)还没有相等的时候,就是没有!否则,有则返回!这样省略了每次都要判断是否到了界点的步骤!
2、有序查找表:“最基本”的是折半查找!首先和R[m]=R[(0+n)/2]比较,如果小于则和R[p]=R[(0+(m-1))/2]比较,大于则和R[q]=R[((m+1)+n)/2]比较!一次类推!注意第二次计算的时候分别是相邻位置!即m-1和m+1
  差值查找:只给出确认下一个查找点的公式:(key-R[low])/(R[high]-R[low]);
  斐波那契:辅助公式就是斐波那契数列!首先确认当前数列长度n位于斐波那契数列数值的哪一索引位置,假设在k位(即F(k)-1

二、动态查找表

1、二叉排序树:每个子树都有左孩子>根节点>右孩子的大小关系
  查找:使用递归,小于当前节点则王左子树上查找,否则往右子树查找!直到匹配到或者当前节点为空则查找结束,返回当前节点即可!
  插入:查找成功,则无需插入!否则,由于查找不成功的时候返回的是紧挨着key值的节点(大于或者小于)且左右孩子都为空,这个时候如果大于则插入右节点,否则插入左节点!
  删除:删除是比较复杂的!假设被删除节点为p,在大话数据结构中叙述:

1. 如果p右子树为空则,则重接左子树;p左子树为空,则重接右子树;

分析:
重接在带指针的C语言中很好实现,即直接把p节点的指针地址赋给其左右孩子就行了!那么p节点的父节点顺着指针地址遍历,就发现原来本该是p的数值,就变成了p的左/右孩子节点!但是在java中,要想重接就必须找到p节点的父节点然后让父节点的指针指向p节点的孩子节点!即C语言中是直接变更p孩子节点的地址(孩子节点直接继承p节点的地址),java中由于没有地址操作,所以必须由父节点原来指向p的指针重新指向p的孩子节点!打个比方,比如在“父债子还”这个过程中,C语言的世界可以让孩子直接住到父亲的房子所在的地址中,下回讨债时还是去父亲的住宅中,就可以了(p的父节点一直指向p节点的地址就行了,孩子节点会自动替换p节点)!但是在java的世界中,不能让某个地址的人换主人(不能操控地址),所以必须告诉讨债的人,你下回讨债的时候去孩子的住宅(即p的父节点必须变更自己孩子节点的指向)!所以问题就来了,在java中,我们必须获取p节点的父节点,以及p是其父节点的左节点还是右节点,这样才能在重接的时候知道p的父节点是应该把左节点改为p的孩子节点还是右节点改为p的孩子节点!

2. 左右子树都不为空则重接前驱节点!

分析:
(2.1)前驱节点的确定:首先p节点“左拐”找到左孩子节点s,然后s一路右拐,直到没路了(s的右节点一直遍历直到为空),那么s就是前驱节点!
(2.2)重接:这里的重接是把p节点的数据直接替换为前驱节点的值,当然由于直接替换值并不能保持各个节点的原来连接关系,所以还需要在替换完值后进行重新排序,毕竟用前驱节点值替换p节点的值,就相当于删除前驱节点,所以要重新排序!具体方法就是,设置变量q记录前驱节点的父节点,然后就把前驱节点s的父节点q指向s节点的孩子节点就行了!(因为s一直向右遍历直到为空,所以实际上s只有左孩子,所以直接指向s节点的左孩子就行了)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值