zoukankan      html  css  js  c++  java
  • 数据结构和算法——进度1

    一、经典问题算法
    1,肥婆那切数列
        普通方法
        public class Fibonaccil(){
            //定义三个变量和方法
            int a=1,b=1,c=0;
            System.out.print(a+" "+b+" ");
            for(int i=1;i<=18;i++){
                c = a + b;
                a = b;
                b = c;
                System.out.print(c+" ");
            }
        }
        数组方法
        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)+" ");
                }
            }
        }
    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;
                }
            }
           

  • 相关阅读:
    左划删除
    UILabel 添加图片
    Swift-11-委托模式
    Swift-11-协议(Protocols)
    Swift-10--错误处理
    Swift-09-可空链式调用(Optional Chaining)
    Swift-08-闭包引起的循环强引用
    Swift-07-析构器deinit
    Swift-06-闭包
    【转】HTML5标签使用的常见误区
  • 原文地址:https://www.cnblogs.com/jinb/p/6201815.html
Copyright © 2011-2022 走看看