数据结构与基本算法(Java语言实现)

源代码: Java数据结构与基本算法

1. 数据结构简介

1.1 定义

数据结构就是研究数据的逻辑结构,存储结构和运算方法的统筹感念。数据的逻辑结构包括:线性结构,树形结构,图形结构。线性结构指的是一对一的关系,树形结构存在一对多的关系,图形结构存在多对多的关系,存在一对多和多对多关系的又称为非线性结构
Java数据结构

1.2 存储方式

数据结构的存储结构:顺序存储(ArrayList),链式存储(LinkedList),索引存储(B-Tree和自定义索引),散列存储(hasCode)

2. 数据结构 — 线性表

线性表是一种线性数据结构,元素存在"一对一的关系",线性表的每个数据元素的类型都是相同的
代表性的有:一维数组和线性链表

2.1 数组

2.1.1 基本类型数组

例如:向一维数组做,插入,更新,替换,删除操作时:

// 声明一个数组
int[] scores = {1, 2, 3, 4, 5, 6};

// 1. 在数据尾部位置插入一个数字
scores = add(scores, 7);
public static int[] add(int[] array, int score) {
        int[] tempArray = new int[array.length + 1];
        for (int i = 0; i < array.length; i++) {
            tempArray[i] = array[i];
        }
        tempArray[array.length] = score;
        return tempArray;
    }
    
// 2. 向一维数组任意位置(指定位置)修改一个数据,真实位置=要求位置-1
scores = update(scores, 7, 2);
public static int[] update(int[] arrary, int score, int index) {
        arrary[index] = score;
        return arrary;
}

// 3. 替换一个数字到指定位置
scores = insert(scores, 7, 2);//将75插入到索引为2的位置
public static int[] insert(int[] array, int score, int index) {
        int[] tempArray = new int[array.length + 1];
        for (int i = 0; i < array.length; i++) {
            if (i < index) {
                tempArray[i] = array[i];
            } else {
                tempArray[i + 1] = array[i];
            }
        }
        tempArray[index] = score;
        return tempArray;
    }

// 4. 删除指定位置的数字
scores = delete(scores, 3);
public static int[] delete(int[] array, int index) {
        int[] tempArray = new int[array.length - 1];
        for (int i = 0; i < array.length; i++) {
            if (i <= index) {
                tempArray[i] = array[i];
            } else {
                tempArray[i - 1] = array[i];
            }
        }
        return tempArray;
    }

2.1.2 封装类型ArrayList数组

//声明初始接口方法
public interface List {
    public void add(Object element);//添加元素
    public Object get(int index);//获得元素
    public Object set(int index,Object element);//修改元素
    public Object remove(int index);//删除元素
    public int size();//集合大小
}
//实现声明接口的数组
public class ArrayList implements List {
    private int initCapacit = 20;//初始数组大小
    private int size;//元素个数
    private Object[] elementData;//数据数组对象

    public ArrayList() {
        elementData = new Object[initCapacit];
    }

    public ArrayList(int initCapacit) {
        elementData = new Object[initCapacit];
        this.initCapacit = initCapacit;
    }

    //添加元素
    @Override
    public void add(Object element) {
        if (size < initCapacit) {
            elementData[size] = element;
            size++;
        } else {
            elementData = expandArray(elementData);
            elementData[size] = element;
            size++;
        }
    }

    //扩充List对象数组大小
    public Object[] expandArray(Object[] elementData) {
        Object[] tempArray = new Object[elementData.length * 2];//每次扩充为原来的2倍大小
        for (int i = 0; i < elementData.length; i++) {
            tempArray[i] = elementData[i];
        }
        return tempArray;
    }

    //获得元素
    @Override
    public Object get(int index) {
        return elementData[index];
    }

    //集合大小
    @Override
    public int size() {
        return size;
    }

    //删除元素
    @Override
    public Object remove(int index) {
        Object removeObj = elementData[index];
        //删除元素后面的元素前移
        for (int i = index; i < size; i++) {
            elementData[i] = elementData[i + 1];
        }
        size--;
        return removeObj;
    }
    
    //修改元素
    @Override
    public Object set(int index, Object element) {
        elementData[index] = element;
        return element;
    }

2.1.3 ArrayList数组迭代器

public interface List {
    public Iterator iterator();//获取迭代器;;
}

public interface Iterator {
    public boolean hasNext();//是否有下一个元素
    public Object next();//获得下一个元素
}

//是否有下一个元素
    @Override
    public boolean hasNext() {
        return index < list.size();
    }

    //获得下一个元素
    @Override
    public Object next() {
        Object element = null;
        if (index < list.size()) {
            element = list.get(index);
            index++;
        }
        return element;
    }
    
    //迭代打印集合元素
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Object obj = iterator.next();
            System.out.println(obj);
        }

2.2 链表

2.2.1 单链表

//单链表的结构,Node的自引用,next代表指针变量指向下一个节点
public class Node {
    private String data;//节点数据
    private Node next;//下一个节点

    public Node(String data, Node next) {
        this.data = data;
        this.next = next;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }
}

