java实现单向链表与链栈

准备复习数据结构,从链表开始,想着csdn看看别人是咋写的,一搜一大堆,每个人写的都不一样,当然我可能写的也很奇葩,我就是根据我学C语言的时候写的

一、单向链表

1、定义链表节点

public class Node {
    public int data;//数据域
    public Node next;//指针域
    public Node(int data){
        this.data=data;
    }
}

表节点分为一个数据域和一个指针域。数据域的值我定义的是int型;指针域的值是next,是表节点类型(Node类型)

2、链表的创建及一些操作

在这里,每增加一个节点我使用的是尾插法

public class Linklist {
    Node head;
    //根据一个整数值创建一个链表
    public Node createlink(int a){
        head=new Node(a);
        head.next=null;
        return head;
    }
    //增加一个链表节点(尾插法)
    public void addNode(int a,Node head){
        // last最后一个尾元素,tmp存储待增加的元素
        Node last,tmp;
        //找到最后一个位置进行尾插
        for(last=head;last.next!=null;last=last.next);
        tmp=new Node(a);
        last.next=tmp;
    }
    //链表的长度
    public int linklength(Node node){
        Node tmp;
        int length=0;
        if(node ==null){
            return length;
        }else{
            for(tmp=node;tmp!=null;tmp=tmp.next){
                length++;
            }
            return length;
        }
    }
    //删除key位置上的节点
    public void deletelink(int key,Node node){
        //用来暂存链表的首元素,进行遍历使用
        Node tmp;
        //判断删除的节点位置是否合理
        if(key<=0&&key>=linklength(node)){
            System.out.println("你想删除的节点位置不存在!");
        }else{
            int count=1;
            for(tmp=node;count!=key-1;tmp=tmp.next);//找到要删除元素的前置节点
            tmp.next=tmp.next.next;
        }
    }
    //打印链表
    public  void printlink(Node node){
        Node tmp;
        for(tmp=node;tmp!=null;tmp=tmp.next){
            System.out.print(tmp.data+"\t");
        }
    }
    //测试
    public static void main(String[] args) {
        Linklist linklist =new Linklist();
        Node head= linklist.createlink(8);
        linklist.addNode(3,head);
        linklist.addNode(2,head);
        linklist.addNode(5,head);
        linklist.addNode(8,head);
        linklist.printlink(head);
        int linklength= linklist.linklength(head);
        System.out.println("\n链表的的长度是:"+linklength);
        linklist.deletelink(2,head);
        linklist.printlink(head);
    }
}
  • 单向链表的优点:易删除和增加节点
  • 链表的缺点:占空间大,既要存指针域又要存数值域;访问慢,必须从表头开始一个一个遍历
  • 使用环境:适用于增加和删除节点

二、链栈

1、定义栈节点

public class Node {
    public int data;//数据域
    public Node next;//指针域
    public Node(){
        this.data=-1;
    }
    public Node(int data){
        this.data=data;
        this.next=null;
    }
}

这里定义链栈节点和链表节点类似,都是一个数据域和一个指针域。

2、创建链栈及一些操作

