1.数组
packagejavaDataStruct.array01;public classMyArray {private int[] arr;//表示有效数据的长度
private intelementsSize;publicMyArray() {//TODO Auto-generated constructor stub
arr = new int[50];
}public MyArray(intmaxSize) {
arr= new int[maxSize];
}/*** 添加数据*/
public void insert(intvalue) {
arr[elementsSize]=value;
elementsSize++;
}/*** 打印数据*/
public voidprintArray() {
System.out.print("[ ");for (int i = 0; i < elementsSize; i++) {
System.out.print(arr[i]+ " ");
}
System.out.println("]");
}/*** 查找数据*/
public int indexSearch(intvalue) {inti;for (i = 0; i < elementsSize; i++) {if (value ==arr[i]) {break;
}
}if (i ==elementsSize) {return -1;
}else{returni;
}
}/*** 二分法查找数据 前提:数组有序*/
public int binarySearch(intvalue) {intmiddle;int low = 0;int high =elementsSize;while (true) {
middle= (low + high) / 2;if (arr[middle] ==value)returnmiddle;else if (low >high) {return -1;
}else{if (arr[middle]
low= middle + 1;elsehigh= middle - 1;
}
}
}/*** 查找数据,根据索引查找*/
public int get(intindex) {if (index < 0 || index >=elementsSize) {throw newArrayIndexOutOfBoundsException();
}else{returnarr[index];
}
}/*** 删除数据*/
public void delete(intindex) {if (index < 0 || index >=elementsSize) {throw newArrayIndexOutOfBoundsException();
}else{for (int i = index; i < elementsSize; i++) {
arr[i]= arr[i + 1];
}
elementsSize--;
}
}/*** 更新数据*/
public void update(int index, intvalue) {if (index < 0 || index >=elementsSize) {throw newArrayIndexOutOfBoundsException();
}else{
arr[index]=value;
}
}
}
packagejavaDataStruct.array01;public classTestMyArray {public static voidmain(String[] args) {//TODO Auto-generated method stub
MyArray array = newMyArray();
array.insert(13);
array.insert(17);
array.insert(34);
array.insert(55);
array.insert(90);
array.printArray();
System.out.println(array.indexSearch(34));
System.out.println(array.indexSearch(90));
System.out.println(array.indexSearch(190));
System.out.println(array.get(2));//System.out.println(array.get(3));
array.delete(1);
array.printArray();
array.update(1, 33);
array.printArray();
System.out.println(array.binarySearch(55));
System.out.println(array.binarySearch(33));
System.out.println(array.binarySearch(13));
}
}
2.简单排序
2.1冒泡排序
假设要对一个大小为 N 的无序序列进行升序排序(即从小到大)。
(1) 每趟排序过程中需要通过比较找到第 i 个小的元素。
所以,我们需要一个外部循环,从数组首端(下标 0) 开始,一直扫描到倒数第二个元素(即下标 N - 2) ,剩下最后一个元素,必然为最大。
(2) 假设是第 i 趟排序,可知,前 i-1 个元素已经有序。现在要找第 i 个元素,只需从数组末端开始,扫描到第 i 个元素,将它们两两比较即可。
所以,需要一个内部循环,从数组末端开始(下标 N - 1),扫描到 (下标 i + 1)。
packagejavaDataStruct.sort02;public classBubbleSort {public static void sort(int[] array) {int temp = 0;
// 需要遍历的次数for (int i = 0; i < array.length - 1; i++) {for (int j = array.length - 1; j > i; j--) { // 注意array.length - 1
// 比较相邻的元素,如果前面的数大于后面的数,则交换if (array[j] < array[j - 1]) {
temp=array[j];
array[j]= array[j - 1];
array[j- 1] =temp;
}
}
}
}
}
2.2选择排序
(1)从待排序序列中,找到关键字最小的元素;
(2)如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换;
(3)从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束。
packagejavaDataStruct.sort02;public classSelectionSort {public static void sort(int[] array) {
// 需要遍历获得最小值的次数
// 要注意一点,当要排序 N 个数,已经经过 N-1 次遍历后,已经是有序数列
int k = 0; // 保存最小数据的索引int temp = 0;for (int i = 0; i < array.length-1; i++) {
k=i;for (int j = i+1; j < array.length; j++) {if (array[j]
k=j; // 更新最小数据的索引
}
// 将最小数据交换
temp=array[k];
array[k]=array[i];
array[i]=temp;
}
}
}
2.3插入排序
packagejavaDataStruct.sort02;public classInsertSort {public static void sort(int[] arr) {int temp = 0;inti, j;
// 第1个数肯定是有序的,从第2个数开始遍历,依次插入有序序列for (i = 1; i < arr.length; i++) {
temp=arr[i]; // 取出第i个数,和前i-1个数比较后,插入合适位置
// 因为前i-1个数都是从小到大的有序序列,所以只要当前比较的数(list[j])比temp大,就把这个数后移一位for (j = i - 1; j >= 0 && temp < arr[j]; j--) {
arr[j+ 1] =arr[j];
}
arr[j+ 1] = temp;
}
}
}
packagejavaDataStruct.sort02;importjavaDataStruct.util.Tool;public classTestSort {public static voidmain(String[] args) {int[] array = { 1, 2, 6, 8, 16, 3, 5};//BubbleSort.sort(array);//SelectionSort.sort(array);
InsertSort.sort(array);
Tool.printArray(array);
}
}
2.4希尔排序
希尔(Shell)排序又称为缩小增量排序,它是一种插入排序。它是直接插入排序算法的一种威力加强版。
该方法因DL.Shell于1959年提出而得名。
希尔排序的基本思想是:
把记录按步长gap 分组,对每组记录采用直接插入排序方法进行排序。
随着步长逐渐减小,所分成的组包含的记录越来越多,当步长的值减小到 1 时,整个数据合成为一组,构成一组有序记录,则完成排序。
我们来通过演示图,更深入的理解一下这个过程。
在上面这幅图中:
初始时,有一个大小为 10 的无序序列。
在第一趟排序中,我们不妨设 gap1 = N / 2 = 5,即相隔距离为 5 的元素组成一组,可以分为 5 组。
接下来,按照直接插入排序的方法对每个组进行排序。
在第二趟排序中,我们把上次的 gap 缩小一半,即 gap2 = gap1 / 2 = 2 (取整数)。这样每相隔距离为 2 的元素组成一组,可以分为 2 组。
按照直接插入排序的方法对每个组进行排序。
在第三趟排序中,再次把 gap 缩小一半,即gap3 = gap2 / 2 = 1。 这样相隔距离为 1 的元素组成一组,即只有一组。
按照直接插入排序的方法对每个组进行排序。此时,排序已经结束。
需要注意一下的是,图中有两个相等数值的元素 5 和 5 。我们可以清楚的看到,在排序过程中,两个元素位置交换了。
所以,希尔排序是不稳定的算法
public static void shellSort(int[] array) {int gap =array.length;while (gap > 0) {inttemp;intj;for (int i = 1; i < array.length; i++) {
temp=array[i];for (j = i - gap; j >= 0 && temp < array[j]; j = j -gap) {
array[j+ gap] =array[j];
}
array[j+ gap] =temp;
}
gap= gap / 2;
}
}
2.5快速排序
public static int division(int[] list, int left, intright) {//以最左边的数(left)为基准
int base =list[left];while (left
while (left < right && list[right] >=base)
right--;//找到了比base小的元素,将这个元素放到最左边的位置
list[left] =list[right];//从序列左端开始,向右遍历,直到找到大于base的数
while (left < right && list[left] <=base)
left++;//找到了比base大的元素,将这个元素放到最右边的位置
list[right] =list[left];
}//最后将base放到left位置。此时,left位置的左侧数值应该都比left小;//而left位置的右侧数值应该都比left大。
list[left] =base;returnleft;
}public static void quickSort(int[] list, int left, intright) {//左下标一定小于右下标,否则就越界了
if (left
int base =division(list, left, right);//对“基准标号“左侧的一组数值进行递归的切割,以至于将这些数值完整的排序
quickSort(list, left, base - 1);//对“基准标号“右侧的一组数值进行递归的切割,以至于将这些数值完整的排序
quickSort(list, base + 1, right);
}
}
2.6归并排序
归并排序是一种概念上最简单的排序算法,与快速排序一样,归并排序也是基于分治法的。归并排序将待排序的元素序列分成两个长度相等的子序列,为每一个子序列排序,然后再将他们合并成一个子序列。合并两个子序列的过程也就是两路归并。
packagedatastruct.t02sort;importdatastruct.Tookit;public classMergeSort {public static void mergeSort(int[] a, int left, intright) {if (left >=right)return;int mid = (left + right) / 2;
mergeSort(a, left, mid);
mergeSort(a, mid+ 1, right);
mergeArray(a, left, mid, right);//合并
}//两个排好序的子序列合并为一个子序列
public static void mergeArray(int[] a, int left, int mid, intright) {int[] temp = new int[a.length];//辅助数组
int p1 = left, p2 = mid + 1, k = left;//p1、p2是检测指针,k是存放指针
while (p1 <= mid && p2 <=right) {if (a[p1]
temp[k++] = a[p1++];elsetemp[k++] = a[p2++];
}while (p1 <= mid) {//如果第一个序列未检测完,直接将后面所有元素加到合并的序列中
temp[k++] = a[p1++];
}while (p2 <= right) {//同上
temp[k++] = a[p2++];
}for (int i = left; i <= right; i++) {
a[i]=temp[i];
}
}public static voidmain(String[] args) {int[] a = { 1, 5, 3, 7, 4, 8, 10};
System.out.println("原数组为:");
Tookit.print(a);
mergeSort(a,0, a.length - 1);
System.out.println("排序之后的数组为");
Tookit.print(a);
}
}
2.7堆排序
heapify操作顺序
从构建好的堆进行排序
1.交换根结点和最后一个结点
2.取出最后一个结点
3.再次从根结点进行heapify
4.交换根结点和最后一个结点
5.取出最后一个结点
重复上述步骤。。。
packagedatastruct.t02sort;import util.*;public classHeapSort {//构建堆
public static void buildHeap(int[] tree, intn) {int lastNode = n - 1;int parent = (lastNode - 1) / 2;inti;for (i = parent; i >= 0; i--) {
heapify(tree, n, i);
}
}/***
*@paramtree
*@paramn:结点数目
*@parami:当前的结点*/
public static void heapify(int[] tree, int n, inti) {if (i >=n)return;int c1 = 2 * i + 1;int c2 = 2 * i + 2;int max =i;if (c1 < n && tree[c1] >tree[max]) {
max=c1;
}if (c2 < n && tree[c2] >tree[max]) {
max=c2;
}if (max !=i) {
swap(tree, max, i);
heapify(tree, n, max);
}
}//交换元素
public static void swap(int[] arr, int i, intj) {int temp =arr[i];
arr[i]=arr[j];
arr[j]=temp;
}//堆排序
public static void heapSort(int[] tree, intn) {
buildHeap(tree, n);for (int i = n - 1; i >= 0; i--) {
swap(tree, i,0);
heapify(tree, i,0);
}
}public static voidmain(String[] args) {/*int[] tree = { 4, 10, 3, 5, 1, 2 };
int n = 6;
heapify(tree, n, 0);
Tool.printArray(tree);*/
/*int[] tree = { 2, 5, 3, 1, 10, 4 };
int n = 6;
buildHeap(tree, n);*/
int[] tree = { 23, 4, 5, 2, 1, 8, 24, 55};
heapSort(tree, tree.length);
Tool.printArray(tree);
}
}
3.栈
packagejavaDataStruct.ch03_stack_and_queue;importcom.sun.javafx.geom.AreaOp.AddOp;public classMyStack {private int[] arr;private inttop;publicMyStack() {//TODO Auto-generated constructor stub
arr = new int[10];
top= -1;
}/*** 带参数的构造方法*/
public MyStack(intmaxSize) {
arr= new int[maxSize];
top= -1;
}/*** 添加数据*/
public void push(intvalue) {
arr[++top] =value;
}/*** 移除数据*/
public intpop() {return arr[top--];
}/*** 查看数据*/
public intpeek() {returnarr[top];
}/*** 是否为空*/
public booleanisEmpty() {return top == -1;
}/*** 判断是否满了*/
public booleanisFull() {return top == arr.length - 1;
}
}
packagejavaDataStruct.ch03_stack_and_queue;public classTestMyStack {public static voidmain(String[] args) {//TODO Auto-generated method stub
MyStack myStack = newMyStack();
myStack.push(1);
myStack.push(10);
myStack.push(12);
myStack.push(16);
System.out.println(myStack.isEmpty());
System.out.println(myStack.isFull());
System.out.println(myStack.peek());
System.out.println(myStack.pop());
System.out.println(myStack.pop());
System.out.println(myStack.pop());
System.out.println(myStack.pop());
System.out.println(myStack.isEmpty());
}
}
4.队列
packagejavaDataStruct.ch03_stack_and_queue;public classMyQueue {private int[] arr;private intelementsSize;private intfront;private inttail;publicMyQueue() {//TODO Auto-generated constructor stub
arr = new int[10];
elementsSize= 0;
front= 0;
tail= -1;
}public MyQueue(intmaxSize) {//TODO Auto-generated constructor stub
arr = new int[maxSize];
elementsSize= 0;
front= 0;
tail= -1;
}/*** 从队尾插入数据*/
public void insert(intvalue) {
arr[++tail] =value;
elementsSize++;
}/*** 从对头删除数据*/
public intremove() {
elementsSize--;return arr[front++];
}/*** 从对头查看数据*/
public intpeek() {returnarr[front];
}/*** 判断是否为空*/
public booleanisEmpty() {return elementsSize == 0;
}/*** 判断是否满了*/
public booleanisFull() {return elementsSize ==arr.length;
}
}
packagejavaDataStruct.ch03_stack_and_queue;public classTestMyQueue {public static voidmain(String[] args) {//TODO Auto-generated method stub
MyQueue mq = newMyQueue();
mq.insert(1);
mq.insert(2);
mq.insert(3);
mq.insert(4);
System.out.println(mq.isEmpty());
System.out.println(mq.isFull());
System.out.println(mq.peek());while (!mq.isEmpty()) {
System.out.print(mq.remove()+ " ");
}
System.out.println();
}
}
5.链表
5.1普通单向链表
1.在头部插入一个节点
2.在头部删除一个节点
packagecn.jxufe.ch04_link;/** 链结点,相当于是车厢*/
public classNode {public intdata;publicNode next;public Node(intvalue) {this.data =value;
}/*** 显示方法*/
public voiddisplay() {
System.out.print(data+ " ");
}
}
packagecn.jxufe.ch04_link;/*** 链表相当于火车*/
public classLinkList {privateNode first;publicLinkList() {
first= null;
}/*** 插入一个节点,在头部进行插入*/
public void insertNode(intvalue) {
Node node= newNode(value);if (first == null) {
first=node;
}else{
node.next=first;
first=node;
}
}/*** 在头部进行删除*/
publicNode deleteFirst() {
Node temp=first;
first=temp.next;returntemp;
}/*** 显示方法*/
public voiddisplay() {
Node current=first;while (current != null) {
current.display();
current=current.next;
}
System.out.println();
}/*** 查找方法*/
public Node find(intvalue) {
Node current=first;while (current.data !=value) {if (current.next == null) {return null;
}
current=current.next;
}returncurrent;
}/*** 删除方法*/
public Node delete(intvalue) {
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;
}returncurrent;
}
}
packagecn.jxufe.ch04_link;public classTestLinkList {public static voidmain(String[] args) {
LinkList linkList= newLinkList();
linkList.insertNode(34);
linkList.insertNode(23);
linkList.insertNode(12);
linkList.insertNode(0);
linkList.insertNode(-1);
linkList.display();
linkList.deleteFirst();
linkList.display();
Node node= linkList.find(23);
node.display();
System.out.println();
Node node1= linkList.delete(0);
node1.display();
System.out.println();
linkList.display();
linkList.display();
}
}
5.2双端链表
1.在尾部插入一个节点
packagecn.jxufe.ch05_first_last_link;importcn.jxufe.ch04_link.Node;/*** 双端链表*/
public classFirstLastLink {privateNode first;privateNode last;publicFirstLastLink() {
first= null;
last= null;
}/*** 插入一个节点,在头部进行插入*/
public void insertNode(intvalue) {
Node node= newNode(value);if(isEmpty()) {
last=node;
}
node.next=first;
first=node;
}/*** 插入一个节点,从尾部插入*/
public void insertLast(intvalue) {
Node node= newNode(value);if(isEmpty()) {
first=node;
}else{
last.next=node;
}
last=node;
}/*** 在头部进行删除*/
publicNode deleteFirst() {
Node temp=first;if(first.next == null){
last= null;
}
first=temp.next;returntemp;
}/*** 显示方法*/
public voiddisplay() {
Node current=first;while (current != null) {
current.display();
current=current.next;
}
System.out.println();
}/*** 查找方法*/
public Node find(intvalue) {
Node current=first;while (current.data !=value) {if (current.next == null) {return null;
}
current=current.next;
}returncurrent;
}/*** 删除方法*/
public Node delete(intvalue) {
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;
}returncurrent;
}/*** 判读是否为空*/
public booleanisEmpty() {return first == null;
}
}
packagecn.jxufe.ch05_first_last_link;public classTestFirstLastLink {public static voidmain(String[] args) {
FirstLastLink fl= newFirstLastLink();
fl.insertNode(34);
fl.insertNode(22);
fl.insertNode(4);
fl.insertNode(56);
fl.display();
fl.deleteFirst();
fl.deleteFirst();
fl.display();
fl.insertLast(28);
fl.insertLast(90);
fl.display();
}
}
5.3双向链表
1.在头部插入一个节点
2.在尾部插入一个节点
3.从头部进行删除
packagecn.jxufe.ch05_first_last_link;/*** 双向链表
* 每个列表除了保存对下一个节点的引用,同时还保存对前一个节点的引用。*/
public classDoubleLink {privateNode first;privateNode last;publicDoubleLink() {
first= null;
last= null;
}/*** 插入一个节点,在头部进行插入
* 首先对列表进行判断,如果为空,则设置尾结点为新添加的节点;如果不为空,则设置头节点的前一个节点为新添加的节点。*/
public void insertFirst(intvalue) {
Node node= newNode(value);if(isEmpty()) {
last=node;
}else{
first.prev=node;
}
node.next=first;
first=node;
}/*** 插入一个节点,从尾部插入
* 如果为空,则直接设置头节点为新添加的节点;否则设置尾结点的后一个节点为新添加的节点,同时设置新添加的
* 节点的前一个节点为尾结点。*/
public void insertLast(intvalue) {
Node node= newNode(value);if(isEmpty()) {
first=node;
}else{
last.next=node;
node.prev=last;
}
last=node;
}/*** 在头部进行删除*/
publicNode deleteFirst() {
Node temp=first;if (first.next == null) {
last= null;
}else{
first.next.prev= null;
}
first=temp.next;returntemp;
}/*** 从尾部进行删除
* 如果头节点后没有其他节点,则设置尾节点为null;否则设置尾节点的前一个节点的next为null。设置为节点为其前一个节点。*/
publicNode deleteLast() {
Node temp=last;if (first.next == null) {
last= null;
}else{
last.prev.next= null;
}
last=last.prev;returnlast;
}/*** 显示方法*/
public voiddisplay() {
Node current=first;while (current != null) {
current.display();
current=current.next;
}
System.out.println();
}/*** 查找方法*/
public Node find(intvalue) {
Node current=first;while (current.data !=value) {if (current.next == null) {return null;
}
current=current.next;
}returncurrent;
}/*** 删除方法*/
public Node delete(intvalue) {
Node current=first;while (current.data !=value) {if (current.next == null) {return null;
}
current=current.next;
}if (current ==first) {
first=first.next;
}else{
current.prev.next=current.next;
}returncurrent;
}/*** 判读是否为空*/
public booleanisEmpty() {return first == null;
}
}
packagecn.jxufe.ch05_first_last_link;public classTestDoubleLink {public static voidmain(String[] args) {
DoubleLink dl= newDoubleLink();
dl.insertLast(45);
dl.insertLast(23);
dl.insertLast(-1);
dl.insertLast(56);
dl.display();
dl.insertFirst(21);
dl.insertFirst(1);
dl.insertFirst(27);
dl.display();
dl.deleteFirst();
dl.display();
dl.deleteLast();
dl.display();
dl.delete(21);
dl.display();
}
}