算法——線性表之鏈式存儲結構


單鏈表:

概念:

1、由於線性表的順序存儲在插入與刪除時需要移動大量元素,適用於不經常改變元素的情況,那么當我們需要經常操作元素時該怎么辦,這就有了接下來的線性表的鏈式存儲結構

2、單鏈表在內存的存儲位置不一定是一段連續的位置,它可以存放在內存中任何地方

3、單鏈表中除了用於存放數據的數據域外,還有存放指針的指針域,指針域的作用是指向鏈表的下一個節點(因為鏈表的元素在內存中的存放時任意位置的,所以需要指向下一個節點)

4、單鏈表第一個節點存儲的位置叫做頭指針,整個單鏈表的存取都是從頭指針開始,單鏈表的最后一個節點是指針指向空(NULL)

 

單鏈表的操作:

  1 package com.alibaba.test03;
  2 
  3 import org.junit.jupiter.api.Test;
  4 
  5 
  6 /**
  7  * 1.  單鏈表的具體實現及操作
  8  * @author wydream
  9  *
 10  */
 11 
 12 public class SingLeLinkedList {
 13 
 14     private int size;//鏈表節點的個數
 15     private Node head;//頭結點
 16     
 17     public SingLeLinkedList() {
 18         size=0;
 19         head=null;
 20     }
 21     
 22     //鏈表中的每個節點類
 23     private class Node{
 24         private Object data;//每個節點的數據
 25         private Node next;//每個節點指向下一個節點的連接
 26         
 27         public Node(Object data){
 28             this.data=data;
 29         }
 30     }
 31     
 32     //在表頭添加元素
 33     public Object addHead(Object obj) {
 34         Node newHead=new Node(obj);
 35         
 36         if(size==0) {
 37             head=newHead;
 38         }else {
 39             newHead.next=head;
 40             head=newHead;
 41         }
 42         size++;
 43         return obj;
 44     }
 45     
 46     //在鏈表頭刪除元素
 47     public Object deleteHead() {
 48         Object obj=head.data;
 49         head=head.next;
 50         size--;
 51         return obj;
 52     }
 53     
 54     //查找指定元素,找到了返回元素Node,找不到返回Null
 55     public Node find(Object obj) {
 56         Node current=head;
 57         int tempSize=size;
 58         while(tempSize>0) {
 59             if(obj.equals(current.data)) {
 60                 return current;
 61             }else {
 62                 current=current.next;
 63             }
 64             tempSize--;
 65         }
 66         return null;
 67     }
 68     
 69     
 70     //刪除指定的元素,刪除成功則返回true
 71     public boolean delete(Object value) {
 72         
 73         if(size==0) {
 74             return false;
 75         }
 76         
 77         Node current=head;
 78         Node previous=head;
 79         while(current.data!=value) {
 80             if(current.next==null) {
 81                 return false;
 82             }else {
 83                 previous=current;
 84                 current=current.next;
 85             }
 86         }
 87         
 88         //如果刪除的是第一個節點
 89         if(current==head) {
 90             head=current.next;
 91             size--;
 92         }else {//刪除的不是第一個節點
 93             previous.next=current.next;
 94             size--;
 95         }
 96         return true;
 97     }
 98     
 99     //判斷鏈表是否為空
100     public boolean isEmpty() {
101         return size==0;
102     }
103     
104     //顯示節點信息
105     public void display() {
106         if(size>0) {
107             Node node=head;
108             int tempSize=size;
109             if(tempSize==1) {//當前鏈表只有一個節點
110                 System.out.println("["+node.data+"]");
111                 return;
112             }
113             while(tempSize>0) {
114                 if(node.equals(head)) {
115                     System.out.print("["+node.data+"->");
116                 }else if(node.next==null){
117                     System.out.print(node.data+"]");
118                 }else {
119                     System.out.print(node.data+"->");
120                 }
121                 node=node.next;
122                 tempSize--;
123             }
124             System.out.println();
125         }else {//如果鏈表一個節點都沒有,直接打印
126             System.out.print("[]");
127         }
128     }
129     
130     @Test
131     public void test() {
132         SingLeLinkedList s=new SingLeLinkedList();
133         s.addHead("1");
134         s.addHead("2");
135         s.addHead("3");
136         s.addHead("4");
137         s.deleteHead();
138         s.display();
139     }
140     
141     
142     
143     
144 }

 

有序鏈表:

概念:

  • 前面的鏈表實現插入數據都是無序的,在有些應用中需要鏈表中的數據有序,這稱為有序鏈表。
  • 在有序鏈表中,數據是按照關鍵值有序排列的。一般在大多數需要使用有序數組的場合也可以使用有序鏈表。有序鏈表優於有序數組的地方是插入的速度(因為元素不需要移動),另外鏈表可以擴展到全部有效的使用內存,而數組只能局限於一個固定的大小中。

 

