头歌JAVA数据结构答案

这篇博客详细介绍了Java中数据结构的实现,从循环链表和线性表开始,涵盖栈、队列、二叉搜索树、二叉树以及排序算法,最后探讨了图的表示及搜索算法。内容包括各数据结构的添加、删除、查找等操作,适合深化对Java数据结构的理解。
摘要由CSDN通过智能技术生成

头歌JAVA数据结构答案

一、Java数据结构-循环链表的设计与实现

第1关 单循环链表的实现—链表的添加、遍历

package step1;
/**
 * Created by sykus on 2018/1/15.
 */
public class MyCircleLinkedList {
    private Node head;//头结点, 不存数据
    private Node tail;//尾结点, 指向链表的最后一个节点
    private int size;
    public MyCircleLinkedList() {
        head = new Node(Integer.MIN_VALUE, null);
        head.next = head;
        tail = head;
        size = 0;
    }
    /**
     * 添加到链表尾部
     *
     * @param item
     */
    public void add(int item) {
        /********** Begin *********/
        Node node = new Node(item, tail.next);
        tail.next = node;
        tail = node;
        ++size;
        /********** End *********/
    }
    /**
     * 遍历链表并输出元素
     */
    public void output() {
        /********** Begin *********/
        Node p = head;
        while (p.next != head) {
            p = p.next;
            System.out.println(p.item);
        }
        /********** End *********/
    }
    public boolean isEmpty() {
        return head.next == head;
    }
    public int size() {
        return size;
    }
    //结点内部类
    private static class Node {
        int item;
        Node next;
        Node(int item, Node next) {
            this.item = item;
            this.next = next;
        }
    }
}

第2关 单循环链表的实现—链表的删除

package step2;
/**
 * Created by sykus on 2018/1/15.
 */
public class MyCircleLinkedList {
    private Node head;//头结点, 不存数据
    private Node tail;//尾结点, 指向链表的最后一个节点
    private int size;
    public MyCircleLinkedList() {
        head = new Node(Integer.MIN_VALUE, null);
        head.next = head;
        tail = head;
        size = 0;
    }
    /**
     * 添加到链表尾部
     *
     * @param item
     */
    public void add(int item) {
        Node node = new Node(item, tail.next);
        tail.next = node;
        tail = node;
        ++size;
    }
    /**
     * 遍历链表并输出元素
     */
    public void output() {
        Node p = head;
        while (p.next != head) {
            p = p.next;
            System.out.println(p.item);
        }
    }
    /**
     * 删除从头结点开始的第index个结点
     * index从0开始
     *
     * @param index
     * @return
     */
    public int remove(int index) {
        checkPosIndex(index);
        /********** Begin *********/
        Node f = head;
        while ((index--) > 0) {
            f = f.next;
        }
        Node del = f.next;
        if (del == tail) {//要删除的是尾结点
            tail = f;//使tail依然指向末尾结点
        }
        f.next = del.next;
        del.next = null;
        int oldVal = del.item;
        del = null;
        --size;
        return oldVal;
        /********** End *********/
    }
    public boolean isEmpty() {
        return head.next == head;
    }
    public int size() {
        return size;
    }
    private void checkPosIndex(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
    }
    //结点内部类
    private static class Node {
        int item;
        Node next;
        Node(int item, Node next) {
            this.item = item;
            this.next = next;
        }
    }
}

第3关 双向循环链表的实现—链表的插入

package step3;
/**
 * Created by sykus on 2018/1/15.
 */
public class MyDoubleLinkedList {
    private Node head;//头结点
    private Node tail;//指向链表的尾结点
    private int size;
    public MyDoubleLinkedList() {
        head = new Node(null, Integer.MIN_VALUE, null);
        head.next = head.prev = head;
        tail = head;
        size = 0;
    }
    /**
     * 添加元素到表尾
     *
     * @param item
     */
    public void add(int item) {
        /********** Begin *********/
        Node newNode = new Node(null, item, null);
        tail.next = newNode;
        newNode.prev = tail;
        newNode.next = head;
        head.prev = newNode;
        tail = newNode;
        ++size;
        /********** End *********/
    }
    /**
     * 打印双向链表
     *
     * @param flag true从左向右顺序打印, false从右向左顺序打印
     */
    public void printList(boolean flag) {
        Node f = head;
        if (flag) {//向右
            while (f.next != head) {
                f = f.next;
                System.out.print(f.item + " ");
            }
        } else {//向左
            while (f.prev != head) {
                f = f.prev;
                System.out.print(f.item + " ");
            }
        }
    }
    public int size() {
        return size;
    }
    //结点内部类
    private static class Node {
        int item;
        Node next;//直接后继引用
        Node prev;//直接前驱引用
        Node(Node prev, int item, Node next) {
            this.prev = prev;
            this.item = item;
            this.next = next;
        }
    }
}

第4关:双向循环链表的实现—链表的删除

package step4;
/**
 * Created by sykus on 2018/1/15.
 */
