【蓝桥杯】必备的java数据结构和常用方法

文章目录

  • 一.线性表
    • 1.顺序表的实现
      • 静态数组
      • 动态数组
    • 2.链表的实现
  • 二.栈
  • 三.队列
  • 四.串
      • String
      • String StringBuffer 和 StringBuilder
  • 五.树和二叉树
  • 六.哈希表
  • 七. 图
      • 邻接矩阵
      • 邻接表

一.线性表

1.顺序表的实现

静态数组

java只有在为数组分配变量时,可以声明数组长度

            java:int[]  a;

                    a = new int [3];//可以用变量

但是java的数组是比较特殊的对象,所以需要借助别的类来实现数组的一些
(1)取值 a[i][j]
(2)遍历可以采用foreach的形式for(int c : a){}
(3)增加(插入),删除都需要根据数组的规律将后置位的元素移动;修改,直接修改
(4)查找调用Arrays类的binarySearch 方法(二分查找)

   	int a[] = {
     1,2,3};
    	int x;
    	x= Arrays.binarySearch(a, 2);

(5)排序 Arrays.sort方法
public static void sort(doule a[])
public static void sort(doule a[],int start,int end);

int []a = {
     55,33,44,22,11}; 
    	int []b = Arrays.copyOfRange(a, 1, 4);
       	Arrays.sort(a, 1, 4);

(6)数组复制 Arrays.copyOf
copyOf方法原型:public static float[] copyOf(float []original,int newLength)
从数组的第一个元素开始复制,复制长度为length,若长度超过数组原长,则超出元素为默认值0

int []a = {
     11,22,33,44,55}; 
 int []b = Arrays.copyOf(a, 7);

copyOfRange方法原型:public static double[] copyOfRange(double []original,int from,int to)
从original下标为from的位置开始复制,到to-1的位置结束,返回一个长度为to-from的数组== 下标范围这种的基本都是从from到to-1所指的元素==

(7)数组转list
Arrays.asList(T… a) 或者Collections.addAll
因为前者返回的是list对象没有增删,只能查改

返回一个受指定数组支持的固定大小的列表。(对返回列表的更改会“直接写”到数组。)此方法同 Collection.toArray() 一起,充当了基于数组的 API 与基于 collection 的 API 之间的桥梁。返回的列表是可序列化的,并且实现了 RandomAccess。
此方法还提供了一个创建固定长度的列表的便捷方法,该列表被初始化为包含多个元素:
//int[]不能直接转成integer的list

  String[] strArray = new String[2];
  ArrayList<String> list = new ArrayList<String>(Arrays.asList(strArray)) ;
 //或者里面直接是一个数组

  String[] strArray = new String[2];
        ArrayList< String> arrayList = new ArrayList<String>(strArray.length);
        Collections.addAll(arrayList, strArray);

(8)初始化:Arrays.fill
(1)public static void fill(byte[] a, byte val)
将指定的 byte 值分配给指定 byte 节型数组的每个元素。
(2)public static void fill(byte[] a,int fromIndex,int toIndex,byte val)
将指定的 byte 值分配给指定 byte 型数组指定范围中的每个元素。填充的范围从索引 fromIndex(包括)一直到索引 toIndex(不包括)。(如果 fromIndex==toIndex,则填充范围为空。)

动态数组

ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能
和Vector不同,ArrayList中的操作不是线程安全的!
(1)构造

// 默认构造函数
ArrayList()

// capacity是ArrayList的默认容量大小。当由于增加数据导致容量不足时,容量会添加上一次容量大小的一半。
ArrayList(int capacity)

// 创建一个包含collection的ArrayList
ArrayList(Collection<? extends E> collection)

(2)取值: get(int index)
(3)增删改查(自动移位)
boolean add(Element e)增加指定元素到链表尾部.
void add(int index, Element e)增加指定元素到链表指定位置.

