本文内容大致参考 书籍 《Java数据结构和算法》 第二版
1. 大O表示法(数组)
- 无序数组的插入:常 T = K;
- 线性查找:与N成正比 T = K*N;
- 二分查找:与log(N)成正比 T=K*log(N);
1.1 用大O表示法表示运行时间
大O表示法只是表达了运行时间是如何受数据项个数所影响的;
N:个数项
O(N):耗时与个数项相同;
O(1):直接根据索引进行对应操作,无论数组的个数项多少,话费的时间都是一定的;
O(logN):二分操作,对应耗时也是与个数项 log(N)成正比;
1.2 大O时间的图
2.简单排序
2.1 冒泡排序
交换次数和比较次数都为 O(N^2);
//排序
public void bubbleSort(){
int out,in;
for (out = nElems-1; out>1 ; out--) {
for (in = 0; in <out ; in++) {
if(initArr[in]>initArr[in+1]){
swap(in,in+1);
}
}
}
}
//换位
public void swap(int one,int two){
long temp = initArr[one];
initArr[one] = initArr[two];
initArr[two] = temp;
}
2.2 选择排序
交换次数O(N) ,比较次数O(N^2);
效率:由于记录需要在内存中移动,所以交换时间的权重是大于比较时间的 所以效率比冒泡排序会快很多;
不变性:下表小于或等于out的为止的数据项总是有序的;
//排序
public void selectSort(){
int out,in,min;
for (out = 0; out<nElems-1 ; out++) {
//每做一次循环就减少一次循环
min = out;
for (in = out+1; in <nElems ; in++) {
if(initArr[in]<initArr[min]){
min = in;
}
swap(out,min);
}
}
}
//换位
public void swap(int one,int two){
long temp = initArr[one];
initArr[one] = initArr[two];
initArr[two] = temp;
}
2.3 插入排序
交换次数O(N) ,比较次数O(N^2);
不变性:每趟结束在将temp位置的项插入后,比out变量下标号小的数据项都是局部有序的;
public void insertSort() {
int in, out;
for (out = 1; out < nElems; out++) {
long temp = initArr[out];
in = out;
while (in > 0 && initArr[in - 1] >= temp) {
initArr[in] = initArr[in - 1];
--in;
}
initArr[in] = temp;
}
}
3. 栈和队列
3.1 栈
-
栈只允许访问一个数据项:即最后插入的数据项,只有移除这个数据项后才能访问到倒数第二个插入的数据项;
-
大部分处理器运用基于栈的体系结构。当调用一个方法是,把它的返回地址和参数压入栈,当方法返回结束时,那些数据出栈;
数据项入栈和出栈的时间复杂度都为常数O(1);
//压入
public void push(char j) {
stackArray[++top] = j;
}
//弹出
public char pop() {
return stackArray[top--];
}
3.2 队列
- 队列是一种数据结构,类似栈,只是在队列中第一个插入的数据项也会最先被移除(先进先出,FIFO),而在栈中最后插入的数据项会最先移除(LIFO)。
队列中插入数据项和移除数据项的时间复杂均为O(1)
public void insert(long j){
if(rear == maxSize-1){
rear = -1;
}
queArray[++rear] = j;
nItems++;
}
public long remove(){
long temp = queArray[front++];
if (front == maxSize) {
front = 0;
}
nItems--;
return temp;
}
3.2.1 双端队列(不常用)
定义两端插入和移除 insertLeft(),insertRight(),removeLeft(),removeRight()
顾名思义,两端都是结尾的队列,队列的每一端都可以插入数据项和移除数据项。如果禁止调用insertLeft(),removeLeft()的插入和移除,双端队列的功能就和栈一样了,如果禁止insertLeft(),removeRight()那它的功能就和队列一样了。
3.2.2 优先级队列
类似普通队列,优先级队列有一个对头和对位,并且也是从对头移除数据项,但是在优先级队列中,数据项按关键字的值有序,这样关键字的最小数据项总是在对头,数据项插入的时候会按照顺序插入到适合的为止以确保队列的顺序。
时间复杂度:插入O(N),删除O(1)
public void insert(long item) {
int i;
if (nItems == 0) {
queueArray[nItems++] = item;
} else {
for (i = nItems-1; i >= 0; i--) {
if (item > queueArray[i]) {
queueArray[i + 1] = queueArray[i];
} else {
break;
}
}
queueArray[i