链表以及双向链表的增删改查

链表是一种重要的数据结构,包含单向链表和双向链表:

1. 单向链表
单链表(单向链表):由两部分组成 数据域(Data)和结点域(Node),单链表就像是一条打了很多结的绳子,每一个绳结相当于一个结点,每个节结点间都有绳子连接,这样原理的实现是通过Node结点区的头指针head实现的,每个结点都有一个指针,每个节点指针的指向都是指向自身结点的下一个结点,最后一个结点的head指向为null,这样一来就连成了上述所说绳子一样的链,对单链表的操作只能从一端开始,如果需要查找链表中的某一个结点,则需要从头开始进行遍历。

在这里插入图片描述

Linklist类:
package linklist;

public class Linklist {
	  // 用来存取该节点的数据,public修饰符不用get set方法  
	public int data = 99999999;   //数值
	// 用来存储下个节点
	public Linklist next; //节点
	/**
	 * 添加
	 * @param data 要添加的值
	 */
	public void add(int data) {
		//如果next为空,就给它赋值
		if(next ==null) { 
			next = new Linklist();
			next.data  = data;
		}else {
			//如果不为空,就让next去添加
			next.add(data);
		}
	}
	/**
	 * 删除
	 * @param data 要删除的数据
	 */
	public void delete(int data) {
		// 如果下一个为空,那么程序退出
		if(next == null) {
			return;
		}
		Linklist temp;
		temp = next;
		if(temp.data == data) {
			next = temp.next;
			temp.next = null;
		}else {
			next.delete(data);
		}
	}
	/**
	 * 查找
	 * @param data  要查找的数据
	 * @return
	 */
	public Linklist find(int data) {
		if(next == null) {
			return null;
		}
		if(next.data == data) {
			return next;
		}else {
			return next.find(data);
		}
		
	}     
	/**
	 * 更新
	 * @param data 更新数据
	 * @param newdata
	 */
	public void update(int data,int newData) {
		Linklist find = find(data);
		find.data = newData;
	}
	@Override
	public String toString() {
		return "Linklist [data=" + data + ", next=" + next + "]";
	}

}

LinklistTest类:
package linklist;

public class LinklistTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Linklist a = new Linklist();
        a.add(5);
        a.add(6);
        a.add(59);
        a.add(-5);
        a.add(9999999);
        a.add(58);
        a.add(-655);
              
        System.out.println(a);
        a.delete(58);
        Linklist b = a.find(59);
        System.out.println(b);
        Linklist c = a.find(-5);
        System.out.println(c);
        a.update(9999999, 99);
        System.out.println(a);
	}

}

运行结果:
在这里插入图片描述
2. 双向链表
双链表(双向链表):双链表和单链表相比,多了一个指向尾指针(tail),双链表的每个结点都有一个头指针head和尾指针tail,双链表相比单链表更容易操作,双链表结点的首结点的head指向为null,tail指向下一个节点的tail;尾结点的head指向前一个结点的head,tail 指向为null,是双向的关系;

在这里插入图片描述

DoublyLinkList类:
package com.wwy.linklist;

import java.io.IOException;

public class DoublyLinkList{
     //头
    private Link frist;
      //尾
    private Link last;
    //初始化首尾指针
    public DoublyLinkList(){
        frist = null;
        last = null;
    }

    public boolean isEmpty(){
        return frist == null;
    }

    public void addFrist(int value){
        Link newLink= new Link(value);
        // 如果链表为空
        if(isEmpty()){ 
            last = newLink; //last -> newLink
        }else {
            frist.pre = newLink; // frist.pre -> newLink
        }
        newLink.next = frist; // newLink -> frist
        frist = newLink; // frist -> newLink
    }

    public void addLast(int value){
        Link newLink= new Link(value);
         // 如果链表为空
        if(isEmpty()){
            frist = newLink; // 表头指针直接指向新节点
        }else {
            last.next = newLink; //last指向的节点指向新节点
            newLink.pre = last; //新节点的前驱指向last指针
        }
        last = newLink; // last指向新节点
    }

