java中的双向链表,数据结构双向链表的实现

  java中的双向链表,数据结构双向链表的实现

  

双向链表(Doubly linked list)

什么是双向链表?

 

  双向链表,也叫双链表,是链表的一种。它的每个数据节点都有两个指针,分别指向直接后继和直接前任。因此,从双向链表中的任何节点开始,都可以很容易地访问它的前一个和后一个节点。

  双向链表与单向链表的主要区别:

  搜索方向:单向链表的搜索方向只能是一个方向,双向链表可以向前或向后搜索。删除:单向链表的删除需要辅助指针的帮助,先找到要删除的节点的前身,然后删除。temp . next=temp . next . next;(temp是二级指针)双链表可以自删除。

  双向链表与单向链表的优劣:

  优点:双链表结构优于单链表结构。

  缺点:从存储结构上看,双向链表比单向链表多一个指针,需要额外的线性内存使用。(指针在32位操作系统中是4字节,在64位操作系统中是8字节)。

  双向链表的逻辑结构图解:

  00-1010添加:插图:

  代码:

  //添加一个节点到最后一个公共void Add(double node new node){ double node temp=head;while(true){ if(temp.next==null){//当temp . next为空时,证明temp是最后一个元素。temp.next=newNode//temp节点的下一位指向新节点newNode.pre=temp//新节点的前一位指向temp //这两步形成一个双链表断点;} else if(temp . next . id==new node . id){//同一个id证明该学生已经存在。System.out.printf(要插入的学号为%d的学生已经存在。n ,新节点。ID);打破;} temp=temp.next} }//添加节点public void sortaddd(双节点新节点){ double node temp=headwhile(true){ if(temp . next==null){//表示要添加的节点序号是当前链表中最大的,所以直接加在末尾。temp.next=newNode//temp节点的下一位指向新节点newNode.pre=temp//新节点的前一位指向temp //这两步形成一个双链表断点;} else If(temp . next . idnew node . id){//如果当前节点的下一个节点的个数大于要添加的新节点,则证明新节点应该添加在temp newNode.next=temp.next之后;//要添加的节点的下一位指向当前节点的下一位temp . next . pre=new node;//temp当前节点的下一位的前一位指向新节点,形成一个双向链表temp.next=newNode//让当前节点的下一位指向新节点newNode.pre=temp//新节点的前一位指向当前节点temp //这样连接完成后,新节点会插入到原链表break中的temp节点和temp.next节点之间;} else if(temp . next . id==new node . id){//同一个id证明该学生已经存在。System.out.printf(要插入的学号为%d的学生已经存在。n ,新节点。ID);打破;} temp=temp.next}

     }删除 :图解:

  

 

  代码:

  

 //删除一个节点。    //自我删除    public void DoubleDelete(int id) {        if (head.next == null) {            System.out.println("链表为空!");            return;        }        DoubleNode temp = head.next;        while (true) {            if (temp == null) {                System.out.printf("要删除的%d节点不存在n", id);                break;            } else if (temp.ID == id) {                //找到要删除节点                // 此时temp 就代表将要被删除节点                //temp.pre.next 指 当前要被删除节点 的前一位 的后一位                // temp.next  指 当前要被删除节点的后一位                temp.pre.next = temp.next;                // (当前要被删除节点 的前一位 的后一位)指向 (当前要被删除节点的后一位)                //这样就完成了 temp节点的删除操作                 // 如果是最后一个节点,就不需要执行下面这句话,否则出现空指针                if (temp.next != null) {                    temp.next.pre = temp.pre;                }                break;            }            temp = temp.next;        }    }

修改:侃侃:它实际上与单链表的删除是一样。

 

  代码:

  

//修改链表节点    public void DoubleUpdate(DoubleNode newNode) {        if (head.next == null) {            System.out.println("链表为空!");            return;        }        DoubleNode temp = head.next;        while (true) {            if (temp == null) {                break;            } else if (temp.ID == newNode.ID) {                //找到要修改的节点                temp.name = newNode.name;                temp.mark = newNode.mark;                return;            }            temp = temp.next;        }        System.out.printf("要修改的%d节点不存在n", newNode.ID);    }

双向链表实例:

用双向链表创建一个学生信息管理系统,完成对学生信息的添加,删除,修改操作。

 

  

