算法--线性结构

一、数据结构

什么是数据结构:数据与数据之间的关系。

数据的存储结构:顺序存储(ArrayList)、链式存储(LinkList)。

数据的逻辑结构:集合结构、线性结构、树形结构、图形结构。

二、算法

算法:解决问题的方法。

算法的特性:输入、输出、有穷、确定性、可行性。

算法的基本要求:正确性、可读性、健壮性、时间复杂度、空间复杂度。

三、线性结构

1、数组

普通数组:类似Java基本类型数组

对象数组:类似ArrayList在对象里面定义一个数组类型的成员变量。

数组中的算法:线性查找和二分法查找。

//线性查找
public void queryByIndex(){
int[] arr = new int[]{2,3,4,6,5};
int target = 4;
int index = -1;
for(int i=0;i<arr.length;i++){
if(target == arr[i]){
index = i;
break;
}
}
System.out.println(index)
}
//二分法查找,前提是数组的内容是有序的
public void queryByMid(){
int[] arr = new int[]{2,3,4,5,6};
int target = 4;
int index = -1;
int begin = 0;
int end = arr.length - 1;
int mid;
while(true){
   mid = (begin+end)/2
if(target == arr[mid]){
index = i;
break;
}else if(target > arr[mid]){
end = mid - 1;
}else{
begin = mid + 1;
}
//不加这行会死循环
if(begin >= end){
break;
}
}

System.out.println(index)
}
2、栈

特点:先入后出,可以使用数组对象模拟。

int elements = new int[0];
//数组越界空指针异常不考虑
public void push(int element){
    int[] arr = new int[elements + 1];
   int len = elements.length;
   for(int i=0;i < len;i++){
       arr[i] = elements[i];
  }
   arr[len] = element;
   elements = arr;
}
//数组越界空指针异常不考虑
public int pop(){
   int[] arr = new int[elements - 1];
   int len = elements.length;
   int value = elements[len -1];
   for(int i=0;i < len -1;i++){
       arr[i] = elements[i];
  }
   elements = arr;
   return value;
}
3、队列

特点:先进先出,可以使用数组对象模拟。

int elements = new int[0];
//入队数组越界空指针异常不考虑
public void add(int element){
   int[] arr = new int[elements + 1];
   int len = elements.length;
   for(int i=0;i < len;i++){
       arr[i] = elements[i];
  }
   arr[len] = element;
   elements = arr;
}
//出队数组越界空指针异常不考虑
public int poll(){
   int[] arr = new int[elements - 1];
   int len = elements.length;
   int value = elements[0];
   for(int i=0;i < len;i++){
       arr[i] = elements[i+1];
  }
   elements = arr;
   return value;
}
4、单向链表

特点:一个节点除存储数据以外,还需存储下一个节点的指向。

public class Node{
   //节点数据
int data;
   //java对象在内存中是地址,可以理解下个节点的地址
   Node next;
   public Node(int data){
       this.data = data;
  }
   public Node append(Node node){
       Node currentNode = this;
       while(true){
           Node nextNode = currentNode.next;
           if(null == nextNode){
               break;
          }
           currentNode = nextNode;
      }
       //当前节点是可变的,因为循环中重新赋值了
       currentNode.next = node;
       return this;
  }
   
   public Node next(){
       return this.next;
  }
   
   public int getData(){
       return this.data;
  }
   public boolean isLast(){
       if(null == this.next){
          return true;
      }
       return false;
  }
   //移除也只能移除当前节点的下个节点
   public void removeNext(){
       Node deleteNode = this.next;
       Node newNext = deleteNode.next();
       this.next = newNext;
  }
   
   //只能插入当前节点后面
   public void inset(Node node){
       Node next = this.next;
       this.next = node;
       node.next = next;
  }
}
5、单项循环链表

特点:和单链表相比,尾节点的下个节点指向首节点,构成一个单向循环。

public class LoopNode{
   //节点数据
int data;
   //java对象在内存中是地址,可以理解下个节点的地址
   Node next = this;
   public LoopNode(int data){
       this.data = data;
  }
   
   public Node next(){
       return this.next;
  }
   
   public int getData(){
       return this.data;
  }
 
   //移除也只能移除当前节点的下个节点
   public void removeNext(){
       Node deleteNode = this.next;
       Node newNext = deleteNode.next();
       this.next = newNext;
  }
   
   //只能插入当前节点后面
   public void inset(Node node){
       Node next = this.next;
       this.next = node;
       node.next = next;
  }
}
6、双向循环链表

特点:由数据、前一个节点和下个节点做成

public class DoubleNode{
DoubleNode pre = this;
   DoubleNode next = this;
   int data;
   public DoubleNode(int data){
       this.data = data;
  }
   //往后增加节点
   public void after(DoubleNode node){
       //当前节点的下个节点
       DoubleNode oldNext = this.next;
       //新增的节点
       this.next = node;
       node.pre = this;
       
       node.next = oldNetx;
       oldNext.pre = node;
  }
}
7、递归

特点:在一个方法或者函数内部调用该方法,记得留出口,不然会栈溢出(StackOverflowError)。

//斐波那契数列 1 1 2 3 5 8 ...
public static int test(int i){
   if(1 == i || 2 == i){
       return 1;
  }
   return test(i - 1) + test(i - 2);
}
//汉诺塔
/**
* 共n个盘子
* 开始位置
* 中间位置
* 目标位置
* 无论有多少盘子,都认为只有两个,上面的所有盘子和下面一个盘子。
*/
public static int test2(int n,char from,char in ,char to){
   if(1 == n){
      System.out.println("第1个盘子从" + from + "移动到 " + to)
  }else{
       //移动上面的盘子到中间位置
       test2(n-1,from,to,in);
       System.out.println("第"+n+"盘子从" + from + "移动到 " + to);
       //把上面的所有盘子从中间位置移动到目标位置
    test2(n-1,in,from,to);
  }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自www.cnblogs.com/hyf-huangyongfei/p/12515974.html