1.数据结构和算法的基础笔记
解决具体的问题,首先要把具体的问题抽象成为数学模型,要想得到模型,必须知道数据之间的关系,在数据结构中数据之间的关系主要有
1.线性数据结构
栈和队列
数据和广义表
线索二叉树
两种,线性关系和非线性关系,其中非线性关系又分为属性关系和图关系。
基本的术语:
数据 数据元素 数据项(项或者字段) 结构(关系)原子类型 结构类型
ADT(抽象数据组织和与之相关联的操作)
ADT 抽象数据的类型名{
数据对象
数据关系
基本操作
}
算法:正确性,确定性,有穷性,输入,输出,要求:正确性,可读,健壮,效率以及存储的效率
1.线性数据结构
线性表的定义:前驱和后继 ,数据元素,记录,数据项,
顺序表:数组,存储结构,每一个元素的位置:di = dl+(i-1)*C
> 多维数组的存储方式
单链表:基本操作,删除节点,添加节点,尾插法(增加一个尾指针),头插法
循环链表:循环的条件在于判断:curr.next() != head
双链表:删除,添加,查找。
查找算法,比较有意思的一点:
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {//前半截从头开始查
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {//后半截从尾巴开始查
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
} 链表应用:
链式存储下一元多项式的加法
链式链表按照一定的顺序(每隔几个元素)删除一定的元素
链表
栈和队列
堆栈的基本的操作:堆栈的初始化,判端栈空操作,判断栈满的操作,取顶端的元素,出栈,入栈,
堆栈的应用:数制的转换,表达式的计算和判断,转换问题和递归问题
》》》 表达式判断是否合法的一些思考》》》》》》》》》》》》》》》》》》》
表达式的正确的判断,如果栈中只保存括号的问题,那么我们可以在见到 ) } ] 的时候
直接的pop() 一直到见到相对应的左边的括号,或者返回false。
但是上面的这种讨论的不能够兼容 122()4345, /34,++++(), 5+6++,这种类型,也就是说
运算符号的确定我们应该怎么去判断呢?
抽取表达式的规则:每一个运算符必须全面是数字,后面也必须是数字。这个是针对中序表达式
的说法。
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
递归的非递归的实现。
队列的定义和基本的操作
循环存储
置空队列,判队空,判队满,出队,入队,取队首的元素
入队操作:
public void addLast(E e) {
if (e == null)
throw new NullPointerException();
elements[tail] = e;
if ( (tail = (tail + 1) & (elements.length - 1)) == head)
doubleCapacity();
} public boolean add(E e) {
addLast(e);
return true;
} 出队:
public E pollFirst() {
int h = head;
E result = elements[h]; // Element is null if deque empty
if (result == null)
return null;
elements[h] = null; // Must null out slot
head = (h + 1) & (elements.length - 1);
return result;
}
采用的是 & 的操作,感觉比较的有趣啊,不是采用的余数操作。
链表队列:和单聊表差不多,只不多保留了队尾和队头指针。
应有:
合并两个队列
模拟客户服务系统
数据和广义表
一维数组(向量),多维数组
一维数组的存储:loc(ai) = loc(a1)+(i-1)*c
多维数组存储分为行优先存储和列优先存储。
矩阵的压缩存储:针对的是对称据陈,稀疏矩阵,三角矩阵
广义表
树,二叉树
节点的度,树的度,叶子,终端节点,父节点,子节点,兄弟节点
总结点数:所有的儿子节点+根节点
总结点数:所有(有度)的节点的总和
满二叉树,完全二叉树
因此:某一个节点如果没有左节点,那么它一定没有右节点,即它必然是叶子节点。
线索二叉树
线索二叉树的数据结构:lchild | ltag | data | rtag | rchild
ltag =0;//lchild指向节点的左节点
ltag=1;//lchild指向节点的前驱节点的左线索
rtag =0;//rchild指向节点的右节点
rtag=1;//rchild指向节点的前驱节点的右线索
前序 的线索二叉树,中序的线索二叉树,后续的线索二叉树。
线索二叉树的运算:
看到这章的内容,就想起来自己的那次安全公司的面试经历,关于树或者字符串匹配算法的,自己不能够清晰的讲出来具体的算法的过程,印象中当时可是复习了很多遍的,具体的原因就在于自己没有亲手的写代码,别说是在白纸上面书写,就是在工具中也没有写,这个是比较大的弊端。
哈弗曼树,最优二叉树(哈弗曼树的构建)
非线性数据-图
G=(V,E) 顶点和边,有向图,无向图,子图,完全图,邻节点,相关边,度,入度,出度,路径,回路,权,带权图
图的存储:邻接矩阵
邻接图,邻接表和邻接图的转换。
遍历算法:深度优先算法和广度优先算法
最小生成树和最短路径