数据结构和算法——进度1

一、经典问题算法
1,肥婆那切数列
    普通方法
    public class Fibonaccil(){
        //定义三个变量和方法
        int a=1,b=1,c=0;
        System.out.print(a+"\t"+b+"\t");
        for(int i=1;i<=18;i++){
            c = a + b;
            a = b;
            b = c;
            System.out.print(c+"\t");
        }
    }
    数组方法
    public class Fibonacci2(){
        //定义数组
        int a[20],a[0]=1;a[1]=1;
        
        for(int i=2;i<aa.length;i++){
            a[i]=a[i-1]+a[i-2];
        }
        for(int i=0;i<aa.length;i++){
            System.out.print(a[i]);
        }
    }
    递归方法
    public class Fibonacci3(){
        //定义变量
        private static int getFibo(int i){
            if(i ==1||i == 2)
            return 1;
            else
            return getFibo(i-1)+getFibo(i-2);
        }
        public static void main(String[] args){
            for(int j=1; j<=20;j++){
                System.out.print(getFibo(j)+"\t");
            }
        }
    }
2,约瑟夫环
    n:人的总数
    start:开始报数的序号,start<n
    m:出列的标记
    public static void main(String[] args){
        //50人,从第一个人开始数,数到3的人出列
        countThree(50,0,3);
    }
    
    private static void countThree(int n, int start, int m){
        List<Integer> list = new ArrayList<Integer>();
        //初始化列表
        for (int i = 1; i <= n; i++){
            list.add(i);
        }
        
        while(list.size()>0){
            //将前两个一如列表尾端
            for(int j=0; j<m-1; j++){
                list.add(list.remove(start));
            }
            //打印出列的序号
            System.out.println(list.remove(start));
        }
    }