void clear()从链表中删除所有元素.
E remove(int index)删除链表中指定位置的元素.
protected void removeRange(int start, int end)删除链表中从某一个位置开始到某一个位置结束的元素。

E set(int index, E element)将链表中指定位置上的元素替换成新元素。注意不能直接赋值

boolean contains(Object o)如果链表包含指定元素,返回true.
int indexOf(Object o)返回元素在链表中第一次出现的位置,如果返回-1,表示链表中没有这个元素。
int lastIndexOf(Object o)返回元素在链表中最后一次出现的位置,如果返回-1,表示链表中没有这个元素。
(4)逆置
Collections.reverse(lists);
(5)排序
Collections.sort()传入ArrayList,会采用默认的方式进行排序(字典序)

2.链表的实现

LinkedList和ArrayList一样是实现了List,API没太大区别,但是本质上还是有些区别

  • ArrayList底层是数组结构,LinkList底层是链表结构。
  • 1.对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。
  • 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

二.栈

Stack来自于Vector,那么显然stack的底层实现是数组。
java中Stack只有一个无参构造函数。

属于stack自己的方法包括

push( num) //入栈
pop() //栈顶元素出栈
empty() //判定栈是否为空
peek() //获取栈顶元素
search(num) //判端元素num是否在栈中,如果在返回1,不在返回-1。
注意pop()和peek()的区别。pop()会弹出栈顶元素并返回栈顶的值,peek()只是获取栈顶的值,但是并不会把元素从栈顶弹出来。

  Stack<Integer> st = new Stack<Integer>();

三.队列

队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作。
LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。虽然是线程不安全和非阻塞的,但是在一般的问题中足够了.

        Queue<String> queue = new LinkedList<String>();

add()和remove()方法在失败的时候会抛出异常(不推荐)queue的增加元素方法add和offer的区别在于,add方法在队列满的情况下将选择抛异常的方法来表示队列已经满了,而offer方法通过返回false表示队列已经满了;在有限队列的情况,使用offer方法优于add方法

public boolean offer(E e),向链表末尾添加元素,返回是否成功;
public boolean offerFirst(E e),头部插入元素,返回是否成功;
public boolean offerLast(E e),尾部插入元素,返回是否成功;

public void clear(),清空链表;
public E poll(),删除并返回第一个元素;

public E peek(),返回第一个元素;
public E peekFirst(),返回头部元素;
public E peekLast(),返回尾部元素;

public E set(int index, E element),设置指定位置的元素;

四.串

String

注意

  • String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了(但是可以使引用类型变量指向另一个字符串对象)如果需要对字符串做很多修改,那么应该选择使用 StringBuffer & StringBuilder 类。
  • 创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就将此字符串对象的地址赋值给引用s(引用s在Java栈中)。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中,并将此字符串对象的地址赋值给引用s(引用s在Java栈中)。
  • 关于equals和== :