package Linkedlist; //双向链表。public class DoubleLinkedListDemo {    public static void main(String agrs[]) {        DoubleNode stu1 = new DoubleNode(6, "张三", 99);        DoubleNode stu2 = new DoubleNode(2, "李四", 99);        DoubleNode stu3 = new DoubleNode(3, "王五", 99);        DoubleNode stu4 = new DoubleNode(5, "王二", 99);        DoubleNode stu5 = new DoubleNode(4, "小红", 99);        DoubleNode stu6 = new DoubleNode(1, "小明", 99);        DoubleNode stu7 = new DoubleNode(1, "小明", 99);         DoubleLinkedlist doubleLinkedlist = new DoubleLinkedlist();        /* doubleLinkedlist.add(stu1);        doubleLinkedlist.add(stu2);        doubleLinkedlist.add(stu3);        doubleLinkedlist.add(stu4);        doubleLinkedlist.add(stu5);        doubleLinkedlist.add(stu6);        doubleLinkedlist.add(stu7);*/         doubleLinkedlist.Sortadd(stu1);        doubleLinkedlist.Sortadd(stu2);        doubleLinkedlist.Sortadd(stu3);        doubleLinkedlist.Sortadd(stu4);        doubleLinkedlist.Sortadd(stu5);        doubleLinkedlist.Sortadd(stu6);        doubleLinkedlist.add(stu7);         System.out.println("原链表展示!");        doubleLinkedlist.ShowList();        System.out.println();         doubleLinkedlist.DoubleDelete(6);        doubleLinkedlist.DoubleDelete(15);        System.out.println("删除后链表展示!");        doubleLinkedlist.ShowList();        System.out.println();          DoubleNode stu8 = new DoubleNode(1, "李思成", 100);        DoubleNode stu9 = new DoubleNode(20, "李成", 100);        doubleLinkedlist.DoubleUpdate(stu8);        doubleLinkedlist.DoubleUpdate(stu9);        System.out.println("修改后链表展示!");        doubleLinkedlist.ShowList();        System.out.println();    }} class DoubleLinkedlist {    private DoubleNode head = new DoubleNode(0, "", 0);     public DoubleNode getHead() {        return head;    }     //添加一个节点到最后    public void add(DoubleNode newNode) {        DoubleNode temp = head;        while (true) {            if (temp.next == null) {                // 当temp.next 为空时,证明temp为最后一个元素。                temp.next = newNode; //temp节点的下一位指向新节点                newNode.pre = temp;//新节点的前一位指向temp                //这两步构成双向链表                break;            }else if (temp.next.ID == newNode.ID) {                //ID相同证明 已经存在该学生。                System.out.printf("要插入学号为%d的学生已经存在。n", newNode.ID);                break;            }            temp = temp.next;        }    }     //按学号顺序添加节点    public void Sortadd(DoubleNode newNode) {        DoubleNode temp = head;        while (true) {            if (temp.next == null) {                //说明要添加的节点序号在当前链表中最大,因此直接添加在末尾。                temp.next = newNode;//temp节点的下一位指向新节点                newNode.pre = temp;//新节点的前一位指向temp                //这两步构成双向链表                break;            } else if (temp.next.ID > newNode.ID) {                //当前节点的下一位节点的编号大于 要添加的新节点,则证明新节点要添加在temp节点之后                newNode.next = temp.next;//要添加节点的下一位 指向temp当前节点的下一位                temp.next.pre = newNode;//temp当前节点的下一位的前一位 指向 新节点构成双向链表                temp.next = newNode; // 再让当前节点的下一位指向 新节点                newNode.pre = temp;//新节点的前一位 指向 当前节点temp                //这样连接完成后就将  新节点插入 到 原本链表的temp节点与temp.next节点之间                break;            }else if (temp.next.ID == newNode.ID) {                //ID相同证明 已经存在该学生。                System.out.printf("要插入学号为%d的学生已经存在。n", newNode.ID);                break;            }            temp = temp.next;        }    }     //删除一个节点。    //自我删除    public void DoubleDelete(int id) {        if (head.next == null) {            System.out.println("链表为空!");            return;        }        DoubleNode temp = head.next;        while (true) {            if (temp == null) {                System.out.printf("要删除的%d节点不存在n", id);                break;            } else if (temp.ID == id) {                //找到要删除节点                // 此时temp 就代表将要被删除节点                //temp.pre.next 指 当前要被删除节点 的前一位 的后一位                // temp.next  指 当前要被删除节点的后一位                temp.pre.next = temp.next;                // (当前要被删除节点 的前一位 的后一位)指向 (当前要被删除节点的后一位)                //这样就完成了 temp节点的删除操作                 // 如果是最后一个节点,就不需要执行下面这句话,否则出现空指针                if (temp.next != null) {                    temp.next.pre = temp.pre;                }                break;            }            temp = temp.next;        }    }     //修改链表节点    public void DoubleUpdate(DoubleNode newNode) {        if (head.next == null) {            System.out.println("链表为空!");            return;        }        DoubleNode temp = head.next;        while (true) {            if (temp == null) {                break;            } else if (temp.ID == newNode.ID) {                //找到要修改的节点                temp.name = newNode.name;                temp.mark = newNode.mark;                return;            }            temp = temp.next;        }        System.out.printf("要修改的%d节点不存在n", newNode.ID);    }     public void ShowList() {        // 判断链表是否为空        if (head.next == null) {            System.out.println("链表为空");            return;        }        // 因为头节点,不能动,因此我们需要一个辅助变量来遍历        DoubleNode temp = head.next;        while (true) {            // 判断是否到链表最后            if (temp == null) {                break;            }            System.out.println(temp);// 输出节点的信息            temp = temp.next;        }    }} class DoubleNode {    public int ID; // 编号。    public String name;    public int mark;    public DoubleNode next;    public DoubleNode pre;      

	  
	  
	  
	  
	  
	  
        

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • mysql复合索引和组合索引,mysql组合索引数据结构
  • mysql复合索引和组合索引,mysql组合索引数据结构,Mysql之组合索引方法详解
  • mysql复合索引和组合索引,mysql复合索引数据结构
  • mysql复合索引和组合索引,mysql复合索引数据结构,MySQL的复合索引总结
  • b+树 多路搜索树,数据结构中树的分类
  • b+树 多路搜索树,数据结构中树的分类,数据结构-树(三):多路搜索树B树、B+树
  • avl树的构造,avl树特性,数据结构之AVL树详解
  • 数据结构c语言哈夫曼树,c语言哈夫曼树的构造,使用C语言详解霍夫曼树数据结构
  • c语言数据结构算法编程库,数据结构 c语言中文网
  • c语言数据结构算法编程库,数据结构 c语言中文网,C语言编程数据结构基础详解小白篇
  • c++纸牌游戏,数据结构纸牌游戏c语言
  • c++纸牌游戏,数据结构纸牌游戏c语言,C语言实战之纸牌游戏
  • ,,c#解析jobject的数据结构
  • ,,javascript数据结构之多叉树经典操作示例【创建、添加、遍历、移除等】
  • ,,Java 数据结构与算法系列精讲之背包问题
  • 留言与评论(共有 条评论)
       
    验证码: