编程思考

左右边界:  循环不变量
1、严格定义边界的实际意义是什么
2、明确变量的含义
3、循环不变量
4、小数据量调试

int l=0, r=n-1;   //在[l,r]的范围里操作,所以当l==r时,区间[l..r]依然是有效的

int l=0, r=n;   //在[l,r)的范围里操作,所以当l==r时,区间[l..r)是无效的  [42,42)
数组:
数组的索引可以有语义,也可以没有语义。
增、删、改、查、    每一种数据结构都可以要实现其中的一部分。
capacity 容量     size 实际有多少元素,size=0是指向了第一个没有存放元素的索引,向数组末尾添加元素,也就等同于向size索引处添加元素。size=capacity是指数组空间已满。
合法的索引:  index<0 || index>size   (index=size是指从数组的最后插入一个元素,如果index>size,则中间会存在不是合法的元素,元素不是紧密排列的) 
最后一个元素的索引是size-1   
动态数组
容器: 可以放置“任何”数据类型



栈:
只能从一端添加元素,也只能从一端取出元素
栈顶
程序调用的系统栈
栈顶元素反映了在嵌套的层次关系中,最近的需要匹配的元素


队列:
只能从一端(队尾)添加元素,只能从另一端(队首)取出元素
循环队列:  队首front(指向队列中的第一个元素)  队尾tail(指向下一次新的元素入队时应该存储的位置)  front=tali时队列为空   (tail+1)% c =fronts是队列为满
capaticy中,浪费了一个空间
假设队列有8个size大小,索引从7到0的变化是(index+1)% c
   
链表:  真正的动态数据结构
head:链表头,指向链表中的第一个节点
在链表头添加元素: node.next=head  head=node
在链表中间添加元素(关键是找到要添加节点的前一个节点): node.next=pre.next  prev.next=node
在链表末尾添加元素: 
虚拟头节点: dummyHead 则链表的第一个元素是dummyHead.next指向的元素
链表元素的删除: pre.next=delNode.next  delNode.next=NULL


链表和递归:
递归  本质上,将原来的问题,转化为更小的同一问题  
递归的宏观语义: 递归函数就是一个函数,完成一个功能
递归的微观解读: 
递归调用是有代价的  函数调用+系统栈空间
递归深度



二分搜索树: 是一颗二叉树  每个节点的值,大于其左子树的所有节点的值,小于其右子树所有节点的值 
存储的元素必须有可比较性

前序遍历    深度优先遍历
中序遍历     排序后的结果
后序遍历    应用:为二分搜索树释放内存
层序遍历   广度优先遍历   借助队列 
删除二分搜索树的最小值和最大值


集合:set  
映射 Map  


堆和优先队列
优先队列:  出队顺序和如入队顺序无关,和优先级有关  
二叉堆: 二叉堆是一颗完全二叉树   堆中某个节点的值总是不大于其父节点的值
1、数组从1开始  parent(i)=i/2   left child(i)=2*i   right child(i)=2*i+1
2、数组从0开始  parent(i)=(i-1)/2   left child(i)=2*i+1   right child(i)=2*i+2




线段树:


哈希表



 










           










 

你可能感兴趣的:(数据结构算法)