数据结构――线性表

匿名 (未验证) 提交于 2019-12-02 23:53:01

线性表是具有相同类型的n个元素(n>=0)的有限序列

  • 线性表采用顺序存储方式
  • 其逻辑顺序和物理顺序相同

问题:需要连续存储空间,插入等操作需要移动大量元素,时间复杂度高。

线性表采用链式存储方式称为单链表。

链式存储是采用节点来进行存储的。

每个节点包括data域和next域。(不一定连续存储)

  • 单链表反转
  • 单链表的增删改查
  • 约瑟夫环


import java.util.Stack;  //定义单个节点 class Node {      public String data;  //定义数据节点      public Node next;   //定义指向下一个节点的指针      public Node() {     }      public Node(String data) {         this.data = data;     }      public String getData() {         return data;     }      public void setData(String data) {         this.data = data;     }      public Node getNext() {         return next;     }      public void setNext(Node next) {         this.next = next;     }      @Override     public String toString() {         return "Note{" +                 "data='" + data + '\'' +                 '}';     } }   public class Operation {     //初始化头结点     private static Node head = new Node();       private static Node reverseHead = new Node();       //插入节点(头插)     public void insertToHead(Node node)     {         Node temp = head;          //头插法需要设置head.next和node.next的值。其中nodeNext指向headNext,而headNext指向node。         //由于是赋值的关系,二者顺序不可颠倒         node.next=temp.next;         temp.next=node;     }      //插入节点(尾插)     public void insertToLast(Node node)     {         Node temp = head;          while (true)         {             if(temp.next==null)             {break;}             temp=temp.next;         }         temp.next=node;     }      //插入节点(指定位置k之后)      public void insertToK(Node node,int k)     {         Node temp = head;         for(int i=0;i<k;i++)         {             temp=temp.next;         }         node.next=temp.next;         temp.next=node;     }       //删除第m个节点     public void deleteM(int m)     {         Node temp = head;         for(int i=0;i<m-1;i++)         {             temp=temp.next;         }         temp.next=temp.next.next;     }       //修改第n个节点(n)     public void updateN(int n)     {         Node temp = head;         for(int i=0;i<n;i++)         {             temp=temp.next;         }         temp.data="up";     }       //递归反转      public Node reverseLinkedList(Node node) {         if (node == null || node.next == null) {             return node;         } else {             Node headNode = reverseLinkedList(node.next);             node.next.next = node;             node.next = null;             return headNode;         }     }      //遍历反转     public Node reserveByFor(Node head)     {         Node cur = head.next;         Node next = null;         Node Rhead = new Node();           while(true)         {             if(cur==null)             {                 break;             }             else             {                 next=cur.next;                 cur.next=Rhead.next;                 Rhead.next=cur;                  cur=next;             }         }          head.next=Rhead.next;          return head;     }      //print(last to first)     public void printLtoF(Node head)     {         Stack<Node>stack = new Stack<>();         Node cur = head.next;         while (cur!=null)         {             stack.push(cur);             cur=cur.next;         }         while (stack.size()>0)         {             System.out.println(stack.pop());         }     }         public static void main(String[] args)     {         Operation operation = new Operation();          operation.insertToHead(new Node("A"));         operation.insertToHead(new Node("B"));         operation.insertToHead(new Node("C"));          operation.insertToLast(new Node("1"));         operation.insertToLast(new Node("2"));         operation.insertToLast(new Node("3"));  //        operation.insertToK(new Node("k"),2);  //        operation.deleteM(3);  //        operation.updateN(1);           Node temp =head;         //遍历链表         while(true)         {             if(temp.next==null)             {break;}             else             {                 temp=temp.next;                 System.out.println(temp.toString());              }         }            System.out.println("//1.求单链表中有效节点个数.");          temp=head;         int count=0;         while(true)         {             if(temp.next==null)             {break;}             else             {                 temp=temp.next;                 count++;             }         }         System.out.println(count);           System.out.println("//2.查找单链表中倒数第K=3个节点");          temp=head;          //获取链表总长         int length=0;          while (true)         {             if(temp.next==null)             {break;}             else             {                 temp=temp.next;                 length++;             }         }           temp=head;         for(int i=0;i<length-2;i++)         {             temp=temp.next;         }         System.out.println(temp.data);           System.out.println("3.实现单链表的反转");  //      temp=operation.reverseLinkedList(head);           temp = operation.reserveByFor(head);          //遍历链表         while(true)         {             if(temp.next==null)             {break;}             else             {                 temp=temp.next;                 System.out.println(temp.toString());             }         }           System.out.println("4.从尾到头打印单链表");          temp = head;         operation.printLtoF(temp);           } }

