Java数据结构实现案例

数据结构

数据结构包括:线性结构和非线性结构

线性结构
  • 线性结构是最常用的数据结构,特点是元素和下标为一对一的关系(a[0] = 0)
  • 线性结构分为两种存储:顺序存储结构(数组)和链式存储结构(链表)。顺序存储称为顺序表,储存的元素是连续的。链式存储 称为链表,链表中的储存元素不一定是连续的,元素节点中存放元素及相邻元素的地址信息。
  • 线性结构常见的有:数组、队列、链表和栈
非线性结构
  • 非线性结构包括:二维数组,多维数组,广义表,树结构,图结构
稀疏数组
package dataStructure;

/**
 * 稀疏数组
 *
 * @author zqh
 **/
public class XisuArray {
    public static void main(String[] args) {
        //初始化创建一个二维数组
        int[][] array = new int[11][11];
        array[1][2] = 1;
        array[2][3] = 2;
        System.out.println("原始的二维数组");
        for (int[] row : array) {
            for (int item : row) {
                System.out.printf("%d\t", item);
            }
            System.out.println();
        }
        //获取有效的数字
        int sum = 0;
        int length = array.length;
        for (int[] row : array) {
            for (int j = 0; j < length; j++) {
                if (row[j] != 0) {
                    sum++;
                }
            }
        }
        System.out.println("有效数字:" + sum);
        //sum + 1因为第一行是存二维数组的行列 后面是值
        int[][] sparseArray = new int[sum + 1][3];
        sparseArray[0][0] = length;
        sparseArray[0][1] = length;
        sparseArray[0][2] = sum;

        //遍历二维数组给稀疏数组赋非0值
        int count = 0;
        for (int i = 0; i < length; i++) {
            for (int j = 0; j < length; j++) {
                if (array[i][j] != 0) {
                    count++;
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = array[i][j];
                }
            }
        }
        System.out.println("稀疏数组");
        for (int[] ints : sparseArray) {
            System.out.printf("%d\t%d\t%d\t\n", ints[0], ints[1], ints[2]);
        }

        //将稀疏数组恢复成二维数组
        int[][] array2 = new int[sparseArray[0][0]][sparseArray[0][1]];

        for (int i = 1; i < sparseArray.length; i++) {
            array2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        }

        System.out.println("恢复后的二维数组");
        for (int[] row : array2) {
            for (int item : row) {
                System.out.printf("%d\t", item);
            }
            System.out.println();
        }
    }
}
单链表
package dataStructure;

import java.util.Stack;

/**
 * 单链表
 *
 * @author zqh
 **/
public class LinkedListDemo {
    public static void main(String[] args) {
        HeroNode h1 = new HeroNode(1, "小米");
        HeroNode h2 = new HeroNode(2, "小明");
        HeroNode h3 = new HeroNode(3, "小红");
        SingleLinkedList list = new SingleLinkedList();
        list.add(h1);
        list.add(h2);
        list.add(h3);
        list.list();

/*        System.out.println("递归反转链表:");
        HeroNode node1 = list.reverse(list.getHead());
        while (node1 != null && node1.next != null) {
            System.out.println(node1);
            node1 = node1.next;
        }*/

        System.out.println("链表反转后:");
        list.revHeroNode();
        list.list();

        System.out.println("反转打印(结构未反转):");
        list.revHeroNode2();
        //修改
        HeroNode newH2 = new HeroNode(2, "小明~~");
        list.update(newH2);
        System.out.println("修改后");
        list.list();

        System.out.println("链表长度为:" + list.getLength());

        HeroNode node = list.findHeroNode(1);
        System.out.println("链表中倒数第k个节点:" + node);
    }
}

class SingleLinkedList {
    //初始化一个头节点,不存放实际数据
    private final HeroNode head = new HeroNode(0, "");

    public HeroNode getHead() {
        return head;
    }

    public void add(HeroNode heroNode) {
        HeroNode temp = head;
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = heroNode;
    }

    public void update(HeroNode newHeroNode) {
        HeroNode temp = head.next;
        while (temp != null) {
            if (temp.id == newHeroNode.id) {
                temp.name = newHeroNode.name;
                break;
            }
            temp = temp.next;
        }
    }

    public void list() {
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        HeroNode temp = head.next;
        while (temp != null) {
            System.out.println(temp);
            temp = temp.next;
        }
    }

    //返回链表有效长度 不包括头节点
    public int getLength() {
        if (head.next == null) {
            System.out.println("链表为空");
            return 0;
        }
        int length = 0;
        HeroNode temp = head.next;
        while (temp != null) {
            length++;
            temp = temp.next;
        }
        return length;
    }

    //获取链表中倒数第k个节点
    public HeroNode findHeroNode(int k) {
        if (head.next == null) {
            System.out.println("链表为空");
            return null;
        }
        int length = getLength();
        if (k < 0 || length < k) {
            return null;
        }
        HeroNode temp = head.next;
        for (int i = 0; i < length - k; i++) {
            temp = temp.next;
        }
        return temp;
    }

    //遍历反转链表结构
    public void revHeroNode() {
        //如果链表为空或只有一个元素时 则不需要反转
        if (head.next == null || head.next.next == null) {
            return;
        }
        //创建一个新的链表 遍历要反转的链表 使用头插法插入到行链表中
        HeroNode reverseHead = new HeroNode(0, ""), cur = head.next, next = null;
        while (cur != null) {
            //先保存当前节点的下一个节点
            next = cur.next;
            cur.next = reverseHead.next;
            reverseHead.next = cur;
            cur = next;
        }
        head.next = reverseHead.next;
    }

    //链表反转打印 结构未反转
    public void revHeroNode2() {
        //如果链表为空或只有一个元素时 则不需要反转
        if (head.next == null) {
            return;
        }
        HeroNode cur = head.next;
        //使用 栈的特性 先进后出
        Stack<HeroNode> stack = new Stack<>();
        while (cur != null) {
            stack.push(cur);
            cur = cur.next;
        }
        while (!stack.isEmpty()) {
            System.out.println(stack.pop());
        }
    }

    //使用递归反转链表 (返回链表头)
    public HeroNode reverse(HeroNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        HeroNode temp = head.next;
        HeroNode newHead = reverse(head.next);
        temp.next = head;
        head.next = null;
        return newHead;
    }

    //合并两个链表 合并后保持有序
    public HeroNode joinHeroNode(HeroNode n1, HeroNode n2) {
        //如果其中一个链表为空,则不必排序直接返回另一个链表
        if (n1 == null) {
            return n2;
        } else if (n2 == null) {
            return n1;
        }
        //节点排序
        HeroNode res = n1.id < n2.id ? n1 : n2;
        //使用递归确定链表的下一个节点
        res.next = joinHeroNode(res.next, res.next.next);
        return res;
    }
}

//链表的定义
class HeroNode {
    public int id;
    public String name;
    public HeroNode next;

    public HeroNode(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
双向链表
package dataStructure;

/**
 * 双向链表
 *
 * @author zqh
 **/
public class TwoLinkedListDemo {
    public static void main(String[] args) {
        HeroNode2 h1 = new HeroNode2(1, "小米");
        HeroNode2 h2 = new HeroNode2(2, "小明");
        HeroNode2 h3 = new HeroNode2(3, "小红");
        SingleTwoLinkedList list = new SingleTwoLinkedList();
        list.add(h1);
        list.add(h2);
        list.add(h3);
        list.list();

        list.del(3);
        System.out.println("删除后:");
        list.list();
    }
}

class SingleTwoLinkedList {
    //头结点
    private final HeroNode2 head = new HeroNode2(0, "");

    public void add(HeroNode2 node) {
        HeroNode2 temp = head;
        //添加到最后
        while (temp.next != null) {
            temp = temp.next;
        }
        //最后一个节点 = 新的节点
        temp.next = node;
        //新节点的前一个节点 = temp 即可形成双向链表
        node.pre = temp;
    }

    public void update(HeroNode2 newHeroNode) {
        HeroNode2 temp = head.next;
        while (temp != null) {
            if (temp.id == newHeroNode.id) {
                temp.name = newHeroNode.name;
                break;
            }
            temp = temp.next;
        }
    }

    public void del(int nodeId) {
        HeroNode2 temp = head;
        while (temp != null) {
            //找到要删除的节点
            if (temp.id == nodeId) {
                //将要删除的上个节点的下一个节点指向 需删除的后一个节点
                temp.pre.next = temp.next;
                //如删除的是最后一个节点 .next则=null,会触发空指针
                if (temp.next != null) {
                    temp.next.pre = temp;
                }
                break;
            }
            temp = temp.next;
        }
    }

    public void list() {
        HeroNode2 temp = head.next;
        while (temp != null) {
            System.out.println(temp);
            temp = temp.next;
        }
    }
}

//双向链表的定义
class HeroNode2 {
    public int id;
    public String name;
    public HeroNode2 pre;
    public HeroNode2 next;

    public HeroNode2(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "HeroNode2{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
package dataStructure;

import java.util.Stack;

/**
 * 栈 特点 先进后出
 *
 * @author zqh
 **/
public class StackTest {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        //入栈
        stack.push(1);
        stack.push(2);
        stack.push(3);
        //出栈 倒序打印
        while (!stack.isEmpty()) {
            System.out.println(stack.pop());
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值