public class MyDoubleLinkedList {
    private Node head;//头结点
    private Node tail;//指向链表的尾结点
    private int size;
    public MyDoubleLinkedList() {
        head = new Node(null, Integer.MIN_VALUE, null);
        head.next = head.prev = head;
        tail = head;
        size = 0;
    }
    /**
     * 添加元素到表尾
     *
     * @param item
     */
    public void add(int item) {
        Node newNode = new Node(null, item, null);
        tail.next = newNode;
        newNode.prev = tail;
        newNode.next = head;
        head.prev = newNode;
        tail = newNode;
        ++size;
    }
    /**
     * 删除指定位置index出的结点,并返回其值
     *
     * @param index
     * @return
     */
    public int remove(int index) {
        checkPosIndex(index);//
        /********** Begin *********/
        Node p = head.next;
        while ((index--) > 0) {
            p = p.next;
        }
        if (p == tail) {
            tail = p.prev;
        }
        p.prev.next = p.next;
        p.next.prev = p.prev;
        int val = p.item;
        p = null;
        --size;
        return val;
        /********** End *********/
    }
    /**
     * 打印双向链表
     *
     * @param flag true从左向右顺序打印, false从右向左顺序打印
     */
    public void printList(boolean flag) {
        Node f = head;
        if (flag) {//向右
            while (f.next != head) {
                f = f.next;
                System.out.print(f.item + " ");
            }
        } else {//向左
            while (f.prev != head) {
                f = f.prev;
                System.out.print(f.item + " ");
            }
        }
    }
    public int size() {
        return size;
    }
    private void checkPosIndex(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
    }
    //结点内部类
    private static class Node {
        int item;
        Node next;//直接后继引用
        Node prev;//直接前驱引用
        Node(Node prev, int item, Node next) {
            this.prev = prev;
            this.item = item;
            this.next = next;
        }
    }
}

二、Java数据结构-线性表的设计与实现

第1关:顺序表的实现之增删功能

package step1;
/**
 * Created by zengpeng on 2017/12/25.
 */
public class MyArrayList {
    private int[] elements;//元素
    private int size;//List中当前的元素个数
    public MyArrayList() {
        this(1);//List默认大小为1
    }
    /**
     * 按指定大小capacity构造List
     *
     * @param capacity List初始化时的大小
     */
    public MyArrayList(int capacity) {
        elements = new int[capacity];
        size = 0;
    }
    /**
     * 返回List中元素的个数
     *
     * @return
     */
    public int size() {
        return size;
    }
    /**
     * 添加一个元素到末尾
     *
     * @param item
     */
    public void Add(int item) {
        int len = elements.length;
        if (size == len - 1) {
            resize(2 * len);
        }
        /********** Begin *********/
        elements[size++] = item;
        /********** End *********/
    }
    /**
     * 添加一个元素到指定位置index
     *
     * @param index
     * @param item
     */
    public void Add(int index, int item) {
        validateRangeForAdd(index);
        int len = elements.length;
        if (size == len - 1) {
            resize(2 * len);
        }
        /********** Begin *********/
        for (int i = size; i > index; i--) {
            elements[i] = elements[i - 1];
        }
        elements[index] = item;
        size++;
        /********** End *********/
    }
    /**
     * 删除指定位置index的元素,并返回被删除的元素
     *
     * @param index
     * @return
     */
    public int remove(int index) {
        validateRange(index);
        /********** Begin *********/
        int oldVal=elements[index];
        for (int i = index; i < size - 1; i++) {
            elements[i] = elements[i + 1];
        }
        --size;
        return oldVal;
        /********** End *********/
    }
    /**
     * 校验索引范围
     *
     * @param index
     */
    private void validateRange(int index) {
        if (index >= size || index < 0) {
            throw new ArrayIndexOutOfBoundsException("索引越界了哦!Index: " + index + ", Size: " + size);
        }
    }
    /**
     * 校验索引范围
     *
     * @param index
     */
    private void validateRangeForAdd(int index) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException("索引越界了哦!Index: " + index + ", Size: " + size);
    }
    /**
     * 动态扩展数组大小
     *
     * @param capacity
     */
    private void resize(int capacity) {
        assert capacity > size;
        int[] tmp = new int[capacity];
        for (int i = 0; i < size; i++) {
            tmp[i] = elements[i];
        }
        elements = tmp;
    }
}

第2关: 顺序表的实现之查询功能

package step2;
/**
 * Cre
Java数据结构栈是一种后进先出(LIFO)的数据结构,它可以存储和操作一组相同类型的元素。栈在计算机科学中有广泛的应用,其中一些包括: 1. 表达式求值:在数学表达式求值过程中,我们可以使用栈来处理操作符和操作数。当遇到一个操作符时,我们可以将其压入栈中。当遇到一个操作数时,我们可以执行相应的操作符,然后将结果重新压入栈中。这种方法可以实现对复杂表达式的计算。 2. 函数调用:在编程中,函数调用通常使用栈来管理函数的执行过程。当一个函数被调用时,它的参数和局部变量会被压入栈中。当函数执行完毕时,这些数据将会从栈中弹出。 3. 浏览器历史记录:当我们在浏览器中打开一个新的网页时,浏览器会将网页URL压入一个栈中。当我们按下后退按钮时,浏览器会从栈中弹出最近访问的URL,以便返回上一个页面。 4. 撤销操作:在编辑器或文本处理软件中,栈可以用来实现撤销操作。每当我们进行修改时,软件会将修改前的文本压入栈中。当我们需要撤销修改时,软件会从栈中弹出最近的一次修改。 5. 符号匹配:在编程语言解析中,栈可以用来检查符号是否正确匹配。例如,我们可以使用栈来验证括号是否正确闭合。 综上所述,Java数据结构栈在许多不同的应用领域中发挥着重要作用。通过理解和灵活运用栈,我们可以提高程序的效率并简化算法的实现。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值