2、简单排序
3、栈和队列
4、链表
5、双端链表和双向链表
6、递归的应用
7、递归的高级应用
8、希尔排序
9、快速排序
10、二叉树的基本概念
11、二叉树的基本操作
12、遍历二叉树
13、删除二叉树节点
14、红黑树
15、哈希表
16、开放地址法
17、链地址法
18、图的基本概念
19、图的搜索
20、图的最小生成树
1、数组
/** * 使用自定义类封装数组 * Created by yz on 2018/03/13. */ public class MyArray { private long[] arr; private int elements; public MyArray(){ arr = new long[50]; } public MyArray(int maxsize){ arr = new long[maxsize]; } /** * 添加数据 * @param value */ public void insert(long value){ arr[elements] = value; elements++; } /** * 添加数据--排序 线性查找 * @param value */ public void insertOfsort(long value){ int i; for (i = 0; i< elements; i++) { if(arr[i]>value){ break; } } for (int j = elements; j > i; j--) { arr[j] = arr[j-1]; } arr[i] = value; elements++; } /** * 显示数据 */ public void display(){ System.out.print("[ "); for (int i = 0; i < elements; i++) { System.out.print(arr[i]+" "); } System.out.println("]"); } /** * 查找数据 根据值查找索引 * @param value * @return */ public int search(long value){ int i; for (i = 0; i < elements; i++) { if(value == arr[i]){ break; } } if(i==elements){ return -1; }else{ return i; } } /** * 查找数据 二分法查找数据 * @param value * @return */ public int binarySearch(long value){ int middle = 0; int low = 0; int pow = elements; while (true){ middle = (low+pow)/2; if(arr[middle] == value){ return middle; }else if (low > pow){ return -1; }else{ // 左边查找 if(arr[middle]>value){ pow = middle - 1; }else{ // 右边查找 low = middle + 1; } } } } /** * 查找数据,根据索引来查 * @param index * @return */ public long get(int index){ if(index >= elements || index<0){ throw new ArrayIndexOutOfBoundsException(); }else{ return arr[index]; } } /** * 删除数据,根据索引来查 * @param index * @return */ public void delete(int index){ if(index >= elements || index<0){ throw new ArrayIndexOutOfBoundsException(); }else{ for (int i = index; i < elements; i++) { arr[index] = arr[index+1]; } elements --; } } /** * 更新数据 * @param index * @param newvallue */ public void change(int index,int newvallue){ if(index >= elements || index<0){ throw new ArrayIndexOutOfBoundsException(); }else{ arr[index] = newvallue; } } public static void main(String[] args) { MyArray arr = new MyArray(); arr.insertOfsort(87); arr.insertOfsort(34); arr.insertOfsort(23); arr.insertOfsort(90); arr.display(); System.out.println(arr.binarySearch(87)); } }
2、简单排序
/** * 排序 * Created by yz on 2018/03/13. */ public class MySort { /** * 冒泡排序 * @param arr */ public static void bubbleSort(int[] arr){ for (int i = 0; i < arr.length-1; i++) { for (int j = arr.length-1; j >i ; j--) { if(arr[j] < arr[j-1]){ //进行交换 int temp = arr[j]; arr[j]=arr[j-1]; arr[j-1]=temp; } } } } /** * 选择排序 * @param arr */ public static void selectionSort(int[] arr){ for (int i = 0; i < arr.length-1; i++) { for (int j = i; j < arr.length; j++) { if(arr[j]<arr[i]){ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } } /** * 插入排序 * @param arr */ public static void insertSort(int[] arr){ for (int i = 1; i < arr.length; i++) { int temp = arr[i]; int j = i-1; while (j>=0 && arr[j] > temp){ arr[j+1] = arr[j]; j--; } arr[j+1] = temp; } } public static void main(String[] args) { int[] arr = new int[]{34,23,2,11,15}; MySort.insertSort(arr); System.out.println(Arrays.toString(arr)); } }
3、栈和队列
/** * 栈 先进后出 * Created by yz on 2018/03/13. */ public class MyStack { // 底层实现是一个数组 private int[] arr; private int top; /** * 默认的构造方法 */ public MyStack() { arr = new int[10]; top = -1; } /** * 带参数的构造方法,参数为数组初始化大小 */ public MyStack(int maxsize) { arr = new int[maxsize]; top = -1; } /** * 添加数据 * @param value */ public void push(int value){ arr[++top] = value; } /** * 移除数据 * @return */ public int pop(){ return arr[top--]; } /** * 查看数据 * @return */ public int peek(){ return arr[top]; } /** * 判断是否为空 * @return */ public boolean isEmpty(){ return top == -1; } /** * 判断是否满了 * @return */ public boolean isFull(){ return top == arr.length-1; } public static void main(String[] args) { MyStack ms = new MyStack(4); ms.push(23); ms.push(12); ms.push(1); ms.push(90); System.out.println(ms.isEmpty()); System.out.println(ms.isFull()); System.out.println(ms.peek()); while (!ms.isEmpty()){ System.out.print(ms.pop()+","); } } }
/** * 队列类 先进先出 * Created by yz on 2018/3/14. */ public class MyQueue { // 底层使用数组 private int[] arr; // 有效数据的大小 private int elements; // 队头 private int front; // 队尾 private int end; /** * 默认构造方法 */ public MyQueue(){ arr = new int[10]; elements = 0; front = 0; end = -1; } /** * 带参数的构造方法,参数为数组的大小 */ public MyQueue(int maxsize){ arr = new int[maxsize]; elements = 0; front = 0; end = -1; } /** * 添加数据,从队尾插入 * @param value */ public void insert(int value){ if(end == arr.length-1){ end = -1; } arr[++end] = value; elements++; } /** * 删除数据,从队头删除 * @return */ public int remove(){ int vlaue = arr[front++]; if(front == arr.length){ front = 0; } elements--; return vlaue; } /** * 查看数据,从对头查看 * @return */ public int peek(){ return arr[front]; } /** * 判断是否为空 * @return */ public boolean isEmpty(){ return elements == 0; } /** * 判断是否满了 * @return */ public boolean isFull(){ return elements == arr.length; } public static void main(String[] args) { MyQueue mq = new MyQueue(4); mq.insert(23); mq.insert(45); mq.insert(13); mq.insert(7); System.out.println(mq.isFull()); System.out.println(mq.isEmpty()); System.out.println(mq.peek()); System.out.println(mq.peek()); while (!mq.isEmpty()){ System.out.print(mq.remove()+" "); } mq.insert(3); System.out.println(mq.peek()); } }
4、链表
链表:每个结点保存对下一个结点的引用
/** * 链结点,相当于是车厢 * Created by yz on 2018/3/14. */ public class Node { // 数据域 public int data; // 指针域 保存下一个结点的引用 public Node next; // 指针域 保存前一个结点的引用 public Node previous; /** * 默认构造方法 * @param vlaue */ public Node(int vlaue){ this.data = vlaue; } /** * 显示方法 */ public void display(){ System.out.print(data+" "); } }
/** * 链表 相当于火车 * Created by yz on 2018/3/14. */ public class LinkList { // 头结点 private Node first; public LinkList(){ first = null; } /** * 插入一个结点,在头结点后进行插入 * @param value */ public void insertFirst(int value){ Node node = new Node(value); node.next = first; first = node; } /** * 删除一个结点,在头结点后进行删除 * @return */ public Node deleteFirst(){ Node temp = first; first = temp.next; return temp; } /** * 显示方法 */ public void display(){ Node current = first; while (current != null){ current.display(); current = current.next; } System.out.println(); } /** * 查找方法 * @param value * @return */ public Node find(int value){ Node current = first; while (current.data != value){ if(current.next == null){ return null; } current = current.next; } return current; } /** * 删除方法,根据数据域来进行删除 * @param value * @return */ public Node delete(int value){ Node current = first; Node previous = first; while (current.data !=value){ if(current.next == null){ return null; } previous = current; current = current.next; } if(current == first){ first = first.next; }else{ previous.next = current.next; } return current; } public static void main(String[] args) { LinkList linkList = new LinkList(); linkList.insertFirst(34); linkList.insertFirst(23); linkList.insertFirst(12); linkList.insertFirst(3); linkList.insertFirst(65); // linkList.display(); // linkList.deleteFirst(); // linkList.display(); // System.out.println(); // Node node = linkList.find(23); // node.display(); Node no = linkList.delete(12); no.display(); System.out.println(); linkList.display(); } }
5、双端链表和双向链表
什么是双端链表:链表中保存着对最后一链结点应用的链表
什么是双向链表:每个结点除了保存对下一个结点的引用,同时还保存着对前一个结点的引用
/** * 双端链表 * Created by yz on 2018/3/14. */ public class FirstLastLinkList { // 头结点 private Node first; // 尾结点引用 private Node last; public FirstLastLinkList(){ first = null; last = null; } /** * 插入一个结点,在头结点后进行插入 * @param value */ public void insertFirst(int value){ Node node = new Node(value); if(isEmpty()){ last = node; } node.next = first; first = node; } /** * 插入一个结点,在尾结点后进行插入 * @param value */ public void insertLast(int value){ Node node = new Node(value); if(isEmpty()){ first = node; }else { last.next = node; } last = node; } /** * 删除一个结点,在头结点后进行删除 * @return */ public Node deleteFirst(){ Node temp = first; if(first.next == null){ last = null; } first = temp.next; return temp; } /** * 显示方法 */ public void display(){ Node current = first; while (current != null){ current.display(); current = current.next; } System.out.println(); } /** * 查找方法 * @param value * @return */ public Node find(int value){ Node current = first; while (current.data != value){ if(current.next == null){ return null; } current = current.next; } return current; } /** * 删除方法,根据数据域来进行删除 * @param value * @return */ public Node delete(int value){ Node current = first; Node previous = first; while (current.data !=value){ if(current.next == null){ return null; } previous = current; current = current.next; } if(current == first){ first = first.next; }else{ previous.next = current.next; } return current; } /** * 判断是否为空 * @return */ public boolean isEmpty(){ return first == null; } public static void main(String[] args) { FirstLastLinkList fl = new FirstLastLinkList(); fl.insertLast(34); // 从尾添加 fl.insertLast(23); fl.insertLast(12); fl.insertFirst(3); // 从头添加 fl.insertFirst(65); fl.display(); fl.deleteFirst(); fl.display(); } }
/** * 双向链表 * Created by yz on 2018/3/14. */ public class DoubleLinkList { // 头结点 private Node first; // 尾结点引用 private Node last; public DoubleLinkList(){ first = null; last = null; } /** * 插入一个结点,在头结点后进行插入 * @param value */ public void insertFirst(int value){ Node node = new Node(value); if(isEmpty()){ last = node; }else{ first.previous = node; } node.next = first; first = node; } /** * 插入一个结点,在尾结点后进行插入 * @param value */ public void insertLast(int value){ Node node = new Node(value); if(isEmpty()){ first = node; }else { last.next = node; node.previous = last; } last = node; } /** * 删除一个结点,在头结点后进行删除 * @return */ public Node deleteFirst(){ Node temp = first; if(first.next == null){ last = null; }else{ first.next.previous = null; } first = temp.next; return temp; } /** * 删除一个结点,在尾结点后进行删除 * @return */ public Node deleteLast(){ Node temp = last; if(first.next == null){ first = null; }else{ last.previous.next = null; } last = last.previous; return last; } /** * 显示方法 */ public void display(){ Node current = first; while (current != null){ current.display(); current = current.next; } System.out.println(); } /** * 查找方法 * @param value * @return */ public Node find(int value){ Node current = first; while (current.data != value){ if(current.next == null){ return null; } current = current.next; } return current; } /** * 删除方法,根据数据域来进行删除 * @param value * @return */ public Node delete(int value){ Node current = first; while (current.data !=value){ if(current.next == null){ return null; } current = current.next; } if(current == first){ first = first.next; }else{ current.previous.next = current.next; } return current; } /** * 判断是否为空 * @return */ public boolean isEmpty(){ return first == null; } public static void main(String[] args) { DoubleLinkList dl = new DoubleLinkList(); dl.insertLast(34); dl.insertLast(23); dl.insertLast(12); dl.display(); while (!dl.isEmpty()){ dl.deleteFirst(); dl.display(); } } }
6、递归的应用
什么是递归:
递归是一种方法调用自己的编程技术
三角数列:
该数列中的第n向是由第n-1项加n得到的
Fibonacci数列:
该数列的第1项为0,第二项为1,第n项为第n-1项加上n-2项得到
/** * 递归的应用 * Created by yz on 2018/3/14. */ public class Recursion { public static void main(String[] args) { test2(100); } public static void test(){ System.out.println("hello"); test();// 死循环,没有结束条件 内存溢出 } public static void test2(int n){ if(n==0){ return; } System.out.println(n); test2(n-1); } }
/** * 三角数列 * Created by yz on 2018/3/14. */ public class Triangle { /** * 通过循环 * @param n * @return */ public static int getNumber(int n){ int total = 0; while (n > 0){ total = total + n; n--; } return total; } /** * 通过递归 * @param n * @return */ public static int getNumberByRecursion(int n){ if(n == 1){ return 1; }else{ return n + getNumberByRecursion(n - 1); } } public static void main(String[] args) { System.out.println(Triangle.getNumber(50)); System.out.println(Triangle.getNumberByRecursion(50)); } }
/** * Fibonacci数列 * Created by yz on 2018/3/14. */ public class Fibonacci { public static int getNumber(int n){ if(n == 1){ return 0; }else if(n == 2){ return 1; }else{ return getNumber(n - 1) + getNumber(n - 2); } } public static void main(String[] args) { System.out.println(Fibonacci.getNumber(20)); } }7、递归的高级应用
汉诺塔的问题:所有的盘子刚开始都放在塔座A上,要求将所有的盘子从塔座A移动到塔座C上,每次只能移动一个盘子,任何盘子不能放比自己小的盘子上。
/** * 汉诺塔 * Created by yz on 2018/3/14. */ public class HanoiTower { /** * 移动盘子 * @param topNum 移动的盘子数 * @param from 起始塔座 * @param inter 中间塔座 * @param to 目标塔座 */ public static void doTower(int topNum,char from,char inter,char to){ if(topNum == 1){ System.out.println("盘子1,从"+from+"塔座到"+to+"塔座"); }else { doTower(topNum-1,from,to,inter); System.out.println("盘子"+topNum+",从"+from+"塔座到"+to+"塔座"); doTower(topNum-1,inter,from,to); } } public static void main(String[] args) { HanoiTower.doTower(5,'A','B','C'); } }8、希尔排序
一、希尔排序的产生
希尔排序是由科学家Donald L.Shell提出来的,希尔排序基于插入排序,并添加了一些新的特性,从而大大的提高插入排序的执行效率
二、插入排序的缺点,多次的移动
假如一个很小的数据在靠右端的位置上,那么要将该数据排序到正确的位置上,则所有的中间数据都需要向右移动一位。
三、希尔排序的优点
希尔排序通过加大插入排序中元素之间的间隔,并对这些间隔的元素进行插入排序,从而使得数据可以大幅度的移动。当完成该间隔的排序后,希尔排序会减少数据的间隔再进行排序。依次进行下去。
四、间隔的计算
间隔h的初始值为1,通过h=3*h+1来计算循环,直到该间隔大于数组的大小时停止。最大间隔为不大于数组大小的最大值。
五、间隔的减少
可用通过公式h=(h-1)/3来计算
六、希尔排序代码实现
/** * 希尔排序 * Created by yz on 2018/3/14. */ public class ShellSort { public static void sort(int[] arr){ // 初始化一个间隔 int h = 1; // 计算最大间隔 while (h < arr.length/3){ h = h * 3 + 1; } while (h > 0){ // 进行插入排序 for (int i = h; i < arr.length; i++) { int temp = arr[i]; int j = i; while (j > h-1 && arr[j-h] >= temp){ arr[j] = arr[j-h]; j -= h; } arr[j] = temp; } // 减小间隔 h = (h-1)/3; } } public static void main(String[] args) { int[] arr = new int[]{34,23,2,11,15,45,37,28,90,2,17,5,-1}; ShellSort.sort(arr); System.out.println(Arrays.toString(arr)); } }