//定义单个节点 class Node {      public String data;  //定义数据节点      public Node next;   //定义指向下一个节点的指针       public Node() {     }      public Node(String data) {         this.data = data;     }       @Override     public String toString() {         return "Note{" +                 "data='" + data + '\'' +                 '}';     }   }   public class Operation {     //初始化头结点     private static Node head = new Node();      //尾插法     public void add(Node node)     {         Node temp = head;          while (true)         {             if(temp.next==null)             {break;}             temp=temp.next;         }         temp.next=node;     }      //创建单向环形链表     public Node createCircle(int n)     {         //创建单链表         for(int i=0;i<n;i++)         {             add(new Node("No:"+(i+1)));         }          //遍历链表         Node temp = head;         while(temp.next!=null)         {             temp=temp.next;             System.out.println(temp);         }          Node last = temp;         temp=head;         last.next=head.next;   //连接首尾          System.out.println("last为最后一个数5:");         System.out.println(last);           System.out.println("循环两遍单向环形链表:");         int count=2*n;         while(last!=null)         {             if(count==0)             {                 break;             }             System.out.println(last.next);             last=last.next;             count--;         }         System.out.println("last="+last.data);         return last;     }      public static void JosephusProblem(int n, int k, int m, Node last)     {         //定位到第k个节点,输出k+1个节点并删除,并让last定位到第k个节点          Node temp = last;         for(int i=0;i<k;i++)  //定位到第k个节点         {             temp=temp.next;         }         System.out.println("第一次输出"+temp.next.data);//输出          temp.next=temp.next.next; //删除第K+1个节点         last=temp.next;            for(int i=0;i<n-1;i++)         {             temp=last;              System.out.println("第二次输出"+temp.next.data);              temp.next=temp.next.next;             last=temp.next;         }       }     public static void main(String[] args)     {         Operation operation = new Operation();          //定义人数         int n=5;         Node last = operation.createCircle(n);           //定义从第几个节点开始数         int k=1;         //定义数的次数         int m=2;           System.out.println("输出约瑟夫环:");         JosephusProblem(n,k,m,last);       } }

单向列表只能从前往后查找,而双向链表可以向前向后查找。
单向链表删除节点需要依靠辅助节点,而双向链表可以实现自我删除。

双向链表与单项列表的实际区别在于多了一个pre域。

import java.util.Stack;  //定义单个节点 class Node {      public String data;  //定义数据节点      public Node next;   //定义指向下一个节点的指针      public Node pre;    //定义指向上一个节点的指针      public Node() {     }      public Node(String data) {         this.data = data;     }       @Override     public String toString() {         return "Note{" +                 "data='" + data + '\'' +                 '}';     } }   public class Operation {     //初始化头结点     private static Node head = new Node();       //插入节点(尾插法)     public void addNode(Node node)     {         Node temp = head;         while(true)         {             if(temp.next==null)             {                 break;             }             temp=temp.next;         }         temp.next=node;         node.pre=temp;     }      //插入节点(头插法)     public void addNodeToHead(Node node)     {         Node temp = head;           node.pre=temp;         node.next=temp.next;         temp.next.pre=node;         temp.next=node;     }      //插入到第k个节点后     public void addToK(Node node,int k)     {         Node temp = head;         for(int i=0;i<k;i++)         {             temp=temp.next;         }         //先建立单链表联系         node.next=temp.next;         temp.next=node;         //建立pre指向         node.pre=temp;         node.next.pre=node;     }      //删除第n个结点     public void deleteNode(int n)     {         Node temp = head;         for(int i=0;i<n;i++)         {             temp=temp.next;         }         temp.next.pre=temp.pre;         temp.pre.next=temp.next;     }      public void list()     {         //遍历链表         Node temp = head;         while(temp.next!=null)         {             temp=temp.next;             System.out.println(temp.toString());         }         System.out.println("=============");     }       //修改第m个结点     public void update(int m)     {         Node temp = head;         for(int i=0;i<m;i++)         {             temp=temp.next;         }         temp.data="up";     }      public static void main(String[] args)     {         Operation operation = new Operation();          operation.addNode(new Node("A"));         operation.addNode(new Node("B"));         operation.addNode(new Node("C"));         operation.addNode(new Node("D"));         operation.addNodeToHead(new Node("head1"));         operation.addNodeToHead(new Node("head2"));         operation.addNodeToHead(new Node("head3"));          //遍历链表         operation.list();          System.out.println("删除第n个节点");         operation.deleteNode(3);          //遍历链表         operation.list();          System.out.println("修改第m个节点");          operation.update(3);          operation.list();          System.out.println("插入到第k个节点后");         operation.addToK(new Node("k" ),3);          operation.list();     } }

来源: https://www.cnblogs.com/noneplus/p/11330317.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!