数据结构相关
数组与链表的的特点:
:数组申请的内存地址是连续的,而链表不需要连续的内存地址,链表所添加的对象的地址是随机的,链表中的每个节点拥有着下一个节点的引用,从而连缀成一条链表。
:数组在创建的时候就已经固定大小,链表不需要指定大小
:数组可以通过下标来随机访问特定的对象,链表只能从表头遍历访问,这就造成数组的访问的效率特别高,而链表的随机访问效率低
:数组的插入和删除操作效率低,因为需要移动其他位置上的对象,链表的插入和删除操作效率高,因为它只需要改变下指针的引用就可以删除或添加对象
链表的简单实现
public class SingleLink {
Node head = null; // 头节点
/**
* 链表中的节点,data代表节点的值,next是指向下一个节点的引用
*/
static class Node {
Node next = null;// 节点的引用,指向下一个节点
int data;// 节点的对象,即内容
public Node(int data) {
this.data = data;
}
}
//添加节点
public void addNode(int d) {
Node newNode = new Node(d);// 实例化一个节点
if (head == null) {
head = newNode;
return;
}
//尾部插入
/*
Node tmp = head;
//找到最后的一个节点
while (tmp.next != null) {
tmp = tmp.next;
}
//把尾节点的指针指向新创建的节点
tmp.next = newNode;
*/
//头部插入
newNode.next=head;
head=newNode;
}
//反转链表
public void reverse(){
if(length()<2)return;
Node curNode=head;
Node nextNode;
Node temp = null;
while (curNode!=null){
nextNode=curNode.next;
if(nextNode==null){
head=curNode;
}
curNode.next=temp;
temp=curNode;
curNode=nextNode;
}
public static void main(String[] args) {
SingleLink list = new SingleLink();
list.addNode(5);
list.addNode(5);
list.addNode(3);
list.addNode(1);
list.addNode(2);
list.addNode(2);
list.addNode(55);
list.addNode(36);
list.addNode(36);
list.printList();
}
}
打印结果 :
表头插入
36
36
55
2
2
1
3
5
5
表尾插入
5
5
3
1
2
2
55
36
36
Process finished with exit code 0
经典面试题:反转链表
//从头结点开始遍历,遍历过程中,把每个节点的指针改为指向前一个节点,
public void reverse(){
if(length()<2)return;
Node curNode=head;
Node nextNode;
Node temp = null;
while (curNode!=null){
nextNode=curNode.next;
//当遍历到最后一个节点的时候,把它设为头节点
if(nextNode==null){
head=curNode;
}
//把当前的节点的指针指向前一个节点
curNode.next=temp;
temp=curNode;
curNode=nextNode;
}
调用:
反转前
SingleLink list = new SingleLink();
list.addNode(1);
list.addNode(2);
list.addNode(3);
list.addNode(4);
list.addNode(5);
list.printList();
打印:
1
2
3
4
5
Process finished with exit code 0
反转后
SingleLink list = new SingleLink();
list.addNode(1);
list.addNode(2);
list.addNode(3);
list.addNode(4);
list.addNode(5);
list.reverse();
list.printList();
打印
5
4
3
2
1
Process finished with exit code 0
常用算法
排序:
1.冒泡排序 (效率低)
/*
* 冒泡排序
* 原理:在遍历的过程中用当前位置的值和下一个值作比较,大于就交换位置,这样一次遍历完之后就把最大的值放到的最后的位置,再次遍历就会把第二大的值放到倒数第二的位置,以此类推
* */
public void bubbleSort(int[] arry){
int length=arry.length;
int temp;
for (int i = 0; i < length-1; i++) {
for (int j = 0; j < length-i-1; j++) {
if(arry[j]>arry[j+1]){
temp=arry[j];
arry[j]=arry[j+1];
arry[j+1]=temp;
}
}
}
}
2.插入排序 (效率低)
/*
* 插入排序
* 原理:将数组分为两部分,将后部分元素逐一与前部分元素比较,如果前部分元素比array[i]小,就将前部分元素往后移动。当没有比array[i]小的元素,即是合理位置,在此位置插入array[i]
* */
public void insertSort(int array[]){
int t,j;
for (int i =1; i < array.length; i++) {
if(array[i]=0 && t
3.快速排序 (效率高)
/**
* 快速排序
* (时间复杂度为nlogn)
* */
public void quickSort(int array[], int low, int high) {// 传入low=0,high=array.length-1;
int key,v=low,temp;
if(low
查找
二分查找算法:
1.递归法:
/*
* 二分查找
* 递归
* */
public int index(int[] array,int key,int low,int high){
if(keyarray[high] || low>high)return -1;
if(array[(low+high)/2]>key){
return index(array,key,low,((low+high)/2)-1);
}else if(array[(low+high)/2]
2.非递归法:
/*
* 二分查找
* 非递归
* */
public int index1(int[] array,int key,int low,int high){
if(keyarray[high] || low>high)return -1;
int index=0;
int moddle;
while (low<=high){
moddle=(low+high)/2;
if(key>array[moddle]){
low=moddle+1;
}else if(key