数据结构与算法(二)
2.5查找算法之线性查找
package my2;
//线性查找
public class Linesearch {
//首先定义一个数组,然后遍历后,返回要查找的数值的下标
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
//要查找的数
int target=111;
//默认下标
int index=-1;
//遍历
for (int i=0;i<arr.length;i++){
if (arr[i]==target){
index=i;
break;//优化
}
}
if(index!=-1){
System.out.println("查找成功!要查找的数"+target+"的下标为"+index);
}else{
System.out.println("查找失败!数组中没有该数值!");
}
}
}
2.6 查找算法之二分法查找
package my2;
/*
二分法查找:给定一个有序的数组,要找的值,开始指针,结尾指针,中间的下标
返回:该数组的下标
*/
public class BinarySearch {
public static void main(String[] args) {
//有序数组
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
//需要查找的值
int target=11;
//开始的下标
int begin=0;
//最后的下标,即数组的最大下标
int end=arr.length-1;
//中间的下标
int mid=(begin+end)/2;
//记录目标的位置,默认为-1
int index=-1;
while (true){
//判断中间的数是否为要找的数
if(arr[mid]==target){
index=mid;
break;
}
else if (arr[mid]>target){//这里曾经把符号写反导致程序停不下来
end=mid-1;
mid=(begin+end)/2;
continue;
}
else {
begin=mid+1;
mid=(begin+end)/2;
}
}
System.out.println("要查找的数的下标index为:"+index);
}
}
2.7查找算法整合
//二分查找:出错的地方是由于没有给方法一个有序的数组
ObjectArray objectArray = new ObjectArray();
objectArray.add(11);
objectArray.add(21);
objectArray.add(31);
objectArray.add(41);
objectArray.add(51);
objectArray.add(61);
int binarySearch = objectArray.binarySearch(91);
System.out.println("二分查找"+11+"的结果为"+binarySearch);
array.line();
//线性查找
int lineSearch = array.lineSearch(7);
System.out.println("线性查找71的结果为"+lineSearch);
//二分法查找
public int binarySearch(int target){
//开始的下标
int begin=0;
//最后的下标,即数组的最大下标
int end=elements.length-1;
//中间的下标
int mid=(begin+end)/2;
//记录目标的位置,默认为-1
int index;
while (true){
//什么时候没有这个元素
//当开始的位置大于结束的位置,或者开始的位置等于结束的位置的时候
if (begin>end&&begin=end){
return -1;
}
//判断中间的数是否为要找的数
if(elements[mid]==target){
index=mid;
return index;
}
else if (elements[mid]>target){//这里曾经把符号写反导致程序停不下来
end=mid-1;
mid=(begin+end)/2;
}
else {
begin=mid+1;
mid=(begin+end)/2;
}
}
}
//线性查找
public int lineSearch(int target){
int index=-1;
//遍历
for (int i=0;i<elements.length;i++){
if (elements[i]==target){
index=i;
return index;
}
}
return index;
}
2.8栈
package my2;
import java.util.Arrays;
//用数据结构与算法来实现栈,核心思想就是压入和弹出。
public class Stack {
int[] elements;
public Stack() {//错误:忘记给数组初始化
this.elements = new int[0];
}
//压入
public void push(int target){
//创建一个新的数组,长度+1,然后把最后一个元素加进里面,最后数组引用,本质上是把数值加入数组后面
int[] newArr = new int[elements.length+1];
for (int i=0;i<elements.length;i++){
newArr[i]=elements[i];
}
newArr[elements.length]=target;
elements=newArr;
}
//弹出
public int pop(){
if (elements.length==0){
throw new RuntimeException("stack is empty!");
}
//
int element = elements[elements.length - 1];
int[] newArr = new int[elements.length - 1];
for (int i=0;i<elements.length-1;i++){
newArr[i]=elements[i];
}
elements=newArr;
//错误:把31行的语句放到此处,此时数组已经被替换,明明还有最后一个数据但触发数组越界异常
return element;
}
//打印数组
public void show(){
String s = Arrays.toString(elements);
System.out.println(s);
}
}
package my2;
public class StackTest {
public static void main(String[] args) {
Stack stack=new Stack();
stack.push(1);
stack.push(2);
stack.show();
System.out.println(stack.pop());
stack.show();
System.out.println(stack.pop());
stack.show();
System.out.println(stack.pop());
stack.show();
}
}
2.9队列
package my2;
import java.util.Arrays;
//队列:先进先出
public class Queue {
int[] elements;
public Queue() {//错误:忘记给数组初始化
this.elements = new int[0];
}
//入队
public void push(int target){
//创建一个新的数组,长度+1,然后把最后一个元素加进里面,最后数组引用,本质上是把数值加入数组后面
int[] newArr = new int[elements.length+1];
for (int i=0;i<elements.length;i++){
newArr[i]=elements[i];
}
newArr[elements.length]=target;
elements=newArr;
}
//出队:出队的话应该是最前面的一个弹出
public int poll(){
if (elements.length==0){
throw new RuntimeException("队列为空!!");
}
//创建一个数减一的新数组
int[] newArr = new int[elements.length - 1];
//取到原数组的第一个,后面返回
int element = elements[0];
//将原数组的第二个元素复制给新数组的第一个元素
for (int i=0;i<elements.length-1;i++){
newArr[i]=elements[i];
}
//数组引用
elements=newArr;
//返回数组
return element;
}
//打印数组
public void show(){
String s = Arrays.toString(elements);
System.out.println("当前的队列为"+s);
}
}
package my2;
public class QueueTest {
public static void main(String[] args) {
Queue queue = new Queue();
queue.push(11);
queue.push(21);
queue.push(31);
queue.push(41);
queue.show();
//出队
int pollOne = queue.poll();
System.out.println("出队1的元素为"+pollOne);
queue.show();
//出队
int pollTwo = queue.poll();
System.out.println("出队2的元素为"+pollTwo);
queue.show();
//出队
int pollThird = queue.poll();
System.out.println("出队3的元素为"+pollThird);
queue.show();
//出队
int pollFour = queue.poll();
System.out.println("出队4的元素为"+pollFour);
queue.show();
//出队,此时队列为空
int empty = queue.poll();
System.out.println("队列为空时,出队:"+empty);
queue.show();
}
}
2.10 单链表
package my2;
import com.sun.org.apache.xpath.internal.operations.Bool;
//实现链表的数据结构
public class Node {
int data;
Node next;
public Node(int data) {
this.data = data;
}
//追加节点:要实现的功能,就是找到当前链表的最后一个节点,然后把节点追加到最后面,需要用到递归
public Node append(Node node){
//创建 当前节点
Node currentNode=this;
//找到当前节点所在链表的最后一个节点
while(true){
//取出下一个节点
Node nextNode=currentNode.next;
if(nextNode==null){
break;
}
//让当前节点的下一个节点变成当前节点
currentNode=nextNode;
}
//把节点追加到最后一个节点上
currentNode.next=node;
return this;
}
//获取下一个节点
public Node next(){
return this.next;
}
//获取节点中的数据
public int getData(){
return this.data;
}
//当前节点是否是最后一个节点
public Boolean isLast(){
return this.next==null;
}
}
package my2;
public class NodeTest {
public static void main(String[] args) {
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
node1.append(node2).append(node3);
System.out.println(node1.next().next().data);
System.out.println(node3.isLast());
}
}
2.11删除单链表中的节点
2.12往单链表中插入节点
2.13 循环链表
2.14 双向循环链表
2.15 递归和斐波那契
2.16 汉诺塔问题