数据结构学习笔记

本文深入讲解了二叉搜索树的查找、销毁方法,单项链表、双向链表的操作技巧,栈与队列的不同实现方式,以及哈希表的原理与冲突解决策略。探讨了字符串的深拷贝和运算符重载的正确实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、二叉搜索树的查找

(1)传统的递归

(2)非递归查找,就硬是循环得了

(3)遍历的递归与非递归方式

 

2、销毁二叉树的方法

(1)需要采用后续遍历的方式(左右中)可以采用递归,简单点

(2)注意传递二级指针或者指针引用

 

3、单项链表

(1)根据索引找到想要操作的节点就可以了

(2)删除全部节点时可以关注下二级指针的问题(避免野指针)

 

4、双向链表(双向就是循环了吗)

(1)注意在根据索引来查找节点时,判断下在前半部分还是后半部分,在通过next或pre偏移,可以有效的减少查找的次数

(2)主要是把想要操作的节点找出来,然后修改他们的前后指针的指向就没啥问题了,与单项链表差不多,复杂不到那里去。

 

5、栈的实现

(1)基于数组来实现:就用[0]来作为栈底元素,数组增长的方向为栈顶的方向,对数组尾巴进行压栈和出栈操作即可。

(2)基于单项链表的实现:用表头作为栈顶,每次的压栈都从表头开始插入,出栈也从表头进行,相对简单。

 

6、队列

(1)元素只能从队尾一端进入队列,元素只能从队首出队列

(2)基于数组实现的循环队列:因为每次从数组头部删除元素(出队)后,需要将头部以后的所有元素往前移动一个位置,时间复杂度位O(n)。如果知识把队首的标志往后移动,就会造成数组空间的流失。我们希望队列的插入和删除操作都是O(1),同时不造成空间的浪费,应该使用循环队列。所谓的循环队列,可以把数组看作一个首位相连的圆环,删除元素时将队首标志往后移动,添加元素时若数组尾部已经没有空间,则考虑数组头部是否空闲,如果是,则在数组的头部进行插入。

栈空:队首标志==队尾标志,表示栈空

栈满:队尾 + 1 == 队首,表示栈满。此时其实还有一个位置,不进行存储

 

(3)基于单向链表实现的队列:以链表头部作为队首,链表尾部作为队尾。存储一个指向队尾的指针,方便从链表尾部插入元素,使用表头,方便从队首删除元素。

 

7、字符串string实现

(1)string的拷贝构造要实现深拷贝,避免浅拷贝带来的内存共享导致的问题

(2)关于operator》和operator《运算符的重载,建议设计成友元函数,不设计成成员函数。因为如果是成员函数,必须通过对象来调用,不符合《》的使用习惯

 

8、哈希表(散列表)

(1)哈希表包含一个数组,通过特殊的索引值(键)来访问数组中的元素(可以理解为散列表和散列函数)

(2)哈希表的主要思想是通过一个哈希函数,在所有可能的键与槽位之间建立一张映射表。哈希函数每次接受一个键,将返回与键对应的哈希编码或者哈希值。键的数据类型可能各种各样,但哈希值只能是整型。当哈希函数能够保证不同的键生成的哈希值互不相同时,就说哈希值能直接寻址想要的结果。

 

(3)哈希表的实现:其中的原理就是用哈希函数来将键值映射为数组的下标,存放对应的数据。哈希函数才是整个实现的关键。因为好的哈希函数要保证数据索引的均匀分配,不浪费空间,较少冲突。

 

(4)哈希函数设计的考虑因素

a、计算散列地址所需要的时间

b、关键字的长度

c、表长

d、关键字分布是否均匀,是否有规律

e、在满足以上条件的情况下尽量减少冲突

 

(4)处理冲突的方法:

a、链地址法:如果遇到冲突,会在原地址新建一个空间,然后以链表结点的形式插入到该空间中。

b、开放定制法:如果遇到冲突,按照一定的探测再散列的法则,向前寻找其他的地址空间,最终合起来算全部的地址位置。(线性探测、平方探测、随机探测等。。。)

 

(5)哈希表的查找效率

a、选用的哈希函数

b、选用的处理冲突的方法

c、哈希表的饱和度?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值