1、二分查找
思想:二分查找又叫做折半查找,它的基本思想是将n个元素分成大致相等的两份,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法终止;如果x<a[n/2],则要在数组a的左半部分按照上述规则继续搜索x;如果x>a[n/2],则只要在数组a的右半部分搜索x。
如题:使用二分查找找数组{1,5,2,4,7,8,9,10,15,20}中15的位置。
public static void main(String[] args) {
int a[]={1,5,2,4,7,8,9,10,15,20};
int i = halfSelect(a, 15);
System.out.println("位置:"+i);
}
public static int halfSelect(int[] a, int x){
int headIndex = 0;
int endIndex = a.length-1;
while (headIndex <= endIndex){
int half = (headIndex + endIndex) / 2;
if(a[half] == x){
return half;
} else if (a[half] < x){
//目标数字在half角标的右侧
headIndex = half + 1;
} else {
目标数字在half角标的左侧
endIndex = half - 1;
}
}
return -1;//未找到x
}
2、Java实现一个链表结构
/**
* Created by czy on 2020/4/12.
* 一个简易的LinkedList
*/
public class MyList<T> {
private class Node<T> {
/**
* 该类定义了双向链表中节点的结构,是一个私有类
*/
public Node<T> pre;//前指针
public Node<T> next;//后指针
public T data;//数据
public Node(Node<T> pre, Node<T> next, T data) {
this.pre = pre;
this.next = next;
this.data = data;
}
}
private int size;
private Node<T> header;
private Node<T> tail;
public MyList() {
/**
* 构造一个带有头尾节点的双向链表,起始长度为0
* 头结点的next指向尾节点,尾节点的pre指向头结点
*/
size = 0;
header = new Node<>(null, null, null);
tail = new Node<>(header, null, null);
header.next = tail;
}
public void add(T item) {
Node<T> aNode = new Node<T>(null, null, item);
tail.pre.next = aNode;
aNode.pre = tail.pre;
aNode.next = tail;
tail.pre = aNode;
size++;
}
public boolean isEmpty(){
return (size == 0);
}
public int getSize() {
return size;
}
public T get(int index){
if(index > size-1 || index < 0)
throw new IndexOutOfBoundsException();
Node<T> current = new Node<T>(header,null,null);
for (int i = 0; i < index; i++) {
current = current.next;
}
return current.data;
}
public void print(){
Node<T> current = header.next;
while (current.next != null){
System.out.println(current.data.toString());
current = current.next;
}
}
}
没有写删除方法,详细的可以参考LinkedList的源码;在其他类中的调用:
public static void main(String[] args) {
MyList<Integer> list = new MyList();
list.add(1);
list.add(2);
list.add(3);
list.print();
}
3、冒泡排序
算法思想:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个,之后比较第二个和第三个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
public static void bubbleSort(int[] array) {
int temp;
for (int j = array.length; j > 0; j--) {
for (int i = 0; i < array.length - 1; i++) {
if (array[i] > array[i + 1]) {
temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
}
}
}
}
4、选择排序
算法思想:将所有数据扫描一遍,从中挑出最小的一个,与最左端的数据交换位置,即最小的数据在0号位,之后从1号位开始寻找最小的,以此类推。
public static void main(String[] args) {
int a[] = {23, 53, 77, 36, 84, 76, 93, 13, 45};
selectSort(a);
System.out.println(Arrays.toString(a));
}
public static void selectSort(int array[]) {
int minIndex;
int temp;
for (int i = 0; i < array.length - 1; i++) {
minIndex = i;
for (int j = i + 1; j < array.length; j++) {
if (array[minIndex] > array[j]) {
minIndex = j;
}
}
temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
}
5、快速排序
算法思想:
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面, 这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
一趟快速排序的算法是:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
3)从j开始向前搜索,即由后开始向前搜索(j–),找到第一个小于key的值A[j],将A[j]和A[i]互换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
public static void main(String[] args) {
int a[] = {23, 53, 77, 36, 84, 76, 93, 13, 45};
quick(a, 0, a.length);
System.out.println(Arrays.toString(a));
}
public static void quick(int[] array, int min, int max) {
if (min < max) {
int i = min;
int j = max - 1;
int key = array[min];
while (i < j) {
//从右往左找第一个小于x的数
while (i < j && array[j] >= key)
j--;
if (i < j)
array[i++] = array[j];
//从左往右找第一个大于等于x的数
while (i < j && array[i] < key)
i++;
if (i < j)
array[j--] = array[i];
}
array[i] = key;
quick(array, min, i);
quick(array, i + 1, max);
}
}