1.大O表示法:粗略的量度方法即算法的速度是如何与数据项的个数相关的
算法 大O表示法表示的运行时间
线性查找 O(N)
二分查找 O(logN)
无序数组的插入 O(1)
有序数组的插入 O(N)
无序数组的删除 O(N)
有序数组的删除 O(N)
O(1)是最优秀的,O(logN)良好,O(N)还可以,O(N2)稍差(在冒泡法中见到)
2. 排序
- public class JWzw {
- //插入排序
- public void insertArray(Integer[] in ) {
- int tem = 0;
- int num = 0;
- int upnum = 0;
- for (int i = 0; i < in .length; i++) {
- for (int j = i - 1; j >= 0; j--) {
- num++;
- if ( in [j + 1] < in [j]) {
- tem = in [j + 1]; in [j + 1] = in [j]; in [j] = tem;
- upnum++;
- } else {
- break;
- }
- }
- }
- for (int i = 0; i < in .length; i++) {
- System.out.print( in [i]);
- if (i < in .length - 1) {
- System.out.print(",");
- }
- }
- System.out.println();
- System.out.println("插入排序循环次数:" + num);
- System.out.println("移动次数:" + upnum);
- System.out.print("\n\n\n");
- }
- //选择排序
- public void chooseArray(Integer[] in ) {
- int tem = 0;
- int num = 0;
- int upnum = 0;
- for (int i = 0; i < in .length; i++) {
- for (int j = i; j < in .length - 1; j++) {
- num++;
- if ( in [j + 1] < in [j]) {
- tem = in [j + 1]; in [j + 1] = in [j]; in [j] = tem;
- upnum++;
- }
- }
- }
- for (int i = 0; i < in .length; i++) {
- System.out.print( in [i]);
- if (i < in .length - 1) {
- System.out.print(",");
- }
- }
- System.out.println();
- System.out.println("选择排序循环次数:" + num);
- System.out.println("移动次数:" + upnum);
- System.out.print("\n\n\n");
- }
- //冒泡排序
- public void efferArray(Integer[] in ) {
- int tem = 0;
- int num = 0;
- int upnum = 0;
- for (int i = 0; i < in .length; i++) {
- for (int j = i; j < in .length - 1; j++) {
- num++;
- if ( in [j + 1] < in [i]) {
- tem = in [j + 1]; in [j + 1] = in [i]; in [i] = tem;
- upnum++;
- }
- }
- }
- for (int i = 0; i < in .length; i++) {
- System.out.print( in [i]);
- if (i < in .length - 1) {
- System.out.print(",");
- }
- }
- System.out.println();
- System.out.println("冒泡排序循环次数:" + num);
- System.out.println("移动次数:" + upnum);
- System.out.print("\n\n\n");
- }
- //打印乘法口诀
- public void printMulti() {
- for (int j = 1; j < 10; j++) {
- for (int i = 1; i <= j; i++) {
- System.out.print(i + " * " + j + " = " + j * i + "\t");
- }
- System.out.print("\t\n");
- }
- System.out.print("\n\n\n");
- }
- //打印N * 1 + N * 2 + N * 3 =num的所有组合
- public void printNumAssemble(int num) {
- for (int i = 0; i < num + 1; i++) {
- for (int j = 0; j < num / 2 + 1; j++) {
- for (int in = 0; in < num / 3 + 1; in ++) {
- if (i * 1 + j * 2 + in * 3 == num) {
- System.out.println("小马" + i + ",\t中马" + j + ",\t大马" + in );
- }
- }
- }
- }
- }
- /**
- * @param args
- */
- public static void main(String[] args) {
- JWzw jwzw = new JWzw();
- int num = 3;
- jwzw.printMulti(); //打印乘法口诀
- jwzw.printNumAssemble(100); //打印N * 1 + N * 2 + N * 3 =num的所有组合
- Integer in [] = {
- 8, 89, 5, 84, 3, 45, 12, 33, 77, 98, 456, 878, 654, 213, 897
- };
- jwzw.efferArray( in ); //冒泡排序
- Integer in1[] = {
- 8, 89, 5, 84, 3, 45, 12, 33, 77, 98, 456, 878, 654, 213, 897
- };
- jwzw.insertArray(in1); //插入排序
- Integer in2[] = {
- 8, 89, 5, 84, 3, 45, 12, 33, 77, 98, 456, 878, 654, 213, 897
- };
- jwzw.chooseArray(in2); //选择排序
- //int i = num++;
- //System.out.println(i);
- System.out.println(1000 >> 2);
- }
- }
3. 优先级队列
- class PriorityQueue {
- private long[] a = null;
- private int nItems = 0;
- private int maxSize = 0;
- public PriorityQueue(int maxSize) {
- a = new long[maxSize];
- this.maxSize = maxSize;
- nItems = 0;
- }
- public void insert(long l) {
- //优先级队列的插入不是队尾,而是选择一个合适的按照某种顺序插入的
- //当队列长度为0时,如下
- //不为0时,将所有比要插入的数小的数据后移,这样大的数就在队列的头部了
- int i = 0;
- if (nItems == 0) {
- a[0] = l;
- } else {
- for (i = nItems - 1; i >= 0; i--) {
- if (l < a[i]) a[i + 1] = a[i];
- else break;
- }
- a[i + 1] = l;
- }
- nItems++;
- }
- public long remove() {
- //移出的是数组最上端的数,这样减少数组元素的移动
- return a[--nItems];
- }
- public boolean isEmpty() {
- return (nItems == 0);
- }
- public boolean isFull() {
- return (nItems == maxSize);
- }
- public int size() {
- return nItems;
- }
- }
- public class duilie { // 队列体类
- private duilie s;
- private String data;
- duilie(String data) {
- this.data = data;
- }
- public String getData() {
- return data;
- }
- public void setData(String data) {
- this.data = data;
- }
- public duilie getS() {
- return s;
- }
- public void setS(duilie s) {
- this.s = s;
- }
- }
- public class duiliecz { // 队列操作类
- /**
- * @param args
- */
- private int i = 0; // 队列长
- private duilie top = new duilie(""); // 队列头
- private duilie end = new duilie(""); // 队列尾
- public void add(String s) { // 添加队列
- duilie m = new duilie(s);
- if (i != 0) {
- m.setS(top.getS());
- top.setS(m);
- } else {
- top.setS(m);
- end.setS(m);
- }
- i++;
- }
4. 队列
- public void del() { // 删除队尾
- if (i == 0) {
- return;
- } else if (i == 1) {
- top.setS(null);
- end.setS(null);
- } else {
- duilie top1 = new duilie(""); // 队列底查找用缓存
- top1.setS(top.getS());
- while (!top1.getS().getS().equals(end.getS())) {
- top1.setS(top1.getS().getS());
- }
- end.setS(top1.getS());
- }
- i--;
- }
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- duiliecz m = new duiliecz();
- m.add("1");
- m.add("2");
- m.add("3");
- m.add("4");
- for (int n = 0; n < 4; n++) {
- m.del();
- }
- }
- public int getI() {
- return i;
- }
- public duilie getEnd() {
- return end;
- }
- public duilie getTop() {
- return top;
- }
- }
5. 栈
- public class Stack {
- int[] arr;
- int len = 0;
- public Stack() {
- arr = new int[100];
- }
- public Stack(int n) {
- arr = new int[n];
- }
- public int size() {
- return len + 1;
- }
- // 扩大数组
- public void resize() {
- int[] b = new int[arr.length * 2];
- System.arraycopy(arr, 0, b, 0, arr.length);
- arr = b;
- }
- public void show() {
- for (int i = 0; i < len; i++) {
- System.out.print(arr[i] + " ");
- }
- System.out.println();
- }
- // 进栈
- public void push(int a) {
- if (len >= arr.length) resize();
- arr[len] = a;
- len++;
- }
- // 出栈
- public int pop() {
- if (len == 0) {
- System.out.println();
- System.out.println("stack is empty!");
- return -1;
- }
- int a = arr[len - 1];
- arr[len - 1] = 0;
- len--;
- return a;
- }
- }
6. 链表
- class Node {
- Object data;
- Node next;
- public Node(Object data) {
- setData(data);
- }
- public void setData(Object data) {
- this.data = data;
- }
- public Object getData() {
- return data;
- }
- }
- class Link {
- Node head;
- int size = 0;
- public void add(Object data) {
- Node n = new Node(data);
- if (head == null) {
- head = n;
- } else {
- Node current = head;
- while (true) {
- if (current.next == null) {
- break;
- }
- current = current.next;
- }
- current.next = n;
- }
- size++;
- }
- public void show() {
- Node current = head;
- if (current != null) {
- while (true) {
- System.out.println(current);
- if (current == null) {
- break;
- }
- current = current.next;
- }
- } else {
- System.out.println("link is empty");
- }
- }
- public Object get(int index) {
- // ....
- }
- public int size() {
- return size;
- }
- }
7. 单链表
- class Node // 节点类,单链表上的节点
- {
- String data; // 数据域,存放String类的数据
- Node next; // 指向下一个节点
- Node(String data) {
- this.data = data; // 构造函数
- }
- String get() {
- return data; // 返回数据
- }
- }
- class MyLinkList // 链表类
- {
- Node first; // 头节点
- int size; // 链表长度
- MyLinkList(String arg[]) {
- // Node first = new Node("head");//生成头节点
- first = new Node("head"); // J.F. 这里不需要定义局部变量 first
- // 如果定义了局部变量,那成员变量 first 就一直没有用上
- // 所以,它一直为空
- size = 0;
- Node p = first;
- for (int i = 0; i < arg.length; i++) // 将arg数组中的元素分别放入链表中
- {
- Node q = new Node(arg[i]);
- q.next = p.next; // 每一个节点存放一个arg数组中的元素
- p.next = q;
- p = p.next;
- size++;
- }
- }
- MyLinkList() // 无参数构造函数
- {
- // Node first = new Node("head");
- first = new Node("head"); // J.F. 这里犯了和上一个构造方法同样的错误
- size = 0;
- }
- int size() // 返回链表长度
- {
- return size;
- }
- void insert(Node a, int index) // 将节点a 插入链表中的第index个位置
- {
- Node temp = first;
- for (int i = 0; i < index; i++) {
- temp = temp.next; // 找到插入节点的前一节点
- }
- a.next = temp.next; // 插入节点
- temp.next = a;
- size++;
- }
- Node del(int index) // 删除第index个节点,并返回该值
- {
- Node temp = first;
- for (int i = 0; i < index; i++) {
- temp = temp.next; // 找到被删除节点的前一节点
- }
- Node node = temp.next;
- temp.next = node.next;
- size--; // 删除该节点,链表长度减一
- return node;
- }
- void print() // 在屏幕上输出该链表(这段程序总是出错,不知道错在哪里)
- {
- Node temp = first;
- for (int i = 1; i < size; i++) // 将各个节点分别在屏幕上输出
- {
- temp = temp.next;
- System.out.print(temp.get() + "->");
- }
- }
- void reverse() // 倒置该链表
- {
- for (int i = 0; i < size; i++) {
- insert(del(size - 1), 0); // 将最后一个节点插入到最前
- // J.F. 最后一个节点的 index 应该是 size - 1
- // 因为第一个节点的 index 是 0
- }
- }
- String get(int index) // 查找第index个节点,返回其值
- {
- if (index >= size) {
- return null;
- }
- Node temp = first;
- for (int i = 0; i < index; i++) {
- temp = temp.next; // 找到被查找节点的前一节点
- }
- return temp.next.get();
- }
- }
- class MyStack // 堆栈类,用单链表实现
- {
- MyLinkList tmp;
- Node temp;
- MyStack() {
- // MyLinkList tmp = new MyLinkList();
- tmp = new MyLinkList(); // J.F. 和 MyLinkList 构造方法同样的错误
- }
- void push(String a) // 压栈,即往链表首部插入一个节点
- {
- Node temp = new Node(a);
- tmp.insert(temp, 0);
- }
- String pop() // 出栈,将链表第一个节点删除
- {
- Node a = tmp.del(0);
- return a.get();
- }
- int size() {
- return tmp.size();
- }
- boolean empty() // 判断堆栈是否为空
- {
- if (tmp.size() == 0) return false;
- else return true;
- }
- }
- public class MyLinkListTest // 测试程序部分
- {
- public static void main(String arg[]) // 程序入口
- {
- if ((arg.length == 0) || (arg.length > 10)) System.out.println("长度超过限制或者缺少参数");
- else {
- MyLinkList ll = new MyLinkList(arg); // 创建一个链表
- ll.print(); // 先输出该链表(运行到这一步抛出异常)
- ll.reverse(); // 倒置该链表
- ll.print(); // 再输出倒置后的链表
- String data[] = new String[10];
- int i;
- for (i = 0; i < ll.size(); i++) {
- data[i] = ll.get(i); // 将链表中的数据放入数组
- }
- // sort(data);// 按升序排列data中的数据(有没有现成的排序函数?)
- for (i = 0; i < ll.size(); i++) {
- System.out.print(data[i] + ";"); // 输出数组中元素
- }
- System.out.println();
- MyStack s = new MyStack(); // 创建堆栈实例s
- for (i = 0; i < ll.size(); i++) {
- s.push(data[i]); // 将数组元素压栈
- }
- while (!s.empty()) {
- System.out.print(s.pop() + ";"); // 再将堆栈里的元素弹出
- }
- }
- }
- }
8. 双端链表
- class Link {
- public int iData = 0;
- public Link next = null;
- public Link(int iData) {
- this.iData = iData;
- }
- public void display() {
- System.out.print(iData + " ");
- }
- }
- class FirstLastList {
- private Link first = null;
- private Link last = null;
- public FirstLastList() {
- first = null;
- last = null;
- }
- public void insertFirst(int key) {
- Link newLink = new Link(key);
- if (this.isEmpty()) last = newLink;
- newLink.next = first;
- first = newLink;
- }
- public void insertLast(int key) {
- Link newLink = new Link(key);
- if (this.isEmpty()) first = newLink;
- else last.next = newLink;
- last = newLink;
- }
- public Link deleteFirst() {
- Link temp = first;
- if (first.next == null) last = null;
- first = first.next;
- return temp;
- }
- public boolean isEmpty() {
- return (first == null);
- }
- public void displayList() {
- System.out.print("List (first-->last): ");
- Link current = first;
- while (current != null) {
- current.display();
- current = current.next;
- }
- System.out.println("");
- }
- }
- class FirstLastListApp {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- FirstLastList theList = new FirstLastList();
- theList.insertFirst(22); // insert at front
- theList.insertFirst(44);
- theList.insertFirst(66);
- theList.insertLast(11); // insert at rear
- theList.insertLast(33);
- theList.insertLast(55);
- theList.displayList(); // display the list
- theList.deleteFirst(); // delete first two items
- theList.deleteFirst();
- theList.displayList(); // display again
- }
- }
9. 有序链表
- package arithmetic;
- class Link {
- public int iData = 0;
- public Link next = null;
- public Link(int iData) {
- this.iData = iData;
- }
- public void display() {
- System.out.print(iData + " ");
- }
- }
- class SortedList {
- private Link first = null;
- public SortedList() {
- first = null;
- }
- public void insert(int key) {
- Link newLink = new Link(key);
- Link previous = null;
- Link current = first;
- // while的第一个条件是没有到达链表的尾端,第二个是按顺序找到一个合适的位置
- while (current != null && key > current.iData) {
- previous = current;
- current = current.next;
- }
- // 如果是空表或者要插入的元素最小,则在表头插入key
- if (current == first) first = newLink;
- else previous.next = newLink;
- newLink.next = current;
- }
- /**
- * 删除表头的节点
- *
- * @return 要删除的节点
- */
- public Link remove() {
- Link temp = first;
- first = first.next;
- return temp;
- }
- public boolean isEmpty() {
- return (first == null);
- }
- public void displayList() {
- System.out.print("List (first-->last): ");
- Link current = first; // start at beginning of list
- while (current != null) // until end of list,
- {
- current.display(); // print data
- current = current.next; // move to next link
- }
- System.out.println("");
- }
- }
- class SortedListApp {
- public static void main(String[] args) { // create new list
- SortedList theSortedList = new SortedList();
- theSortedList.insert(20); // insert 2 items
- theSortedList.insert(40);
- theSortedList.displayList(); // display list
- theSortedList.insert(10); // insert 3 more items
- theSortedList.insert(30);
- theSortedList.insert(50);
- theSortedList.displayList(); // display list
- theSortedList.remove(); // remove an item
- theSortedList.displayList(); // display list
- }
- }
10. 双向链表
- class Link {
- // 双向链表,有两个指针,一个向前,一个向后
- public int iData = 0;
- public Link previous = null;
- public Link next = null;
- public Link(int iData) {
- this.iData = iData;
- }
- public void display() {
- System.out.print(iData + " ");
- }
- }
- class DoublyLinked {
- // 分别指向链表的表头和表尾
- private Link first = null;
- private Link last = null;
- public boolean isEmpty() {
- return first == null;
- }
- /**
- * 在表头插入数据
- *
- * @param 要插入的节点的数据
- */
- public void insertFirst(int key) {
- Link newLink = new Link(key);
- // 如果开始链表为空,则插入第一个数据后,last也指向第一个数据
- if (this.isEmpty()) last = newLink;
- else { // 表不为空的情况
- first.previous = newLink;
- newLink.next = first;
- }
- // 无论怎样,插入后都的让first重新指向第一个节点
- first = newLink;
- }
- public void insertLast(int key) { // 在尾端插入数据,同上
- Link newLink = new Link(key);
- if (this.isEmpty()) first = newLink;
- else {
- last.next = newLink;
- newLink.previous = last;
- }
- last = newLink;
- }
- /**
- * 在指定的节点后插入数据
- *
- * @param key
- * 指定的节点的值
- * @param iData
- * 要插入的数据
- * @return 是否插入成功
- */
- public boolean insertAfter(int key, int iData) {
- Link newLink = new Link(key);
- Link current = first;
- // 从first开始遍历,看能否找到以key为关键字的节点
- while (current.iData != key) {
- current = current.next;
- // 若能找到就跳出循环,否则返回false,插入失败
- if (current == null) return false;
- }
- // 如果插入点在last的位置
- if (current == last) {
- last = newLink;
- } else { // 非last位置,交换各个next和previous的指针
- newLink.next = current.next;
- current.next.previous = newLink;
- }
- current.next = newLink;
- newLink.previous = current;
- return true;
- }
- /**
- * 删除表头的节点
- *
- * @return
- */
- public Link deleteFirst() {
- Link temp = first;
- // 如果表中只有一个元素,删除后则为空表,所以last=null
- if (first.next == null) last = null;
- else
- // 否则,让第二个元素的previous=null
- first.next.previous = null;
- // 删除头指针,则first指向原来的second
- first = first.next;
- return temp;
- }
- public Link deleteLast() { // 同上
- Link temp = last;
- if (last.previous == null) first = null;
- else last.previous.next = null;
- last = last.previous;
- return temp;
- }
- public Link deleteKey(int key) {
- Link current = first;
- // 遍历整个链表查找对应的key,如果查到跳出循环,否则...
- while (current.iData != key) {
- current = current.next;
- // ...否则遍历到表尾,说明不存在此key,返回null,删除失败
- if (current == null) return null;
- }
- if (current == first) first = first.next;
- else current.previous.next = current.next;
- if (current == last) last = last.previous;
- else current.next.previous = current.previous;
- return current;
- }
- public void displayForward() {
- Link current = first;
- while (current != null) {
- current.display();
- current = current.next;
- }
- System.out.println();
- }
- public void displayBackward() {
- Link current = last;
- while (current != null) {
- current.display();
- current = current.previous;
- }
- System.out.println();
- }
- }
- class DoublyLinkedApp {
- public static void main(String[] args) { // make a new list
- DoublyLinked theList = new DoublyLinked();
- theList.insertFirst(22); // insert at front