有序鏈表的實現:

 1 /**
 2  * 
 3  * @author wydream
 4  *
 5  */
 6 
 7 public class OrderLinkedList {
 8     
 9     private Node head;
10 
11     private class Node{
12         private int data;
13         private Node next;
14         
15         public Node(int data) {
16             this.data=data;
17         }
18     }
19     
20     public OrderLinkedList() {
21         head=null;
22     }
23     
24     //插入節點,並按從小到大的順序排列
25     public void insert(int value) {
26         Node node=new Node(value);
27         Node pre=null;
28         Node current=head;
29         while(current!=null&&value>current.data) {
30             pre=current;
31             current=current.next;
32         }
33         if(pre==null) {
34             head=node;
35             head.next=current;
36         }else {
37             pre.next=node;
38             node.next=current;
39         }
40     }
41     
42     //刪除頭節點
43     public void deleteHead() {
44         head=head.next;
45     }
46     
47     public void display() {
48         Node current=head;
49         while(current!=null) {
50             System.out.println(current.data+" ");
51             current=current.next;
52         }
53         System.out.println("");
54     }
55     
56     
57     
58 }

 

雙向鏈表: 

概念:

我們知道單向鏈表只能從一個方向遍歷,那么雙向鏈表它可以從兩個方向遍歷。

 

雙向鏈表的實現:

  1 import org.junit.jupiter.api.Test;
  2 
  3 /**
  4  *  雙向鏈表的實現
  5  * @author wydream
  6  *
  7  */
  8 
  9 public class TwoWayLinkedList {
 10     
 11     private Node head;//鏈表頭
 12     private Node tail;//鏈表尾
 13     private int size;//鏈表長度
 14     
 15 
 16     private class Node{
 17         private Object data;
 18         private Node next;
 19         private Node prev;
 20         
 21         public Node(Object obj){
 22             this.data=obj;
 23         }
 24         
 25     }
 26     
 27     public TwoWayLinkedList(){
 28         size=0;
 29         head=null;
 30         tail=null;
 31     }
 32     
 33     //在表頭添加新節點
 34     public void addHead(Object obj) {
 35         Node node=new Node(obj);
 36         //如果鏈表長度為零,則添加的這個元素就是頭節點和尾節點
 37         if(size==0) {
 38             head=node;
 39             tail=node;
 40         }else {
 41             head.prev=node;
 42             node.next=head;
 43             head=node;
 44         }
 45         
 46         size++;
 47     }
 48     
 49     //在鏈表尾添加新節點
 50     public void addEnd(Object obj) {
 51         Node newNode=new Node(obj);
 52         if(size==0) {
 53             head=newNode;
 54             tail=newNode;
 55         }else {
 56             tail.next=newNode;
 57             newNode.prev=tail;
 58             tail=newNode;
 59         }
 60         size++;
 61     }
 62     
 63     //刪除鏈表頭
 64     public Node deleteHead() {
 65         Node temp=head;
 66         if(size!=0) {
 67             head=head.next;
 68             head.prev=null;
 69             size--;
 70         }
 71         return temp;
 72     }
 73     
 74     
 75     //刪除鏈表尾
 76     public void deleteEnd() {
 77         Node end=tail;
 78         if(size!=0) {
 79             tail=tail.prev;
 80             tail.next=null;
 81             size--;
 82         }
 83     }
 84     
 85     
 86     //獲取鏈表節點個數
 87     public int getLength() {
 88         return size;
 89     }
 90     
 91     //判斷鏈表是否為空
 92     public boolean isEmpty() {
 93         if(size>0) {
 94             return true;
 95         }
 96         return false;
 97     }
 98     
 99     //顯示節點信息
100     public void display() {
101         if(size>0) {
102             Node node=head;
103             int tempSize=size;
104             if(tempSize==1) {
105                 System.out.println("["+node.data+"]");
106                 return;
107             }
108             while(tempSize>0) {
109                 if(node.equals(head)) {
110                     System.out.print("["+node.data+"->");
111                 }else if(node.equals(tail)) {
112                     System.out.print(node.data+"]");
113                 }else {
114                     System.out.print(node.data+"->");
115                 }
116                 node=node.next;
117                 tempSize--;
118             }
119             System.out.println();
120         }else {
121             System.out.println("[]");
122         }
123         
124     }
125     
126     @Test
127     public void test() {
128         TwoWayLinkedList tl=new TwoWayLinkedList();
129         tl.addEnd("1");
130         tl.addEnd("2");
131         tl.addEnd("3");
132         tl.addEnd("4");
133         tl.deleteHead();
134         tl.deleteEnd();
135         tl.display();
136     }
137     
138     
139 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM