数据结构Java基础

List接口有序有索引,允许重复

list.add();//添加

list.remove(索引);//移除

list.set(索引,"");//替换

list集合遍历三种方式

for(int i=0;i<list.size();i++)

迭代器Iterator<String> it=list.Iterator();

while(it.hasNext){};

增强for循环for(String s:list){};

LinkedList底层是链表

LinkedList<String> linked=new LinkedList<>();//不能使用多态

linked.pop;//相对于list的remove

数组:查询快(首地址索引可以快速查找)增删慢(创建新数组,原数组垃圾回收)

//判断为空
public boolean isEmpty(){
    return size==0;
}
//获取容量
public int getCapacity(){
    return data.length;
}
//获取元素个数
public int getSize{
    return size;
}
//添加一个元素
public void addLast(int e){
    if(size==data.length)
        throw new IllegalArgumentException(AddLast failed.Array is full)
    data【size】=e;
    size++;
}
//指定位置添加元素
public void add(int e,int index){
     if(size==data.length)
        throw new IllegalArgumentException(Add failed.Array is full)
     if(index<0||index>size)
        throw new IllegalArgumentException(Add failed.Require index>=0 and index <=size)
     for(int i =size-1;i>=index; i--)
        data[i] = data[i-1];
     data[index] = e;
     size++;
//字符串输出
public String toString(){
    String string = new String();
    string.append("[")
    for(int i=0;i<size; i++){
        string.append(i);
    if(i!=size-1)
        string.append("]");
    }
    return string.toString();
}
//搜索
public boolean contains(int e){
    for(int i =0;i <size;i++){
        if(data[i]=e)
                return true;    
    }return false;
}
//删除
public int remove(int index){
     if(index<0||index>size)
        throw new IllegalArgumentException(Add failed.Require index>=0 and index <=size)
     int a = data[index];
     for(int i =index+1;i<size;i++)
        data[i-1]=data[i];
     size--;
     return a;
}
栈
Stack<String> stack = new Stack<>();
//添加到栈顶
stack.push(e);
//删除栈底并返回该元素
stack.push(e);

队列
Queue<String> queue = new Queue<>();
//元素添加到队列尾
queue.enqueue(e);
//删除队列头
queue.dequeue(e);

循环队列
//队尾添加元素
public void enqueue(E e){
    if(tail+1)%data.length == front;
        resize(getCapacity * 2);
    data[tail] = e;
    tail = (tail+1)%data.length;
    size++;
}
//队首删除元素
Public void dequeue(){
    if(isEmpty()
        throw new
    E ret = data[front];
    data[front] = null;
    front = (front+1)% data.length;
    return ret;
    size--;
//扩容
private void resize(int new Capacity){
    E[] newData = (E[])new Object[beCapacity+1];
    for(int i = 0;i<size;i++)
        newData[i] = data[front+i]%data.length;
    data = newData;
    front=0;
    tail =size;}
//得到容积
public int getCapacity(){
    return data.length-1;
}
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
使用java中的linkedList集合来实现一个队列,通过调用linkedList中的方法来实现队列的入队出队,判空等操作
Queue<Node> q = new LinkedList<>():

链表 是动态结构,不需要提前分配空间,,地址不连续,查询需从头开始,插入和删除不需要移动元素 (查询慢增删快)

一个元素也叫做一个节点,一个节点包括一个数据和两个地址

链表的增加删除修改查找O(n)
数据存储在节点Node中,优点是真正的动态不需要处理固定容量的问题,缺点是丧失随机访问能力
//头部插入新元素,头没有前面的节点
public void addFirst(E e){
    Node node = new Node(e);
    node.next = head;
    head = node;
    size++;
}
//设立虚拟节点
dummyhead
//尾部插入
public void addLast(E e){
    Node node = new Node(e);
    if(tail==null)
        tail=head=node;
    else{tail.next = node;
        tail = tail.next;}
    size++;
}
//指定位置插入元素
public void add(int index, E e){
    if(index==0)
        addFirst(e);
    else if(index>size\\index<0)
       throw
    else{
        Node pre = head;
        for(int i = 0; i<index-1;i++)
            pre = pre.next;
        Node node = new Node(e);
        node.next = pre.next;
        pre.next = node;
        size++;
        }
}
//获得索引元素
public void get(int index,){
    if(index<0 || index>=size)
            throw
    Node cur = head.next;
    for(int i=0;i<index;i++)
        cur = cur.next;
    return cur;
//查询是否有e
public boolean find(int e){
    Node cur = head.next;
    while(cur!=null){
        if(cur=e){
            return true;
        cur = cur.next;}
    return false;
//更新
public void set(int index,int e){
     if(index<0 || index>=size)
            throw
    Node cur = head.next;
    for(int i=0;i<index;i++)
        cur = cur.next;
    cur = e;}
//删除
public E remove(int index){
    if(index<0 || index>=size)
            throw
    Node pre = head;
    for(int i =1;i<index;i++){
       pre=pre.next;
    Node restnode = pre.next;
    pre.next = retnode.next;
    retnode.next = null;}
    return E retnode;

堆:每个节点的值都大于等于其左右子节点的值称为大顶堆,arr[i]>=arr[2*i+1]&&arr[i]>=arr[2*i+2]
每个节点的值小于等于其左右子节点的值称为小顶堆
package day;

import java.util.Arrays;

public class HeapSort{
	
    public static void main(String[] args){
    		int[] arr= {4,7,1,2,6};
    		heapSort(arr);
    }   		
    //编写一个堆排序的方法
    public static void heapSort(int arr[]) {
    	int t=0;
    	for(int i=arr.length/2-1;i>=0;i--) {
		adjustheap(arr, i, arr.length);}
    	for(int j=arr.length-1;j>=0;j--) {
    		t=arr[j];
    		arr[j]=arr[0];
    		arr[0]=t;
    		adjustheap(arr, 0,j);
    	}
		System.out.println(Arrays.toString(arr));
	}
    /**
    @param arr待调整数组
    @param i 非叶子节点在数组中索引
    @param length 对多少个元素继续调整
    */
    //将数组调整成大顶堆
    public static void adjustheap(int arr[],int i,int length) {
		int t=arr[i];
		//开始调整,i的左子节点是2*i+1
		for(int k=2*i+1;k<length;k=k*2+1) {
			//左子节点小于右子节点
			if(arr[k+1]<arr[k+1]&&k+1<length) {
				k++;//指向右子节点
			}
			if(arr[k]>t) {//如果子节点大于父节点
				arr[i]=arr[k];//较大值赋给当前节点
				i=k;//i指向k,继续循环比较
			}else {
				break;
			}
		}
		arr[i]=t;//将原来的值放调整后的位置
	}
}
package day;
public class ArrayBinaryTreedemo{
	//顺序存储二叉树
    public static void main(String[] args){
    	int[] arr= {1,2,3,4};
    	ArrayBinaryTree arrayBinaryTree=new ArrayBinaryTree(arr);
    	//arrayBinaryTree.preorder(0);
    	arrayBinaryTree.preorder();
}
    class ArrayBinaryTree{
    	private int[] arr;
    	public ArrayBinaryTree(int[] arr) {
			this.arr=arr;
		}
    	//重载方法
    	public void preorder() {
    		this.preorder(0);
    	}
    	//编写一个方法完成前序遍历
    	public void preorder(int index) {
			if(arr==null||arr.length==0) {
				System.out.println("数组为空,不能进行前序遍历");
		}//输出当前这个元素
    	System.out.println(arr[index]);
    	//左递归遍历
    	//第n个元素左子节点为2*n+1
    	if((index*2+1)<arr.length) {
    		preorder(2*index+1);
    	}
    	//右递归遍历
    	//第n个元素右子节点为2*n+2
    	if((index*2+2)<arr.length) {
    		preorder(2*index+2);
    	}
    }
}}

遍历

package day;
public class BinaryTreedemo{
    public static void main(String[] args){
    	BinaryTree binaryTree=new BinaryTree();
    	//创建节点
    	HerodNode root=new HerodNode(1, "Ruby");
    	HerodNode HerodNode1=new HerodNode(2, "Weiss");
    	HerodNode HerodNode2=new HerodNode(3, "Blake");
    	HerodNode HerodNode3=new HerodNode(4, "Yang");
    	//创建二叉树
    	root.setLeftHerodNode(HerodNode1);
    	root.setRightHerodNode(HerodNode2);
    	HerodNode2.setLeftHerodNode(HerodNode3);
    	binaryTree.setRoot(root);
    	//前序遍历
    	binaryTree.preorder();
    	//前序查找
    	HerodNode resHerodNode=binaryTree.preordersearch(1);
    	if(resHerodNode!=null) {
    		System.out.printf("no=%dname=%s,resHerodNode.getNo(),resHerodNode.getName()");
    	}else {
    		System.out.printf("没有找到");
    	}
    }
    //定义二叉树
    class BinaryTree{
    	private HerodNode root;
		public void preorder() {//前序遍历
    		if(this.root!=null) {
    			this.root.preorder();
    			}
    		System.out.println("二叉树空");
    		}
    	public void inorder() {
    		if(this.root!=null) {
    			this.root.preorder();
    		}
    		System.out.println("二叉树空");
    	}
    	public void postorder() {
    		if(this.root!=null) {
    			this.root.preorder();
    		}
    		System.out.println("二叉树空");
    	}
    	public HerodNode preordersearch(int no) {//前序查找
			if(root!=null) {
				return root.preordersearch(no);
				}else {
					return null;
				}
			}
    	public void del(int no) {
			//是空树则等价二叉树置空
    		if(this.root!=null) {
    			//判断root是不是要删除的节点
    			if(root.getNo()==no) {
    			this.root=null;}else {
    				root.del(no);
    			}
    			}
    		else {System.out.println("空树不能删除");
    			}
    		}
    }
    //创建HerodNode节点
    class HerodNode{
    	private int no;
    	private String name;
    	private HerodNode leftHerodNode;//默认null
    	private HerodNode rightHerodNode;//默认null
		public HerodNode(int no, String nameString) {
			super();
			this.no = no;
			this.name = nameString;
		}//private的只有对象自己才可以访问,安全性高,其他对象只能通过它的public方法,
		//set,get来获取或设置原对象的private属性。而public其他对象可以访问,安全性就不高了。
		public int getNo() {
			return no;
		}
		public void setNo(int no) {
			this.no = no;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public HerodNode getLeftHerodNode() {
			return leftHerodNode;
		}
		public void setLeftHerodNode(HerodNode leftHerodNode) {
			this.leftHerodNode = leftHerodNode;
		}
		public HerodNode getRightHerodNode() {
			return rightHerodNode;
		}
		public void setRightHerodNode(HerodNode rightHerodNode) {
			this.rightHerodNode = rightHerodNode;
		}//toString()将节点更方便输出
		@Override
		public String toString() {
			return "HerodNode [no=" + no + ", name=" + name + "]";
		}
		//前序遍历
		public void preorder() {
			System.out.println(this);//输出父节点
			//不为空递归左子树
			if(this.leftHerodNode!=null) {
				this.leftHerodNode.preorder();
			}
			//递归右子树
			if(this.rightHerodNode!=null) {
				this.rightHerodNode.preorder();
			}
		}
		//中序遍历
		public void inorder() {
			//不为空递归左子树
			if(this.leftHerodNode!=null) {
				this.leftHerodNode.preorder();
			}
			System.out.println(this);//输出父节点
			//递归右子树
			if(this.rightHerodNode!=null) {
				this.rightHerodNode.preorder();
			}
		}
		//后序遍历
			public void postorder() {
				//不为空递归左子树
				if(this.leftHerodNode!=null) {
					this.leftHerodNode.preorder();
				}
				//递归右子树
				if(this.rightHerodNode!=null) {
					this.rightHerodNode.preorder();
				}
				System.out.println(this);//输出父节点
			}
			//前序查找,找到就返回Node没找到就null
			public HerodNode preordersearch(int no) {
				//比较当前节点
				if(this.no==no) {
					return this;//谁调用this,this就指向谁
				}
				//判断左子节点是否为空,不为空就递归前序查找,找到节点则返回
				 HerodNode resHerodNode=null;
				if(this.leftHerodNode!=null) {
					resHerodNode=this.leftHerodNode.preordersearch(no);
				}
				if(resHerodNode!=null) {//已找到
					return resHerodNode;
				}
				//判断右子节点是否为空,不为空就递归前序查找
				if(this.rightHerodNode!=null) {
					resHerodNode=this.rightHerodNode.preordersearch(no);
				}
				return resHerodNode;
			}
			
//二叉树是单向的,所以判断当前节点的子节点是否需要删除,而不是判断当前这个节点是不是需要删除

			public HerodNode del(int no) {
		//如果左子节点不为空,且左子节点就是要删除节点,this.left=null然后返回
				if(this.leftHerodNode==no&&this.leftHerodNode!=null) {
					this.leftHerodNode=null;
					return;
				}
		//如果右子节点不为空,且左子节点就是要删除节点,this.right=null然后返回
				if(this.rightHerodNode==no&&this.rightHerodNode!=null) {
					this.rightHerodNode=null;
					return;
				}
				//如果左右子节点不是要删除的,就向左子树,递归删除
				if(this.leftHerodNode!=null) {
					this.leftHerodNode(no);
				}
				//如果左子树没有就向右子树,递归删除
				if(this.rightHerodNode!=null) {
					this.rightHerodNode(no);
				}
				
			}
		}
}
    

集合set

Set:1.不允许重复对象

     2. 无序容器,没有索引,无法for循环,底层是哈希表(查询速度快)

        3. 只允许一个 null 元素

        4.Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。

Set<Integer> set= new HashSet<>();
set.add();//添加
Iterator<Integer> it=set.iterator();
while(it.hasNext()){
    Integer n=it.next();
}

HashSet

哈希值是一个十进制整数由系统随机给出,是一个模拟出的逻辑地址int hashCode()返回哈希值是object类的方法

HashSet中的键值是唯一的,不可重复的

HashSet<String> set = new HashSet<>();

  • String s1 = new String("aaa");

  • set.add(s1);

  • HashSet存储自定义类型元素需要重写hashcode方法和equals方法

映射Map

 

多重映射key可以重复
映射基于二分搜索树实现,二分搜索树元素必须comparable
public class BSTMap<K extends Comparable<K>,V> implements Map<K,V>{
    private class Node{
        public K key;
        public V value;
        public Node left,right;

        public Node(K key,Vvalue){
            this.key = key;//this.key即用户传来的key
            this.value = value;
            left = null;
            right = null;}}
    private Node root;
    private int size;
    public BSTMap(){
        root = null;
        size=0;}
    public int getSize(){
        return size;}
    public boolean isEmpty(){
        return size==0;}
//向以node为根的二分搜索树中插入元素(key,value),递归算法
//返回插入新节点后二分搜索树的根
    public void add(K key, V value)
        root = add(root,key,value);

private Node add(Node node, K key, V value){
    if(node == null){
        size ++;
        return new Node(key,value):}
    if(key.compareTo(node.key)<0)
        node.left = add(node.left,key,value);
    else if(key.compareTo(node.key)>0)
        node.right = add(node.right,key,value);
    else
        node.value = value;
    return node;}
//返回以node为根节点的二分搜索树key所在的节点
private Node getNode(Node node,K key){
    if(node==null)
        return null;
    if(key.comparaTo(node.key)==0)
        return node;
    else if(key.comparaTo(node.key)<0)
        return getNode(node.left,key);
    else
         return getNode(node.right,key);
//得到key所对应的value
public V get(K key){
    Node node = getNode(root,key);
    return node==null?null:node.value;}
//删除掉以node为根的二分搜索树中值为e的节点,递归算法
//返回删除节点后新的二分搜索树的根
public void remove(K key){
    Node node = getNode(root);
    if(node!=null){
        roote = remove(root,e);
        return node.value;}
    return null;}
private Node remove(Node node,K key){
    if(node==null)
        return null;
    if(key.compareTo(node.key)<0)
        {node.left = remove(node.left,key);
        return node;}
    else if(key.compareTo(node.key)>0)
        {node.right = remove(node.right,key);
        return node;}
    else{//待删除节点左子树为空
        if(node.left==null){
            Node rightnode = node.right;
            node.right = null;
            size--;
            return rightnNode;}
        if(node.right==null){
            Node leftnode = nodeleft;
            node.left = null;
            size--;
            return leftnNode;}
  `//带删除节点左右子树都不空,找到比待删除节点大的最小节点,即待删除节点右子树最小节点
    Node successor = minimum(node.right);
    succeor.rgh remove(node.rght);
    uccessor.left = node.lef;
    node.left= node.right=null;

可变参数(类型确定,个数不确定,底层是数组)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值