二、数据结构
    查找
        int[] intArr = new int[10];
        intArr[0] = 1;
        intArr[1] = 2;
        intArr[2] = 3;
        intArr[3] = 4;
        intArr[4] = 5;
        intArr[5] = 6;
        int[] intArr = {1,2,3,4,5,6};
        
        public class MyArray{
            private long[] arr;
            private int size=0;
            
            public MyArray(){
                arr = new long[10];
            }
            public MyArray(int maxSize){
                arr = new long[maxSize];
            }
            
            //向数组中插入数据
            public void insert(long element){
                arr[size] = element;
                size++;
            }
            //显示数组中数据
            public void show(){
                for(int i=0; i<size; i++){
                    if(i==0){
                        System.out.print(arr[i])
                    }
                }
            }
            //根据value进行查询
            public int queryByValue(long element){
                int i;
                for(i=0; i<size; i++){
                    if(arr[i] == element) break;
                }
                if(i == size){
                    return -1;
                }else{
                    return -1;
                }
            }
            //根据索引查找值
            public long queryByIndex(int index){
                if(index >= size || index<0){
                    throw new ArrayIndexOutOfBoundsException();
                }else{
                    return arr[index];
                }
            }
            //删除元素
            public void delete(int index){
                if(index >= size || index<0){
                    throw new ArrayIndexOutOfBoundsException();
                }else{
                    //当size=maxSize,删除最后一个数时,不会执行for
                    for(int i = index; i<size-1;i++){
                        arr[index] = arr[index +1];
                        System.out.println("for");
                    }
                }
                size--;
            }
            //更新数据
            public void update(int index, long value){
                if(index >= size || index<0){
                    throw new ArrayIndexOutOfBoundException();
                }else{
                    arr[index] = value;
                }
            }
        }
        二分查找法:(前提是:有序)
            public int binarySearch(long value){
                public middle = 0;
                int left = 0;
                int right = size - 1;
                
                while(true){
                    middle = (left + right)/2;
                    if(arr[middle] == value){
                        return middle;//①value为中间值,比较次数为1
                    }else if(left>right){
                        return -1;
                    }else{
                        if(arr[middle]<value)//value偏大
                            left = middle+1;                
                        }else{//value偏小
                            right = middle-1;
                        }
                    }
                }
            }
            
            public class binarySearch(long value){
                long middle = 0;
                left = arr[0];
                right = arr[size-1];
                while(true){
                    middle = (left+right)/2;//重写时把这个忘了
                    if(arr[middle]==value)
                        return arr[middle];
                    else if(value>arr[middle]){
                        left = middle+1;
                    }else{
                        right = middle-1;
                    }
                }
            }
    排序
        冒泡排序
        //bubble sort;
        public static void bubbleSort(long[] arr){
            long temp;
            for(int i=0; i<arr.length;i++){//外部的i向前循环,正序
                for(int j=arr.length-1;j>i;j--){
                    if(arr[j]<arr[j-1]){//内部的j向后循环,逆序
                        temp = arr[j];
                        arr[j] = arr[j-1];
                        arr[j-1] = temp;
                    }
                }
            }
        }
        
        public static void bubbleSort(long[] arr){
            long temp;
            for(int i=0; i<arr.length;i++){
                for(int j=arr.length-1; j>i;j--){
                    if(a[j]>a[j--]){//第一次重写时把交换条件弄丢了。
                        temp = a[i];//交换的数组小标也写错了。应该是j
                        a[i] = a[i--];
                        a[i--] = temp;
                    }
                }
            }
        }
        选择排序
            基本思想:在排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中
        再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。
            与冒泡排序相比,选择排序将必要的交换次数从O(N*N)减少到O(N),但比较次数还是保持才O(N)
            select sort
            public static void selectSort(long[] arr){
                long temp;
                for(int i=0; i<arr.length-1;i++){//外层排序,是正序。
                    int k=i;//k用来记录最小数的数组下标
                    for(int j=i+1;j<arr.length; j++){//内层排序也是正序,起始点为每次i的下一个元素。
                        if(arr[j]<arr[k]){
                            k=j;
                        }
                    }
                    temp = arr[i];
                    arr[i] = arr[k];
                    arr[k] = temp;
                }//外层循环中实现交换
            }
        插入排序
                基本思想:在要排序的一组数组中,假设前面(n-1)[n>=2]个数已经是拍好顺序的(局部有序),现在
            要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。
                在插入排序中,一组数据仅仅是局部有序的;而冒泡排序和选择排序,一组数据项在某个时刻是完全有序的。
            insert sort
            public static void insertSort(long[] arr){
                long temp;
                for(int i=1; i<arr.length;i++){//外层循环,用i来表示遍历整个序列
                    temp = arr[i];//记录要插入的元素
                    int j = i;
                    while(j>=1 && arr[j-1]>temp){//找到待插入元素应该插入的位置,从小到大,如果发现比待插入元素大的元素,和带插入元素进行交换。
                        arr[j] = arr[j-1];
                        j--;
                    }
                    arr[j] = temp;//在应插入位置插入记录元素。
                }
            }
    存储结构
        栈的数组实现
        public class Mystack{
            private long[] arr;
            private int top;
            
            public MyStack(){
                arr = new long[10];
                top = -1;
            }
            public MyStack(int maxSize){
                arr = new long[maxSize];
                top = -1;
            }
            
            //进栈
            public void push(long value){
                arr[++top] = value;
            }
            
            //出栈
            public long pop(){
                return arr[top--];
            }
            
            //读栈顶
            publid long peek(){
                return arr[top];
            }
            
            //判空
            public boolean isEmpty(){
                return (top == -1);
            }
            
            //判栈满
            public boolean isFull(){
                return (top == arr.length-1);
            }
        }
    队列
        队列的数组实现
        public class MyQueue{
            private long[] arr;
            private int size;
            private int front;
            private int rear;
            
            public MyQueue(){
                arr = new long[10];
                size = 0;
                front = 0;
                rear = -1;
            }
            public MyQueue(int maxSize){
                arr = new long[maxSize];
                size = 0;
                front = 0;
                rear = -1;
            }
            //队尾插入元素
            public void insert(long value){
                if(isEmpty()){
                    throw new ArrayIndexOutOfBoundsException();
                }
                if(rear == arr.length-1){//队列环绕式处理,把插入元素的队尾 重置为-1
                    rear = -1;
                }
                arr[++rear] = value;//插入元素
                size++;
            }
            //队首删除元素
            public long remove(){
                long value = arr[front++];
                if(front == arr.length){
                    front = 0;
                }
                size--;
                return value;
            }
            //取队首
            public long peek(){
                return arr[front];
            }
            //判空
            public boolean isEmpty(){
                return(size == 0);
            }
            //判满
            public boolean isFull(){
                return (size == arr.length);
            }
        }
    链表
        链表的定义
        pubic class Link{
            public long data;
            public Link next;
            
            public Link(long data){
                this.data = data;
            }
            
            public void displayLink(){
                System.out.print(data+"--->");
            }
        }
        单链表
        public class LinkList{
            private Link first;
            
            public LinkList(){
                this.first = null;
            }
            
            //表头插入
            public void insertFirst(long value){
                Link newLink = new Link(value);
                newLink.next = first;
                first = newLink;
            }
            
            //表头删除并返回
            public Link deleteFirst(){
                if(first == null){
                    return null;
                }
                Link temp = first;
                first = first.next;
                return temp;
            }
            
            //输出遍历链表
            public void displayList() {
                Link current = first;
                while(current != null){
                    current.displayLink();
                    current = current.next;
                }
                System.out.println();
            }
            
            //查找指定节点
            public Link find(long key){
                Link current = first;
                    
                        while(current.data != key){
                            if(current.next == null){
                                return null;
                            }else{
                                current = current.next;
                            }
                        }    
                        return current;
                        
                        //while(current.next != null)
                        //{
                        //    if(current.data == key){
                        //        return current;
                        //    }else{
                        //        current = current.next;
                        //    }
                        //    return null;
                        //}
            }
            
            //删除指定节点
            public Link delete(long key){
                Link current = first;
                Link previous = first;
                while(current.data != key){
                    if(current.next == null){
                        return null;
                    }else{
                        previous = current;
                        current = current.next;
                    }
                }//找到并跳出循环
                if(current == first){
                    first = first.next;
                }else{
                    previous.next = curren.next;//删除
                }
                return current;
            }
        }
    双端链表
        链表中保存着对最后一个链结点的引用
        public class FirstLastList{
            private Link first;
            private Link last;
            
            public FirstLastList(){
                this.first = null;
                this.last = null;
            }
            
            public boolean isEmpty(){
                return first == null;
            }
            //表头添加节点
            public void insertFirst(long value){
                Link newLink = new Link(value);
                if(isEmpty()){
                    last = newLink;
                }
                newLink.next = first;
                first = newLink;
            }
            //表尾添加节点
            public void insetLast(long value){
                Link newLink = new Link(value);
                if(isEmpty){
                    first = newLink;
                }else{
                    last.next = newLink;
                }
                last = newLink;
            }
            //删除表头
            public Link deleteFirst(){
                Link temp = first;
                
            }
        }
    双向链表
        public class DoubleLink{
            public long data;
            public DoubleLink next;
            public DoubleLink previous;
            
            public DoubleLink(long data){
                this.data = data;
            }
            
            public void displayLink(){
                System.out.print(data+"<==>");
            }
        }
        
        public class DoublyLinkedList{
            private DoubleLink first;
            private DoubleLink last;
            
            public DoubleLinkedList(){
                this.first = null;
                this.last = null;
            }
            
            public boolean is Empty(){
                return first == null;
            }
            //头部插入
            public void insertFirst(long value){
                DoubleLink newLink = new DoubleLink(value);
                if(isEmpty()){
                    last = newLink;
                }else{
                    first.previous = newLink;
                    newLink.next = first;
                }
                first = newLink;
            }
            //尾插法
            public void inserLast(long value){
                DoubleLink newLink = new DoubleLink(value);
                if(isEmpty()){
                    first = newLink;
                }else{
                    last.next = newLink;
                    newLink.previous = last;
                }
                last = newLink;
            }
            //头删除
            pubic DoubleLink deleteFirst(){
                DoubleLink temp = first;
                if(first.next == null){
                    last = null;
                }else{
                    first.next.previous = null;
                }
                first = first.next;
                return temp;
            }
            //尾删除
            public DoubleLink deleteLast(){
                DoubleLink temp = last;
                if(first.next == null){
                    first = null;
                }else{
                    last.previous.next = null;
                }
                last = last.previous;
                return temp;
            }
            //指定节点后插入
            public boolean insertAfter(long key, long data){
                DoubleLink current = first;
                while(current.data != key){
                    if(current.next == null){
                        return fasle;
                    }else{
                        current = current.next;
                    }
                }//循环遍历,找到跳出并返回current指针,否则返回false;
                DoubleLink newLink = new DoubleLink(data);
                if(current == last){//如果是指定节点是尾节点
                    newLink.next = null;
                    last = newLink;
                }else{
                    newLink.next = current.next;
                    current.next.previous = newLink;
                }
                current.next = nweLink;
                newLink.previous = current;
                return true;
            }
            //删除指定节点
            public DoubleLink deleteKey(long key){
                DoubleLink current = first;
                while(current.data != key){//①找到指定节点,没有放回null;
                    if(current.next == null){
                        return null;
                    }else{
                        current = current.next;
                    }
                }//跳出循环并找到指定current.data
                if(current == first){//②根据current的前驱结点来完成current前一结点到后一节点的连接。如果没有前驱节点比如首节点的情况,直接删除首节点的操作,first = first.next;
                    first = first.next;
                }else{
                    current.previous.next = current.next;
                }
                if(current == last){//③根据curren的后继结点来完成current后一节点都前一结点的指向,如果没有后继结点,比如刚好是尾节点,直接删除尾节点,last=last.previous
                    last = last.previous;
                }else{
                    current.next.previous = current.previous;
                }
                return current;
            }
            //正序输出
            public void displayForward(){
                System.out.print("first-->last:");
                DoubleLink current = first;
                while(curren != null){
                    current.displayLink();
                    current = current.next;
                }
                System.out.println();
            }
            //逆序输出
            public void displayBackword(){
                System.out.print("last-->first:");
                DoubleLink current = last;
                while(current != null){
                    current.displayLink();
                    current = current.previous;
                }
                System.out.println();
            }
        }
    递归
        递归调用:一种在方法中定义中调用方法自身的编程技术。解决递归问题的直接转化法和间接转化法。
        三角数:第n项为n-1项与n的和
            public static int triangleByRecursion(int n){
                if(n == 1){
                    return 1;
                }else{
                    return n + triangleByRecursion(n-1);
                }
            }
        Fibonacci数列
            public static int fibo(int n){
                if(n==1 || n==2){
                    return 1;
                }else{
                    return fibo(n-1) + fibo(n-2);
                }
            }
        汉诺塔问题
            public static doTowers(int topN, char from, char inter, char to){
                if(topN == 1){
                    System.out.println("Disk 1 from" + from +"to" +to);
                }else{
                    doTowers(topN-1,from,to,inter);
                    System.out.println("Disk" + topN +"from" +from +"to" +to);
                    doTowers(topN-1,inter,from,to);
                }
            }
        

            尾递归:直接转换法,尾递归是指在递归算法中,递归调用语句只有一个,而且是处在算法的最后
            阶乘
            public  long fact(int n)
           {
              if (n==0) return 1;
              else return n*fact(n-1);//递归的调用在算法最后的结束处,不需要保存中间值。
          }
        
            public long fact(int n)
          {
          int s=0;
          for (int i=1; i
          s=s*i; //用s保存中间结果
          return s;
          }
        
            单向递归:调用语句在递归算法的最后,尾递归是单项递归的特例。递归调用的参数之间没有关系。
            单项递归可以设置一些中间变量,保存中间值。
            public int f(int n)
            {
              if (n= =1 | | n= =0) return 1;
              else return f(n-1)+f(n-2);
            }    
            
            public int f(int n)
          {
          int i, s;
          int s1=1, s2=1;
          for (i=3; i {
          s=s1+s2;
          s2=s1; // 保存f(n-2)的值//利用中间变量保存值
          s1=s; //保存f(n-1)的值
          }
          return s;
          }
            间接转化法解决递归问题:
                使用栈保存中间结果,一般需要根据递归函数在执行过程中栈的变化得到。其一般过程如下:
                将初始化状态s0进栈
                while(栈不为空){
                    退栈,将栈顶元素赋给s;
                  if (s是要找的结果) 返回;
                  else {
                  寻找到s的相关状态s1;
                  将s1进栈
                  }
                }
    树
        有序数组插入数据项和删除数据项太慢,链表查找数据太慢,在树中能快速地查找,插入和删除数据项。
        树:从根到任何一个节点有且只有一条路径。
        二叉树
            1.被删除节点没有子树的情况,直接删除,并修改对应父节点的指针为空。

            2.对于只有一个子树的情况,考虑将其子树作为其父节点的子树,关于是左还是右,根据被删除的节点确定。

            3.最复杂的是有两个子数的情况,可以考虑两种方法,都是同样的思想:用被删除节点A的左子树的最右节点或者A的右子树的最左节点作为替代A的节点,并修改相应的最左或最右节点的父节点的指针,修改方法类似2 ,不做细致讨论
            
            public class Node{
                long data;
                Node leftChild;
                Node rightchild;
                
                public Node(long data){
                    this.data = data;
                }
            }
            
            public void insert(long value){
                Node newNode = new Node(value);
                if(root == null){//如果是空树
                    root = newNode;
                }else{
                    Node current = root;
                    Node parent;
                    while(true){
                        parent = current;//parent指向当前节点
                        if(value < current.data){//待插入节点值小于根
                            current = current.leftChild;//分配到左子树中
                            if(current == null){//判断是否到应该插入的位置,也就是到达了叶子节点
                                parent.leftChild = newNode;//插入节点
                                return;
                            }else{
                                current = current.rightchild;
                                if(current == null){
                                    parent.rightChild = newNode;
                                    return;
                                }
                            }
                        }
                    }
                }
            }
            
                        public void insert(long value){
                            Node newNode = new Node(value);
                            if(root == null){//①判空
                                root = newNode;
                            }else{
                                Node current = root;
                                Node parent;
                                while(true){//②循环子树
                                //第一次写时,忘记了循环,这个是以树为子问题的解决方法
                                    parent = current;
                                    if(data<current.data){//③判左右
                                        current = curren.leftChild;
                                        if(current == null){//④判是否为子节点
                                            parent.leftChild = newNode;
                                            return;//第一次书写忘了return。
                                        }
                                    }else{
                                        current = curren.rightChild;
                                        if(current == null){
                                            parent.rightChild = newNode;
                                            return;
                                        }
                                    }
                                }
                            }
                        }
            public Node find(long value){
                Node current = root;
                while(current.data != value){
                    if(value < current.data){
                        current = current.leftChild;
                    }else{
                        current = current.rightChild;
                    }
                    if(current == null){
                        return null;
                    }
                }
                return current;
            }
            //树节点的删除
            //首先找到指定要删除的节点,有三种情况要考虑:①节点为叶子节点,没有子节点。
            ②节点只有一个子节点,③节点有两个节点
            public boolean delete(long value){
                Node current = root;
                Node parent = current;
                boolean isLeftChild = true;
                while(current.data != value){
                    parent = current;
                    if(value < curren.data){
                        current = curren.leftChild;
                        isLeftChild = true;
                    }else{
                        current = current.rightChild;
                        isLeftChild = false;
                    }
                    if(current == null){
                        return false;
                    }
                }find it
                //find no child
                if(current.leftChild = null && current.rightChild == null){
                    if(current == root){
                        root = null;
                    }else if(isLeftChild){
                        parent.leftChild = null;
                    }else{
                        parent.rightChild = null;
                    }
                }else if(current.leftChild == null){
                    // if no left child, replace with right subtree
                    if(current == root){
                        root = current.rightChild;
                    }else if(isLeftChild){
                        parent.leftChild = current.rightChild;
                    }else{
                        parent.rightChild = current.rightChild;
                    }
                }else if(current.right == null){
                    if(current == root){
                        root = current.leftChild;
                    }else if(isLeftChild){
                        parent.leftChild = current.leftChild;
                    }else{
                        parent.rightChild = current.leftChild;
                    }
                }else{
                    //two childdren
                    Node successor = getSuccessor(current);
                    if(current == root){
                        root = successor;
                    }else if(isLeftChild){
                        parent.leftChild = successor;
                    }else{
                        parent.rightChild = successor;
                    }
                    successor.leftChild = current.leftChild;
                }
                return true;
            }
            private Node getSuccessor(Node delNode) {
                Node current = delNode.righttChild; //go to right child
                Node successorParent = delNode;
                Node successor = delNode;
                
                while(current !=  null) { //until no more
                    successorParent = successor;
                    successor = current;
                    current = current.leftChild; //go to left child
                }
                // if successor not right child, make connections
                if(successor != delNode.righttChild) {
                    successorParent.leftChild = successor.righttChild;
                    successor.righttChild = delNode.righttChild;
            }
            return successor;
    }
        //二叉树的删除功能
        public boolean delete(long value){
            Node current = root;
            Node parent = current;
            boolean isLeftChild = true;
            //1.查找指定节点的,并用current指向该节点。
            while(current.data != value){
                 parent = current;
                 if(value < current.data){
                    current = current.leftChild;
                    isLeftChild = true;
                 }else{//
                    current = current.rightChild;
                    isLeftChild = false;
                 }
                 if(current == null){
                    return false;
                 }
            }
             //2.对查找出的节点进行三种不同情况的进行判断和相应操作
             if(current.leftChild == null && current.rightChild == null){//①子节点
                if(current == root){
                    root = null;
                }else if(isLeftChile){
                    parent.leftChild = null;
                }else{
                    parent.rightChild = null;
                }
                
             }else if(current.leftChild == null){//②current只有右节点,对parent的左右两个节点进行判断操作
                if(current == root){
                    root = current.leftChild;
                }else if(isLeftChild){
                    parent.leftChild = current.rightChild;//parent 为current父节点,如果current没有左子树就把current的右字树直接接到父节点的左子树中。实现没有左子树的current节点的左子树的删除。
                }else{
                    parent.righttChild  = current.righttChild;
                }
             }else if(current.rightChild == null){//③current只有左节点,对parent的左右两边进行删除,把相应current的左节点挂靠到parent的左右节点上。
                if(current == root){
                    root = current.leftChild;
                }else if(isLeftChild){
                    parent.leftChild = current.leftChild;
                }else{
                    parent.rightChild = current.leftChild;
                }
             }else{ //④current具有两个节点,
                //获得current下的所有字树
                private Node getSuccessor(Node delNode){
                    Node current = delNode.rightChild;
                    Node successorParent = delNode;
                    Node successor = delNode;
                    
                    while(current != null){
                        successorParent = successor;
                        successor = current;
                        current = current.leftChild;
                    }
                    if(successor != delNode.right){
                        successorParent.leftChild = successor.rightChild;
                        
                    }
                }
                Node successor = getSuccessor(current);
                //把获得的剩余的字树挂靠到父节点parent上面
                if(current == root){
                    root = successor;
                }else if(isLeftChild){
                    parent.leftChild = successor;
                }else{
                    parent.rightChild = successor;
                }
                successor.leftChild = current.leftChild;
             }
             return true;
            }
        
            //二叉树的遍历
            先根遍历,先序遍历
            public void frontOrder(Node node){
                if(node != null){
                    System.out.println(node.data);
                    frontOrder(node.leftChild);
                    frontOrder(node.rightChild);
                }
            }
            中根遍历,中序遍历
            public void inOrder(Node node){
                if(node != null){
                    inOrder(node.leftChild);
                    System.out.println(node.data);
                    inOrder(node.rightChild);
                }
            }
            后根遍历,后序遍历
            public void inOrder(Node node){
                if(node != null){
                    inOrder(node.leftChild);
                    inOrder(node.rightChild);
                    System.out.println(node.data);
                }
            }
        红黑树与平衡树:
    
    图
        1)图是一种和树相像的数据结构,通常有一个固定的形状,这是由物理或抽象的问题来决定的。
        2)如果两个顶点被同一条边连接,就成这两个顶点邻接
        3)路径是从一个点到另一个点经过的序列
        4)至少有一条路径可以连接所有的顶点,那么这个图就是联通的,否则是非联通
        5)有向图和无向图
        6)带权图
        
        //Vertex顶点类
        public class Vertex{
            char label;
            boolean wasVisited;
            
            public Vertex(char label){
                this.label = label;
                wasVisited = false;
            }
        }
        
        //Graph图类
        public class Graph{
            private int maxSize = 20;
            private Vertex[] vertexList;//节点列表,存储节点
            private int[][] adjmat;//邻接矩阵,存储边
            private int nVertex;//记录节点数目
            private MyStack theStack;//
            
            public Graph(){
                vertexList = new Vertex[maxSize];
                adjmat = new int[maxSize][maxSize];
                nVertex = 0;
                theStack = new MyStack();
                for(int i=0; i<maxSize; i++){
                    for(int j=0; j<maxSize; j++){
                        adjmat[i][j] = 0;
                    }
                }
            }
            
            public void addVertex(char label){
                vertexList[nVertex++] = new Vertex(label);
            }
            public void addEdge(int start,int end){
                adjmat[start][end] = 1;
                adjmat[end][start] = 1;
            }
            public void display(){
                for(int i=0; i<nVertex; i++){
                    System.out.println(vertexList[i].label);
                }
            }
        }
        图的搜索
        1)图的搜索是指从一个指定的顶点到达那些顶点
        2)有两种常用的方法用来搜索图:深度优先搜索(DFS)和广度优先搜索(BFS)
        深度优先搜索通过栈来实现,而广度优先搜索通过队列来实现。
        3)深度优先搜索
            ①如果可能,访问一个邻接的未访问的顶点,标记它,并把它放入栈中。
            ②当不能执行规则1时,如果栈不为空,就从栈中弹出一个顶点。
            ③当不能执行规则1和规则2时,就完成了整个搜索过程。
            
        DFS
        public void dfs(){
            vertexList[0].wasVisited = true;
            System.out.println(vertexList[0].label);
            theStack.push(0);
            while(!theStack.isEmpty()){
                int v = getAdjUnvisitedVertex((int) theStack.peek);
                if(v == -1){
                    theStack.pop();
                }else{
                    vertexList[V].wasVisited = true;
                    System.out.println(vertexList[V].label);
                    theStack.push(V);
                }
            }
            for(int i=0; i<nVertex; i++){
                vertexList[i].wasVisited = false;
            }
        }
        public int gerAdjUnvisitedVertex(int V){
            for(int i=0; i<nVertex; i++){
                if(adjmat[V][i]==1 && vertexList[i].wasvisited == false){
                    return i;
                }
            }
            return -1;
        }
        4)广度优先搜索
            ①访问下一个邻接的未访问过的,这个顶点必须是当前节点的邻接点。标记它,并把它插如到队列中。
            ②如果无法执行规则1,那么就从对猎头取出一个顶点,并使其作为当前顶点。
            ③当队列为空不能执行规则2时,就完成了整个搜索。
        BFS
        5)图的最小生成树
            连接每个顶点最少的连线,最小生成树边的数量总是比定点的数量少1
        public void mast(){
            vertexList[0].wasVisited = true;
            theStack.push(0);
            while(!theStack.isEmpty()){
                int currentVertex = (int) theStack.peek();
                int v = getAdjUnvisitedVertex(currentVertex);
                if( v == -1){
                    theSatck.pop();
                }else{
                    vertexList[v].wasVisited = true;
                    System.out.print(vertexList[currentVertex].label+"-");
                    System.out.println(vertexList[v].label);
                    theStack.push(v);
                }
            }
            for(int i=0; i<nVertex; i++){
                vertexList[i].wasVisited = false;
            }
        }
       

posted @ 2016-12-20 11:03  Jin_c  阅读(401)  评论(0)    收藏  举报