数据结构与算法分析 第三天

第三章 表 (栈还有队列的定义.)
这一章开始就是介绍一些经典的数据结构 .

1.表.
如果用数据实现的表,在删除还有插入中最坏 的情况是O(N) , 查找操作就是可以用常数的时间即 O(1)  能够快速的随机访问.
如果用链表来实现, 这里刚好是相反的.查找的操作 最坏的情况就是O(N),但是插入或者删除就是O(1)

2.iterator
------如果要用加强for循环 for(xx  : xxx) xx 必须实现iterator 接口.
  
  
public interface Iterator<E> {
//如果是用增强for 循环的话 先调用next 和 hashNext
//这个方法能够判断后面能不能继续访问.
boolean hasNext();
// 在数组相当于后移了一格. 在链表中就是跳到下一个地址.
E next();
//相对于collection中的remove 方法.这个remove方法是在遍历中直接删除的.并且不容易引起 COoncurrentModificationException异常的出现
void remove();
}

   
   
public interface ListIterator<E> extends Iterator<E> {
//继承回来的.
boolean hasNext();
E next();
void remove ();
//拓展能够从后向前的遍历.
boolean hasPrevious();
E previous();
int nextIndex ();
int previousIndex ();  
 
 
void set(E e);
void add(E e);
}

Iterator与ListIterator有什么区别?

  • Iterator是ListIterator的父接口。
  • Iterator是单列集合(Collection)公共取出容器中元素的方式。
  •        对于List,Set都通用。
  •        而ListIterator是List集合的特有取出元素方式。
  • Iterator中具备的功能只有hashNext(),next(),remove();
  •       ListIterator中具备着对被遍历的元素进行增删改查的方法,可以对元素进行逆向遍历。
  •       之所以如此,是因为ListIterator遍历的元素所在的容器都有索引。

栈的定义  

      栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表。  

  • 通常称插入、删除的这一端为栈顶 (Top),另一端称为栈底 (Bottom)。  
  • 当表中没有元素时称为空栈。  
  • 栈为后进先出(Last In First Out)的线性表,简称为 LIFO 表。  
  • 栈的修改是按后进先出的原则进行。每次删除(退栈)的总是当前栈中" 

 
栈的应用
  • 平衡符号
  • 后缀表达式.
  • 中缀到后缀的转换
  • 方法的调用(这个是重点.)


第四章  树
只能说简单的看懂了.但是没有做过几题题目什么的.只能空想主义了.!

  1. 二叉查找树(二叉排序树)
  2. 平衡二叉树(AVL树)
  3. 红黑树
  4. B-树
  5. B+树
  6. 字典树(trie树)
  7. 后缀树
  8. 广义后缀树





第五章 散列 
数组能够提供快速随机访问,但是难以拓展. 链表容易做增加删除,但是在查找的时候开销很大.
散列表提供了达到此目标的一种方法。

简单的术语:

  1. 关键字:元素的存储部分,数据库的元素通过它进行存储,查找等操作(也称作散列关键字)
  2. 散列表元:散列数组的某个位置,其后跟着另外一个包含其元素的结构
  3. 散列函数:对关键字和散列表元提供映射的函数
  4. 完全散列函数:对关键字和整数提供一一映射的函数

散列函数:

下面是一个最原始的散列 函数
但是最后散列的结果并不均匀. 书本上还提供了另外两种,但是我更想看看java 底层的hash 方法.
    
    
public static int hash(String key,int tableSize){
int hashVal = 0;
/**
* 这里对字符串key 中的每个字母进行相加,得到一个 hasVal;
*/
//模运算,看看这个值最后落到那个桶里面
return hashVal % tableSize ;
}

    
    
//计算hash值的方法 通过键的hashCode来计算  
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}

当hash函数出现相同值的时候 就会发现冲突.
解决冲突的方法有下列几种
1.开放定址法
    开放定址法的一般形式为: hi=(h(key)+di)%m 1≤i≤m-1 
    di为增量序列 有三种增量 线性,平方,随机
2.再哈希法:即重新计算哈希函数地址. 知道冲突不再发生.
3.链地址法:  将所有关键字为同义词的结点链接在同一个单链表中 ,这个也是hashmap所实现的方法.
4.建立一个公共溢出区.

链地址法与开放定址法相比,拉链法有如下几个优点:
  • (1)链地址法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
  • (2)由于链地址法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;
  • (3)开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;
  • (4)在用链地址法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。而对开放地址法构造的散列表,删除结点不能简单地将 被删结点的空间置为空,否则将截断在它之后填人散列表的同义词结点的查找路径。这是因为各种开放地址法中,空地址单元(即开放地址)都是查找失败的条件。 因此在用开放地址法处理冲突的散列表上执行删除操作,只能在被删结点上做删除标记,而不能真正删除结点。
链地址法的缺点
 链地址法的缺点是:指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指针空间用来扩大散列表的规模,可使装填因子变小,这又减少了开放定址法中的冲突,从而提高平均查找速度。

 






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值