(1)对于==,如果作用于基本数据类型的变量则直接比较其存储的"值"是否相等;如果作用于引用类型的变量(String),则比较的是所指向的对象的地址(即是否指向同一个对象)。
(2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量。如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;而String类对equals方法进行了重写,用来比较指向的字符串对象所存储的字符串是否相等。其他的一些类诸如Double,Date,Integer等,都对equals方法进行了重写用来比较指向的对象所存储的内容是否相等。

常用方法
public char charAt (int index) :返回指定索引处的 char值,不能直接说是修改
public int indexOf (String str) :返回指定子字符串第一次出现在该字符串内的索引,没有返回-1
public String substring (int beginIndex) :返回一个子字符串,从beginIndex开始截取字符串到字符串结尾。
public String substring (int beginIndex, int endIndex) :返回一个子字符串,从beginIndex到endIndex截取字符串。含beginIndex,不含endIndex。
public char[] toCharArray () :将此字符串转换为新的字符数组。
public String replace (CharSequence target, CharSequence replacement) :将与target匹配的字符串使用replacement字符串替换。
public String[] split(String regex) :将此字符串按照给定的regex(规则)拆分为字符串数组。

String StringBuffer 和 StringBuilder

StringBuilder 它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。

StringBuilder sb = new StringBuilder(); //无参构造方法,默认容量是16
StringBuilder sb = new StringBuilder(int capacity); //指定容量的字符串缓冲区对象
StringBuilder sb = new StringBuilder(String string); //指定字符串内容的字符串缓冲区对象

StringBuilder和String的相互替换
String------->StringBuilder
(1)通过构造方法
(2)通过StringBuilder的append或者insert方法
StringBuilder------->String
(1)通过toString()方法
(2)通过substring(0,length)方法
大部分方法和String相同
public StringBuffer append(String s)
将指定的字符串追加到此字符序列。
public StringBuffer reverse()
将此字符序列用其反转形式取代。
public delete(int start, int end)
移除此序列的子字符串中的字符。
public insert(int offset, int i)
将 int 参数的字符串表示形式插入此序列中。
replace(int start, int end, String str)
使用给定 String 中的字符替换此序列的子字符串中的字符。
public String substring(int start, int end) 截取从指定位置开始到结束位置,包括开始位置,不包括结束位置(注意:返回值不再是StringBuffer本身,而是String)

五.树和二叉树

/**   
* TreeNode: 普通的树节点  
*/  
public class TreeNode<T> {
       
    T value;  
    TreeNode<T> leftChild;  
    TreeNode<T> rightChild;  
  
    TreeNode(T value) {
       
        this.value = value;  
    }  
    
    TreeNode() {
       
    }  
      
    /**   增加左子节点 
    * addLeft:  
    * @param value  
    * void  返回类型    
    */  
    public void addLeft(T value){
       
        TreeNode<T> leftChild = new TreeNode<T>(value);  
        this.leftChild = leftChild;  
    }  
    /**   
    * addRight: 增加右子节点 
    * @param value  
    * void  返回类型    
    */  
    public void addRight(T value){
       
        TreeNode<T> rightChild = new TreeNode<T>(value);  
        this.rightChild = rightChild;  
    }  
    /* (non-Javadoc) 
     * @see java.lang.Object#equals(java.lang.Object) 
     * 重载equal方法 用来判断节点所对应的值是否相等
     */  
    @Override  
    public boolean equals(Object obj) {
       
        // TODO Auto-generated method stub  
        if(!(obj instanceof TreeNode)){
       
            return false;  
        }  
        return this.value.equals(((TreeNode<?>)obj).value);  
    }  
    /* (non-Javadoc) 
     * @see java.lang.Object#hashCode() 
     * 重载hashCode方法 
     */  
    @Override  
    public int hashCode() {
       
        // TODO Auto-generated method stub  
        return this.value.hashCode();  
    }  
    @Override  
    public String toString(){
       
        return this.value==null?"":this.value.toString();  
    }  
      
      
}

一些方法

import java.util.ArrayList;  
import java.util.LinkedList;  
import java.util.List;  
import java.util.Queue;  
  
/** 
 * TreeTools:树的操作类 g 
 */  
public class TreeTools {
       
  
    /** 
     * getTreeNum: 判断树中节点个数 
     *  
     * @param root 
     *            根节点 
     * @return int 返回类型 
     */  
    public static <T> int getTreeNum(TreeNode<T> root) {
       
        if (root == null) {
       
            return 0;  
        }  
        return getTreeNum(root.leftChild) + getTreeNum(root.rightChild) + 1;  
    }  
  
    /** 
     * getTreeDepth: 判断树的深度 
     *  
     * @param root 
     *            根节点 
     * @return int 返回类型 
     */  
    public static <T> int getTreeDepth(TreeNode<T> root) {
       
        if (root == null) {
       
            return 0;  
        }  
        int leftDepth = getTreeDepth(root.leftChild) + 1;  
        int rightDepth = getTreeDepth(root.rightChild) + 1;  
        return Math.max(leftDepth, rightDepth);  
    }  
  
    /** 
     * preOrderTravel: 前序遍历 
     *  
     * @param root 
     *            void 返回类型 
     */  
    public static <T> void preOrderTravel(TreeNode<T> root) {
       
        if (root == null) {
       
            return;  
        }  
        visitNode(root);  
        preOrderTravel(root.leftChild);  
        preOrderTravel(root.rightChild);  
    }  
  
    /** 
     * midOrderTravel: 中序遍历 
     *  
     * @param root 
     *            void 返回类型 
     */  
    public static <T> void midOrderTravel(TreeNode<T> root) {
       
        if (root == null) {
       
            return;  
        }  
        midOrderTravel(root.leftChild);  
        visitNode(root);  
        midOrderTravel(root.rightChild);  
    }  
  
    /** 
     * backOrderTravel: 后序遍历 
     *  
     * @param root 
     *            void 返回类型 
     */  
    public static <T> void backOrderTravel(TreeNode<T> root) {
       
        if (root == null) {
       
            return;  
        }  
        backOrderTravel(root.leftChild);  
        backOrderTravel(root.rightChild);  
        visitNode(root);  
    }  
  
    /** 
     * visitNode: 访问node节点 
     *  
     * @param node 
     *            void 返回类型 
     */  
    private static <T> void visitNode(TreeNode<T> node) {
       
        System.out.print(node.value + "\t");  
    }  
  
    /** 
     * levelTravel: 分层遍历 
     *  
     * @param root 
     *            void 返回类型 
     */  
    public static <T> void levelTravel(TreeNode<T> root) {
       
        Queue<TreeNode<T>> q = new LinkedList<TreeNode<T>>();  
        q.offer(root);  
        while (!q.isEmpty()) {
       
            TreeNode<T> temp = q.poll();  
            visitNode(temp);  
            if (temp.leftChild != null) {
       
                q.offer(temp.leftChild);  
            }  
            if (temp.rightChild != null) {
       
                q.offer(temp.rightChild);  
            }  
        }  
    }  
  
    /** 
     * getNumForKlevel: 求第K层节点个数 
     *  
     * @param root 
     * @param k 
     * @return int 返回类型 
     */  
    public static <T> int getNumForKlevel(TreeNode<T> root, int k) {
       
        if (root == null || k < 1) {
       
            return 0;  
        }  
        if (k == 1) {
       
            return 1;  
        }  
        int leftNum = getNumForKlevel(root.leftChild, k - 1);  
        int rightNum = getNumForKlevel(root.rightChild, k - 1);  
        return leftNum + rightNum;  
    }  
  
    /** 
     * getLeafNum: 求二叉树中叶子节点的个数 
     *  
     * @param root 
     * @return int 返回类型 
     */  
    public static <T> int getLeafNum(TreeNode<T> root) {
       
        if (root == null) {
       
            return 0;  
        }  
        if (root.leftChild == null && root.rightChild == null) {
       
            return 1;  
        }  
        int leftNum = getLeafNum(root.leftChild);  
        int rightNum = getLeafNum(root.rightChild);  
        return leftNum + rightNum;  
    }  
  
    /** 
     * exchange: 交换根节点的左右子树 
     * @param root 
     * @return TreeNode 返回类型 
     */  
    public static <T> TreeNode<T> exchange(TreeNode<T> root) {
       
        if (root == null) {
       
            return null;  
        }  
        TreeNode<T> left = exchange(root.leftChild);  
        TreeNode<T> right = exchange(root.rightChild);  
        root.leftChild = right;  
        root.rightChild = left;  
        return root;  
    }  
  
    /** 
     * nodeIsChild: 查看node是否是root的子节点 
     *  
     * @param root 
     * @param node 
     * @return boolean 返回类型 
     */ 
    public static <T> boolean nodeIsChild(TreeNode<T> root, TreeNode<T> node) {
       
        if (root == null || node == null) {
       
            return false;  
        }  
        if (root == node) {
       
            return true;  
        }  
        boolean isFind = nodeIsChild(root.leftChild, node);  
        if (!isFind) {
       
            isFind = nodeIsChild(root.rightChild, node);  
        }  
        return isFind;  
    }  

多个孩子的数的话,孩子节点用list实现
public class Tree {
private Object data;
private List childs;

六.哈希表

 hashMap和hashTable的l联系和区别主要从存储结构和线程安全这两个方面来说,在单一线程下使用hashMap的速度要比hashTable要快,再多线程下可以使用hashTable来保证线程安全

构造

HashMap hm1 = new HashMap();
HashMap hm2 = new HashMap();

常用方法
put(Object key,Object value)在此映射中关联指定的Key-value
putAll(Collection c)在此映射中将指定的映射关系添加到被操作的映射中

String [] key = {
     "name","age","tender"};
		String [] value = {
     "zhangsan","16","men"};
		hm2.put("id","012");
		hm2.put("describe", "zhangdelaohaokanle");
		for(int i = 0;i<3;i++){
     
			hm1.put(key[i], value[i]);
		}
		hm1.putAll(hm2);

get(Object key)根据key获取指定的value

System.out.println(hm1.get("name"));

containsKey(Object key)检测该映射中是否存在指定key的映射,有则返回true;没有则返回false
containsValue(Object value)检测该映射中是否存在指定value的映射,有则返回true;没有则返回false

remove(Object key)根据key的值删除指定的映射关系

values()返回值的集合,

isEmpty()测试映射是否为空

Collection<String> li = hm1.values();
	for (String string : li) {
     
		System.out.print(string+"     ");
	}

两种常用的遍历方法

for (Map.Entry<String, String> me:hm1.entrySet()) {
     
		System.out.println(me.getKey()+":"+me.getValue());
		}
		
for (String key1:hm1.keySet()) {
     
			System.out.println(key1+":"+hm1.get(key1));
		}

七. 图

数据结构参考
参考博客

邻接矩阵

public class GraphAdjMatrix<E> implements IGraph<E> {
     
	private E[] vexs;// 存储图的顶点的一维数组
	private int[][] edges;// 存储图的边的二维数组
	private int numOfVexs;// 顶点的实际数量
	private int maxNumOfVexs;// 顶点的最大数量
	private boolean[] visited;// 判断顶点是否被访问过
 
	@SuppressWarnings("unchecked")
	public GraphAdjMatrix(int maxNumOfVexs, Class<E> type) {
     
		this.maxNumOfVexs = maxNumOfVexs;
		edges = new int[maxNumOfVexs][maxNumOfVexs];
		vexs = (E[]) Array.newInstance(type, maxNumOfVexs);
	}
 
	// 得到顶点的数目
	public int getNumOfVertex() {
     
		return numOfVexs;
	}
	// 插入顶点
	public boolean insertVex(E v) {
     
		if (numOfVexs >= maxNumOfVexs)
			return false;
		vexs[numOfVexs++] = v;
		return true;
	}
	// 删除顶点
	public boolean deleteVex(E v) {
     
		for (int i = 0; i < numOfVexs; i++) {
     
			if (vexs[i].equals(v)) {
     
				for (int j = i; j < numOfVexs - 1; j++) {
     
					vexs[j] = vexs[j + 1];
				}
				vexs[numOfVexs - 1] = null;
				for (int col = i; col < numOfVexs - 1; col++) {
     
					for (int row = 0; row < numOfVexs; row++) {
     
						edges[col][row] = edges[col + 1][row];
					}
				}
				for (int row = i; row < numOfVexs - 1; row++) {
     
					for (int col = 0; col < numOfVexs; col++) {
     
						edges[col][row] = edges[col][row + 1];
					}
				}
				numOfVexs--;
				return true;
			}
		}
		return false;
	}
	// 定位顶点的位置
	public int indexOfVex(E v) {
     
		for (int i = 0; i < numOfVexs; i++) {
     
			if (vexs[i].equals(v)) {
     
				return i;
			}
		}
		return -1;
	}
	// 定位指定位置的顶点
		public E valueOfVex(int v) {
     
			if (v < 0 ||v >= numOfVexs )
				return null;
			return vexs[v];
		}
	// 插入边
	public boolean insertEdge(int v1, int v2, int weight) {
     
		if (v1 < 0 || v2 < 0 || v1 >= numOfVexs || v2 >= numOfVexs)
			throw new ArrayIndexOutOfBoundsException();
		edges[v1][v2] = weight;
		edges[v2][v1] = weight;
		return true;
	}
	// 删除边
	public boolean deleteEdge(int v1, int v2) {
     
		if (v1 < 0 || v2 < 0 || v1 >= numOfVexs || v2 >= numOfVexs)
			throw new ArrayIndexOutOfBoundsException();
		edges[v1][v2] = 0;
		edges[v2][v1] = 0;
		return true;
	}
	// 查找边
	public int getEdge(int v1,int v2){
     
		if (v1 < 0 || v2 < 0 || v1 >= numOfVexs || v2 >= numOfVexs)
			throw new ArrayIndexOutOfBoundsException();
		return edges[v1][v2];
	}
	// 深度优先搜索遍历
	public String depthFirstSearch(int v) {
     
 
	}
	// 广度优先搜索遍历
	public String breadFirstSearch(int v) {
     
 
	}
	// 实现Dijkstra算法
	public int[] dijkstra(int v) {
     
 
	}
}

邻接表

public class GraphAdjList<E> implements IGraph<E> {
     
	// 邻接表中表对应的链表的顶点
	private static class ENode {
     
		int adjvex; // 邻接顶点序号
		int weight;// 存储边或弧相关的信息,如权值
		ENode nextadj; // 下一个邻接表结点
 
		public ENode(int adjvex, int weight) {
     
			this.adjvex = adjvex;
			this.weight = weight;
		}
	}
 
	// 邻接表中表的顶点
	private static class VNode<E> {
     
		E data; // 顶点信息
		ENode firstadj; // //邻接表的第1个结点
	};
 
	private VNode<E>[] vexs; // 顶点数组
	private int numOfVexs;// 顶点的实际数量
	private int maxNumOfVexs;// 顶点的最大数量
	private boolean[] visited;// 判断顶点是否被访问过
 
	@SuppressWarnings("unchecked")
	public GraphAdjList(int maxNumOfVexs) {
     
		this.maxNumOfVexs = maxNumOfVexs;
		vexs = (VNode<E>[]) Array.newInstance(VNode.class, maxNumOfVexs);
	}
 
	// 得到顶点的数目
	public int getNumOfVertex() {
     
		return numOfVexs;
	}
 
	// 插入顶点
	public boolean insertVex(E v) {
     
		if (numOfVexs >= maxNumOfVexs)
			return false;
		VNode<E> vex = new VNode<E>();
		vex.data = v;
		vexs[numOfVexs++] = vex;
		return true;
	}
 
	// 删除顶点
	public boolean deleteVex(E v) {
     
		for (int i = 0; i < numOfVexs; i++) {
     
			if (vexs[i].data.equals(v)) {
     
				for (int j = i; j < numOfVexs - 1; j++) {
     
					vexs[j] = vexs[j + 1];
				}
				vexs[numOfVexs - 1] = null;
				numOfVexs--;
				ENode current;
				ENode previous;
				for (int j = 0; j < numOfVexs; j++) {
     
					if (vexs[j].firstadj == null)
						continue;
					if (vexs[j].firstadj.adjvex == i) {
     
						vexs[j].firstadj = null;
						continue;
					}
					current = vexs[j].firstadj;
					while (current != null) {
     
						previous = current;
						current = current.nextadj;
						if (current != null && current.adjvex == i) {
     
							previous.nextadj = current.nextadj;
							break;
						}
					}
				}
				for (int j = 0; j < numOfVexs; j++) {
     
					current = vexs[j].firstadj;
					while (current != null) {
     
						if (current.adjvex > i)
							current.adjvex--;
						current = current.nextadj;
					}
				}
				return true;
			}
		}
		return false;
	}
 
	// 定位顶点的位置
	public int indexOfVex(E v) {
     
		for (int i = 0; i < numOfVexs; i++) {
     
			if (vexs[i].data.equals(v)) {
     
				return i;
			}
		}
		return -1;
	}
 
	// 定位指定位置的顶点
	public E valueOfVex(int v) {
     
		if (v < 0 || v >= numOfVexs)
			return null;
		return vexs[v].data;
	}
 
	// 插入边
	public boolean insertEdge(int v1, int v2, int weight) {
     
		if (v1 < 0 || v2 < 0 || v1 >= numOfVexs || v2 >= numOfVexs)
			throw new ArrayIndexOutOfBoundsException();
		ENode vex1 = new ENode(v2, weight);
 
		// 索引为index1的顶点没有邻接顶点
		if (vexs[v1].firstadj == null) {
     
			vexs[v1].firstadj = vex1;
		}
		// 索引为index1的顶点有邻接顶点
		else {
     
			vex1.nextadj = vexs[v1].firstadj;
			vexs[v1].firstadj = vex1;
		}
		ENode vex2 = new ENode(v1, weight);
		// 索引为index2的顶点没有邻接顶点
		if (vexs[v2].firstadj == null) {
     
			vexs[v2].firstadj = vex2;
		}
		// 索引为index1的顶点有邻接顶点
		else {
     
			vex2.nextadj = vexs[v2].firstadj;
			vexs[v2].firstadj = vex2;
		}
		return true;
	}
 
	// 删除边
	public boolean deleteEdge(int v1, int v2) {
     
		if (v1 < 0 || v2 < 0 || v1 >= numOfVexs || v2 >= numOfVexs)
			throw new ArrayIndexOutOfBoundsException();
		// 删除索引为index1的顶点与索引为index2的顶点之间的边
		ENode current = vexs[v1].firstadj;
		ENode previous = null;
		while (current != null && current.adjvex != v2) {
     
			previous = current;
			current = current.nextadj;
		}
		if (current != null)
			previous.nextadj = current.nextadj;
		// 删除索引为index2的顶点与索引为index1的顶点之间的边
		current = vexs[v2].firstadj;
		while (current != null && current.adjvex != v1) {
     
			previous = current;
			current = current.nextadj;
		}
		if (current != null)
			previous.nextadj = current.nextadj;
		return true;
	}
 
	// 得到边
	public int getEdge(int v1, int v2) {
     
		if (v1 < 0 || v2 < 0 || v1 >= numOfVexs || v2 >= numOfVexs)
			throw new ArrayIndexOutOfBoundsException();
		ENode current = vexs[v1].firstadj;
		while (current != null) {
     
			if (current.adjvex == v2) {
     
				return current.weight;
			}
			current = current.nextadj;
		}
		return 0;
	}
 
	// 深度优先搜索遍历
	public String depthFirstSearch(int v) {
     
 
	}
 
	// 广度优先搜索遍历
	public String breadFirstSearch(int v) {
     
 
	}
 
	// 实现Dijkstra算法
	public int[] dijkstra(int v) {
     
 
	}
}

你可能感兴趣的:(蓝桥杯,Java,数据结构,蓝桥杯,Java)