public class LinkStack {
    Node base;//栈底指针
    Node top;//栈顶指针
    int size;//栈的大小
    //构造一个空的链栈
    public LinkStack(){
        this.base=null;
        this.top=null;
        this.size=0;
    }
    //创建一个空的链栈
    public void createStack(){
      base=top=null;
      size=0;
    }
    //向链栈中放入一个整数值
    public void push(int a){
        Node tmp=new Node(a);
        if(base==null){
            base=tmp;
            top=tmp;
        }else{
            top.next=tmp;
            top=tmp;
        }
        //链栈的大小就加一
        this.size++;
    }
    //弹出栈顶的值
    public void pop(){
        Node tmp;
        if(this.size<=0){
            System.out.println("栈空!");
        }else{
           for(tmp=base;tmp.next!=top;tmp=tmp.next);
           tmp.next=tmp.next.next;
           top=tmp;
           size--;
        }
    }
    //入栈方向打印链栈
    public void printStack(){
        Node tmp;
        System.out.println("链栈的入栈顺序为:"+"\n");
        for(tmp=base;tmp!=null;tmp=tmp.next){
            System.out.print(tmp.data+"\t");
        }
    }
    //出栈方向打印链栈
    public void printStack1(){
        Node tmp,flag;
        System.out.println("链栈的出栈顺序为:"+"\n");
        for(tmp=base,flag=top;tmp.next!=flag;tmp=tmp.next){
            System.out.println(flag.data);
            flag=tmp;
        }
    }
    //测试
    public static void main(String[] args) {
        LinkStack stack=new LinkStack();
        stack.createStack();
        System.out.println(stack.size);
        stack.push(2);
        stack.push(5);
        stack.push(3);
        stack.push(8);
        stack.push(9);
        stack.push(9);
        System.out.println(stack.size);
        stack.printStack();
        stack.pop();
        stack.pop();
        System.out.println(stack.size);
    }
}

链栈的优点:不存在因栈满而溢出的情况

链栈的缺点:栈空间大,只能从栈顶进行删除与插入元素(可以说这是大多数栈的特点,读者可以尝试通过两个双向栈实现链表)

三、单向链队列

1、定义队列节点

队列的节点和栈节点的定义相似,都是一个值域和数据域,只不过在创建的时候,链栈创建的是base栈底指针和top栈顶指针,base指针不动,入栈出栈栈顶指针来回指。而创建链队列的时候创建的是front队首指针和rear队尾指针,出队时队首指针变动,入队时队尾指针变动。

public class Node {
    int data;//存储数据域
    Node next;//存储指针域
    Node(int data){
        this.data=data;
        next=null;
    }
}

2、创建链栈及一些操作

public class Queue {
    Node front;//存储队首元素
    Node rear;//存储队尾元素
    Queue(){
        front=null;
        rear=null;
    }
    //创建一个空队列
    public void createQueue(){
        front=rear=null;
    }
    //增加元素,从队尾增加
    public void enQueue(int num){
        Node tmp=new Node(num);
        if(front==null){
            front=rear=tmp;
        }else{
            rear.next=tmp;//从队尾开始增加节点
            rear=tmp;
        }
    }
    //出队列,从队首出队
    public void deQueue(){
        if(this.getSize()<=0){
            System.out.println("此队列为空,不能进行出队");
        }else {
            front=front.next;//直接让原来的队首元素指向下一个元素即可
        }
    }
    //打印队列
    public void printQueue(){
        Node tmp;
        if(this.getSize()<=0){
            System.out.println("此队列为空!");
        }else{
            System.out.println("\ns队列遍历如下:");
            //从队首向队尾开始遍历
            for(tmp=front;tmp!=null;tmp=tmp.next){
                System.out.print(tmp.data+"\t");
            }
        }
    }
    //获取队列的长度大小
    public int getSize(){
        Node tmp;
        int count=1;
        if(front==null){
            return count-1;
        }else{
            for(tmp=front;tmp!=rear;tmp=tmp.next){
                count++;
            }
            return count;
        }
    }
    //测试
    public static void main(String[] args) {
        Queue queue=new Queue();
        queue.createQueue();
        queue.enQueue(9);
        queue.enQueue(4);
        queue.enQueue(2);
        queue.enQueue(5);
        queue.enQueue(1);
        queue.enQueue(8);
        System.out.println("\n队列的长度为:"+queue.getSize());
        queue.printQueue();
        queue.deQueue();
        queue.printQueue();
        System.out.println("\n队列的长度为:"+queue.getSize());
    }
}

链队列的优点:相对于链栈可对表进行双向操作

链队列的缺点:也只能从表两头进行操作

使用环境:可以考虑排队的问题

 

posted @ 2022-11-08 00:15  _SpringCloud  阅读(13)  评论(0编辑  收藏  举报  来源