1* 绪论
程序设计=数据结构+算法
数据项是数据不可分割的最小单位
逻辑结构:
数据对象中数据元素之间的相互关系
集合机构 线性结构 树形结构 图形结构
物理结构:
数据的逻辑结构在计算机中的储存形式
顺序储存 链式存储
2* 算法
算法是解决待定问题求解步骤的描述,在计算机中表现:
有限序列,并且每条指令表示一个或多个操作
算法的特性:
输入、输出、有穷性、确定性(无二义)和可行性
算法设计要求 :正确性 可读性 健壮性 高效率 低储存量
算法度量方法:事后统计方法(不科学、不准确)、事前分析估算方法
推导大O阶:
1.用常数1取代运行时间中的所有加法常数
2.在修改后的运行次数函数中,只保留最高阶项
3.如果最高阶项存在且不是1,则去除与这个项相乘的常数
空间复杂度
S(n)= O(f(n)) n为问题的规模,f(n)为语句关于n所占储存空间的函数
3* 线性表
数组的长度和线性表的长度:
线性表的长度表示线性表中数据元素的个数,是可以变化的
数组的长度是存储空间的长度,一般是不变的
静态链表(游标实现法)
双向链表
先搞定s的前驱和后继
再搞定后结点的前驱
解决前结点的后继
4* 栈与队列
栈
栈是限定仅在表尾插入和删除操作的线性表
允许插入和删除的一端称为栈顶(top)另一端称为栈底(bottom)
栈又被称为后进先出(last in first out)线性表 ,简称LIFO结构
进栈 push 出栈 pop
栈的顺序储存结构的实现
栈的结构定义
class stack{
int[] data = new int[10]; //类型多变,假设为int
int top = -1; //栈顶指针,通常为-1
}
两栈共享空间
栈1为空时,top1=-1,栈2为空时,top2=n
两栈见面之时,top1+1 == top2 栈满
class SqDoubleStack{
Object data[MAXSIZE];
int top1;
int top2;
}
栈的链式存储结构及实现
public class LinkedStack {
private int size ;
private StackNode top ;
public void push(Object obj){
top = new StackNode(obj,top);
size++;
}
public void pop(){
StackNode oldnode = top;
top = top.next;
oldnode.next = null;
size--;
}
public static void main(String[] args) {
LinkedStack stack = new LinkedStack();
stack.push("aaa");
stack.push("ok");
System.out.println(stack);
}
}
class StackNode{
public Object value;
public StackNode next;
public StackNode(Object value, StackNode next) {
this.value = value;
this.next = next;
}
}
栈的应用——逆波兰表示
队列
队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端叫队尾,允许删除的一端称为队头
顺序存储
队列满的条件: (rear+1) % QueueSize == front
队列长度公式: (rear - front + QueueSize) % QueueSize
5* 串
串是由零个或多个字符组成的有限序列,又名叫字符串
顺序存储结构
用一组地址连续的存储单元来存储串中的字符序列,一般用定长数组来定义
链式存储结构
与线性表相似 总体来说不如顺序存储灵活,性能不如顺序存储结构好
朴素的模式匹配算法
就是在串中找子串的问题
首先对主串做大循环,每个字符开头做小循环
时间复杂度为0((n-m+1)*m)
KMP模式匹配算法
KMP: 克努特—莫里斯—普拉特
算法:
重点:求next数组
void get_next(String T, int[] next){
int j = 1, t = 0;
next[1] = 0;
while( j < T[0]) { //T[0]表示串T的长度
if(t==0 || T[j] == T[t]){ //T[j]表示后缀的单个字符
//T[t]表示前缀的单个字符
++j;
++t;
next[j] = t;
}else{
t = next[t]; //如果字符不相同,t回溯
}
}
}
KMP算法
int KMP(String str, Str substr, int next[]){
int i = 1, j = 1;
while(i<= str.length() && j <= substr.length()){
if(j == 0 || str[i] == substr[j]){
++i;
++j;
}else{
j = next[j];
}
}
if(j > substr.length()){
return i- substr.length();
}else{
return 0;
}
}