数据结构和算法

1:链表与数组

2:队列和栈,出栈与入栈

3:链表的删除,插入,反向

4:字符串操作

5:hash表的hash函数,冲突解决方法有哪些?

1.开放定址法

线性探测再散列

二次探测再散列

伪随机探测再散列

2.再哈希法

这种方法是同时构造多个不同的哈希函数

3.链地址法 (java的HashMap采用这种方法)

4.建立一个公共溢出区

将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表

6:排序的原理,平均时间复杂度,最坏时间复杂度,空间复杂度,是否稳定

冒泡:平均时间复杂度为 O(n2),空间复杂度 O(1)

选择:平均时间复杂度为 O(n2), 空间复杂度 O(1)

插入:平均时间复杂度为 O(n2), 空间复杂度 O(1)

希尔:对插入排序,数据量巨大的时候, 平均时间复杂度为 O(nlog2n), 空间复杂度 O(1)

 

(1) 将数的个数设置为n,取奇数k = n/2,

(2) 将差值为K的数分为一组,构成有序序列

(3) 再取k = k/2,将差值为K的数分为一组,构成有序序列

(4) 重复3直到K=1执行插入排序

快排:要求时间最快时,平均时间复杂度为 O(nlog2n), 空间复杂度 O(nlog2n)

(1) 选择第一个数为P,小于P的放在左边,大于P的放在右边

(2) 递归的将P左边的和右边的都按照(1)直到不能递归

归并:速度仅次于快排,内存小的时候使用,可以进行并行计算的时候使用,O(nlog2n), 空间复杂度 O(n)

(1)选择相邻的两个数组成一个有序数列

(2)选择相邻的两个有序数列成一个有序数列

(3)重复第二步

堆排:

(1)建堆

(2)调整堆

 

桶排:

基数:用于大量数,很长的数进行排序

7:快排的parition函数与归并的Merge函数

private static int getMiddle(int[] list, int low, int high) {

int tmp = list[low]; // 数组的第一个作为中轴

while (low < high) {

while (low < high && list[high] >= tmp) {

high--;

}

list[low] = list[high]; // 比中轴小的记录移到低端

while (low < high && list[low] <= tmp) {

low++;

}

list[high] = list[low]; // 比中轴大的记录移到高端

}

list[low] = tmp; // 中轴记录到尾

return low; // 返回中轴的位置

}

public static void merge(int[] data, int left, int center, int right) {

int[] tmpArr = new int[data.length];// 临时数组

int mid = center + 1;// 右数组第一个元素索引

int third = left;// third 记录临时数组的索引

int tmp = left;// 缓存左数组第一个元素的索引

while (left <= center && mid <= right) {

if (data[left] <= data[mid]) {

tmpArr[third++] = data[left++];

} else {

tmpArr[third++] = data[mid++];

}

}

// 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)

while (mid <= right)

tmpArr[third++] = data[mid++];

while (left <= center)

tmpArr[third++] = data[left++];

// 将临时数组中的内容拷贝回原数组中

// (原left-right范围的内容被复制回原数组)

while (tmp <= right)

data[tmp] = tmpArr[tmp++];

}

8:对冒泡与快排的改进

9:二分查找,与变种的二分查找

二分查找: mid=low+(high-low)/2

变种二分查找:

插值查找二分查找:

mid=low+(key-a[low])/(a[high]-key)*(high-low)

斐波那契查找算法:

mid=low+F(k?1)?1

10:二叉树

11:AVL树(平衡二叉树的一种)

绝对的平衡二叉树,不过增删的操作复杂度过高,应用不如红黑树广

LL:某一节点的左孩子的左子树上插入一个新的节点,使得该节点不再平衡。这时只需要把树向右旋转一次即可

RR:某一节点的右孩子的右子树上插入一个新的节点,使得该节点不再平衡。这时只需要把树向左旋转一次即可

LR:某一节点的左孩子的右子树上插入一个新的节点,使得该节点不再平衡。这时需要旋转两次,左旋+右旋

RL:某一节点的右孩子的左子树上插入一个新的节点,使得该节点不再平衡。这时需要旋转两次,右旋+左旋

12:红黑树(平衡二叉树的一种)

(1)每个节点或者是黑色,或者是红色。

(2)根节点是黑色。

(3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]

(4)如果一个节点是红色的,则它的子节点必须是黑色的。

(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

左旋:对x进行左旋,意味着 将x变成一个左节点

右旋:对x进行右旋,意味着 将x变成一个右节点

添加:第一步: 将红黑树当作一颗二叉查找树,将节点插入。

  第二步:将插入的节点着色为"红色"。

  第三步: 通过一系列的旋转或着色等操作,使之重新成为一颗红黑树。

删除:第一步:将红黑树当作一颗二叉查找树,将节点删除。

  第二步:通过"旋转和重新着色"等一系列来修正该树,使之重新成为一棵红黑树。

13        Treap(树堆)

14:哈夫曼树

15:二叉树的前中后续遍历,递归非递归写法,层序遍历算法

递归是自己调用自己

非递归是使用堆栈

16:KMP算法

17:排列组合问题

18:动态规划,贪心算法,分治算法

19:跳表的数据结构

一种可以代替平衡树的数据结构

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值