    public boolean addBefore(int key,int value){

        Link cur = frist;
        if(frist.next.val == key){
            addFrist(value);
            return true;
        }else {
            while (cur.next.val != key) {
                cur = cur.next;
                if(cur == null){
                    return false;
                }
            }
            Link newLink= new Link(value);
            newLink.next = cur.next;
            cur.next.pre = newLink;
            newLink.pre = cur;
            cur.next = newLink;
            return true;
        }
    }

    public void addAfter(int key,int value)throws RuntimeException{
        Link cur = frist;
        while(cur.val!=key){ //经过循环,cur指针指向指定节点
            cur = cur.next;
            if(cur == null){ // 找不到该节点
                throw new RuntimeException("Node is not exists");
            }
        }
        Link newLink = new Link(value);
        if (cur == last){ // 如果当前结点是尾节点
            newLink.next = null; // 新节点指向null
            last =newLink; // last指针指向新节点
        }else {
            newLink.next = cur.next; //新节点next指针,指向当前结点的next
            cur.next.pre = newLink; //当前结点的前驱指向新节点
        }
        newLink.pre = cur;//当前结点的前驱指向当前结点
        cur.next = newLink; //当前结点的后继指向新节点
    }

    public void deleteFrist(){
        if(frist.next == null){
            last = null;
        }else {
            frist.next.pre = null;
        }
        frist = frist.next;
    }

    public void deleteLast(int key){
        if(frist.next == null){
            frist = null;
        }else {
            last.pre.next = null;
        }
            last = last.pre;
    }

    public void deleteKey(int key)throws RuntimeException{
        Link cur = frist;
        while(cur.val!= key){
            cur = cur.next;
            if(cur == null){ //不存在该节点
                throw new RuntimeException("Node is not exists");
            }
        }
        if(cur == frist){ // 如果frist指向的节点
            frist = cur.next; //frist指针后移
        }else {
            cur.pre.next = cur.next;//前面节点的后继指向当前节点的后一个节点
        }
        if(cur == last){ // 如果当前节点是尾节点
            last = cur.pre; // 尾节点的前驱前移
        }else {
            cur.next.pre = cur.pre; //后面节点的前驱指向当前节点的前一个节点
        }
    }

    public int queryPre(int value)throws IOException,RuntimeException{
        Link cur = frist;
        if(frist.val == value){
            throw new RuntimeException("Not find "+value+"pre");
        }
        while(cur.next.val!=value){
            cur = cur.next;
            if(cur.next == null){
                throw new RuntimeException(value +"pre is not exeist!");
            }
        }

        return cur.val;
    }

    public void displayForward(){
        Link cur = frist;
        while(cur!=null){
            cur.displayCurrentNode();
            cur = cur.next;
        }
        System.out.println();

    }
    public void displayBackward(){
        Link cur = last;
        while(cur!=null){
            cur.displayCurrentNode();
            cur = cur.pre;
        }
        System.out.println();
    }
}


Test类:
package com.wwy.linklist;

import java.io.IOException;

public class Test {

	public static void main(String[] args) throws IOException, RuntimeException {
		// TODO Auto-generated method stub
	//	 public void test()throws Exception{ // 自己测试代码
		        DoublyLinkList d = new DoublyLinkList();
		        d.addFrist(1);
//		        d.addFirst(1);
		        d.addFrist(2);
		        d.addFrist(3);
		        d.addLast(6);
		        d.addFrist(4);
		        d.addFrist(5);
		        d.addLast(7);
		        d.displayForward();
		      
		 //       System.out.println(d.queryPre(4));
		  //      System.out.println(d.queryPre(2));
		        System.out.println(d.queryPre(3));
		        System.out.println(d.queryPre(7));
		        System.out.println(d.queryPre(6));
		      
		   d.addBefore(6, 9);
		   d.displayBackward();
		
		   d.deleteKey(3);
		   d.displayBackward();
		  
		      
		    }
		}

		class Link {
		    public int val;
		    public Link next;
		    public Link pre;

		    public Link(int val) {
		        this.val = val;
		    }

		    public void displayCurrentNode() {
		        System.out.print(val + "  ");
		    }
}

运行结果:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值