《算法》二分查找、栈的实现、队列的实现、揹包

1.二分查找

//二分查找,《算法》p28
package algorithm;

public class BinarySearch_p28 {

    public static int rank(int key, int[] a){
        int lo = 0;
        int hi = a.length - 1;
        while(lo <= hi){
            int mid = (lo + hi)/2;
            if (a[mid] > key){
                hi = mid - 1;
            }
            else if(a[mid] < key){
                lo = mid + 1;
            }
            else return mid;
        }
        return -1;  
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] a = {2,3,4,5,6,7,8};
        int key = 4;
        System.out.printf("%d的索引为:\n" , key);
        System.out.println(rank(key,a));

    }

}

2.1栈的实现(数组)

//数组实现容量可变的栈,《算法》p88
package algorithm;

import java.util.Iterator;

public class ResizingArrayStack_p88<Item> implements Iterable<Item> {
    private Item[] a = (Item[]) new Object[1];//泛型数组的创建方式
    private int N = 0;
    public boolean isEmpty(){return N == 0;}//判断栈是否为空的方法
    public int size(){return N;}            //返回栈中元素的个数
    public void resize(int max){            //通过将栈移动到另一个max大小的数组中,改变原数组大小
        Item[] temp = (Item[]) new Object[max];
        for(int i = 0; i < N; i++)
            temp[i] = a[i];
        a = temp;                           //令a指向temp所指向的数组,同时释放原a所指向的数组;
    }
    public void push(Item item){
        if(N == a.length) resize(2*a.length);//先计算栈是否已满,再进栈
        a[N++] = item;                      //先填充a[N],N再加一;
    }
    public Item pop(){                      //先出栈,再调整数组大小
        Item item = a[--N];                 //N先减1,再出栈a[N]
        a[N] = null;                        //将已出栈的位置赋值为null,避免对象游离
        if((N > 0) && (N == a.length/4)) resize(a.length/2);
        return item;
    }   
    public Iterator<Item> iterator() {//ResizingArrayStack_p88<Item>实现Iterable<Item>接口重写方法iterator()
        return new ReverseArrayIterator();
        //ReverseArrayIterator向上转型为Iterator<Item>接口
    }
    private class ReverseArrayIterator implements Iterator<Item>{//内部类实现Iterator<Item>接口
        private int i = N;
        public boolean hasNext(){return (i > 0); }
        public Item next()      {return a[--i];  }
        public void remove()    {                }
    }


    /*---------用匿名内部类实现 public Iterator<Item> iterator() {//ResizingArrayStack_p88<Item>实现Iterable<Item>接口 //重写方法iterator() return new Iterator<Item>(){ private int i = N; public boolean hasNext(){return (i > 0); } public Item next() {return a[--i]; } public void remove() { } };//ReverseArrayIterator向上转型为Iterator<Item> } ---------------*/


    public static void main(String args[]){
        ResizingArrayStack_p88<Integer> test = new ResizingArrayStack_p88<Integer>();
        test.push(1); 
        test.push(2); 
        test.push(3); 
        //System.out.println(test.pop() + "," + test.pop() + "," + test.pop());
        Iterator<Integer> iterator = test.iterator(); //调用对象的iterator(),返回迭代器iterator
        while(iterator.hasNext())//通过迭代器iterator查看栈中元素
            System.out.println(iterator.next());    
        ResizingArrayStack_p88.ReverseArrayIterator aaa = test.new ReverseArrayIterator();//测试内部类
        System.out.println(aaa.i);//测试内部类
    }
}

结果

3
2
1
3

接口默认是public访问权限
内部类即使被设置为private,里面的变量也是private,在包含此内部类的外部类中仍然可以访问它们,但是在其他类中这些是不可见的。

2.2栈的实现(链表)

//链表实现栈,《算法》p94
package algorithm;

public class Stack_p94<Item> {
    private int N;
    public boolean isEmpty(){return N == 0;}
    public int size(){return N;}    
    private class Node{//定义结点的嵌套类
        Item item;
        Node next;
    }
    private Node top;
    public void push(Item item){
        Node oldtop = top;
        top = new Node();
        top.item = item;
        top.next = oldtop;
        N++;
    }
    public Item pop(){
        if (N == 0){
            System.out.println("栈空");
            return null;
        }
        else{
            Node oldtop = top;
            top = oldtop.next;
            N--;
            System.out.println(oldtop.item);
            return oldtop.item;
        }
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Stack_p94<Integer> test = new Stack_p94<Integer>();
        test.push(1); 
        test.push(2); 
        test.push(3); 
        test.pop();
        test.pop();
        test.pop();
        test.pop();
    }
}

结果

3
2
1
栈空

3.队列

//链表实现队列,《算法》p94
package algorithm;

public class Queue_p95<Item> {
    private int N;
    public boolean isEmpty(){return N == 0;}
    public int size(){return N;}
    private class Node{
        Item item;
        Node next;
    }
    public Node first;//队列的第一个结点
    public Node last;//队列的最后一个结点
    public void enqueue(Item item){//从队尾进入队列
        Node oldlast = last;
        last = new Node();
        last.item = item;
        //last.next = null;//可省略 
        if(isEmpty()){  //原队列为空时
            first = last;
        }
        else{
            oldlast.next = last;//原队列不为空时
        }
        N++;

    }
    public Item dequeque(){//从队头退出队列
        if(isEmpty()){
            System.out.println("队列为空");
            return null;
        }
        else{
            Item item = first.item;
            first = first.next;
            N--;
            if(isEmpty()) last = null; //删除元素后队列为空时
            System.out.println(item);
            return item;                
        }       
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Queue_p95<Integer> test = new Queue_p95<Integer>();
        test.enqueue(1); 
        test.enqueue(2); 
        test.enqueue(3); 
        test.dequeque();
        test.dequeque();
        test.dequeque();
        test.dequeque();
        test.enqueue(4);
        test.dequeque();
    }
}

结果

1
2
3
队列为空
4

注意:要考虑增加结点前,原队列为空时,处理first指向last所指向的对象;
删除结点后,队列为空时,last赋值为null。

4.揹包

//链表实现揹包,《算法》p98
//包含迭代器
package algorithm;

import java.util.Iterator;

public class Bag_P98<Item> implements Iterable<Item>{
    private int N;
    public boolean isEmpty(){return N == 0;}
    public int size(){return N;}    
    private class Node{//定义结点的嵌套类
        Item item;
        Node next;
    }
    private Node top;
    public void add(Item item){         //像揹包中放入结点
        Node oldtop = top;
        top = new Node();
        top.item = item;
        top.next = oldtop; 
        N++;
    }
    public Iterator<Item> iterator() {      //实现Iterable<Item>接口,重写iterator()方法
        // TODO Auto-generated method stub
        return new ListIterator();
    }
    private class ListIterator implements Iterator<Item>{ //实现Iterator<Item>接口
        private Node current = top;
        public boolean hasNext(){return current != null;}
        public Item next(){                                 //后进先出遍历
            Item item = current.item;
            current = current.next;
            return item;
        }
        public void remove(){}
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Bag_P98<Integer> test = new Bag_P98<Integer>();
        test.add(1);
        test.add(2);
        test.add(3);
        Iterator<Integer> iterator = test.iterator();
        while(iterator.hasNext())
            System.out.println(iterator.next());
    }   
}

结果

3
2
1
点赞