2.2.2 单循环链表

 // 核心在于打印两次,头开始到尾,再从尾到头循环打印
 public static void print(Node node) {
        Node p = node;
        Node startNode = node;
        int circleCount = 0;//循环打印次数
        while (circleCount < 2) {
            //从头开始到尾,再从尾到头循环打印
            String data = p.getData();
            System.out.print(data + "→");
            p = p.getNext();
            if (p.getNext() == startNode) {
                circleCount++;
            }
        }
        String data = p.getData();
        System.out.print(data + "\n\n");
    }

2.2.3 双链表

// 双链表,prev和next两个指针变量  prev-data-next
class Node {
    private String data;//结点数据
    private Node prev;//上一个结点
    private Node next;//下一个结点

    public Node(String data, Node prev, Node next) {
        this.data = data;
        this.prev = prev;
        this.next = next;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public Node getPrev() {
        return prev;
    }

    public void setPrev(Node prev) {
        this.prev = prev;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }
}

2.2.4 双向循环链表

       nt circleCount = 0;//循环打印次数
        while (circleCount < 2) {
            //从头开始直到尾结束,再从尾到头循环打印
            String data = p.getData();
            System.out.print(data + "->");
            p = p.getNext();
            if (p.getNext()==startNode){
                circleCount++;
            }
        }

2.2.5 LinkedList实现

public interface List {
    public void add(Object element);//添加元素
    public Object get(int index);//获得元素
    public Object set(int index,Object element);//修改元素
    public Object remove(int index);//删除元素
    public int size();//集合大小
}

//节点内部类,双向
 class Node {
    private Object data;//节点数据
    private Node prev;//上一个节点
    private Node next;//下一个节点
    public Node(Object data,Node prev,Node next){
        this.data=data;
        this.prev=prev;
        this.next=next;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public Node getPrev() {
        return prev;
    }

    public void setPrev(Node prev) {
        this.prev = prev;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }
}

public class LinkedList implements List {
    private Node head;//定义头节点
    private Node tail;//定义尾节点
    private int size;//元素个数
    public LinkedList(){

    }
    //表尾插入数据,没有指定位置
    @Override
    public void add(Object element) {
        if (head==null){
            head=new Node(element,null,null);
            tail=head;
        }
        else {
            Node newNode=new Node(element,null,null);
            tail.setNext(newNode);
            newNode.setPrev(tail);
            tail=newNode;
        }
        size++;
    }

    @Override
    public Object get(int index) {
        Node p=head;
        int i=0;
        while (p.getNext()!=null && i<index)
        {
            p=p.getNext();
            i++;
        }
        return p.getData();
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public Object set(int index, Object element) {
        Node p=head;
        int i=0;
        while (p.getNext()!=null && i<index){
            p=p.getNext();
            i++;
        }
        p.setData(element);
        return element;
    }

    @Override
    public Object remove(int index) {
        Node p=head;
        int i=0;
        while (p.getNext()!=null && i<index){
            p=p.getNext();
            i++;
        }
        Node temp=p;//保存要删除的节点
        p.getPrev().setNext(p.getNext());
        p.getNext().setPrev(p.getPrev());
        temp.setNext(null);
        temp.setPrev(null);
        size--;
        return temp.getData();
    }
}

2.2.6 LinkedList迭代器

public interface List {
    public Iterator iterator();//获取迭代器;;
}
public interface Iterator {
    public boolean hasNext();//是否有下一个元素
    public Object next();//获得下一个元素
}

    @Override
    public boolean hasNext() {
        return currentNode!=null;
    }

    @Override
    public Object next() {
        Object element=null;
        element=currentNode.getData();
        currentNode=currentNode.getNext();
        return element;
    }
       //迭代打印元素
        Iterator iterator=list.iterator();
        while (iterator.hasNext()){
            Object obj=iterator.next();
            System.out.println(obj);
        }

2.3 栈

栈是限制在表尾进行插入和删除的线性表,特性是先进后出,主要应用在铁路和存放桶

2.4 队列

队列(Single Queue)是限制在表的两端进行操作的线性表,主要特点是"先进先出",队首部允许删除,队尾允许插入

2.5 串

串是零个或多个任意字符组成的有限队列,串也分顺序存储和链式存储,Java中有基本字符类型Char和封装字符串类型String类

2.6 多维数组

2.6.1 二维数组

2.7 广义表

3. 数据结构 之 非线性表

3.1 树

3.1.1 二叉树

3.1.2 红黑树

3.2 图

3.2.1 无向图

3.2.1.1 广度优先搜索
3.2.1.1 深度优先搜索

3.2.2 有向图

3.2.2.1 广度优先搜索
3.2.2.1 深度优先搜索

3.3 散列表

3.3.1 哈希

3.3.2 自定义存储

3.4 堆

3.4.1 大顶堆

3.4.2 小顶堆

4. 查找

查找分为静态查找和动态查找(对查找表进行插入元素或删除元素的操作)
静态查找表包含顺序查找,分块查找和二分折半查找(效率较高)

4.1 静态查找

4.1.1 二分折半查找

4.2 动态查找

4.2.1 哈希查找

4.2.2 二叉搜索

5. 基本算法

基本算法

5.1 稳定排序

5.1.1 冒泡排序

5.1.2 插入排序

5.1.3 归并排序

5.1.4 计数排序

5.1.5 桶排序

5.1.6 基数排序

5.2 不稳定排序

5.2.1 选择排序

5.2.2 希尔排序

5.2.3 快速排序

5.2.4 堆排序

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值