自定义LinkedList实现

来源:互联网 发布:专业分流系统 源码 编辑:程序博客网 时间:2024/05/29 12:25

1,为什么要用到链表

数组作为存放同类数据的集合,给我们在程序设计时带来很多的方便,增加了灵活性。但数组也同样存在一些弊病。如数组的大小在定义时要事先规定,不能在程序中进行调整,这样一来,在程序设计中针对不同问题有时需要3 0个大小的数组,有时需要5 0个数组的大小,难于统一。我们只能够根据可能的最大需求来定义数组,常常会造成一定存储空间的浪费。

我们希望构造动态的数组,随时可以调整数组的大小,以满足不同问题的需要。链表就是我们需要的动态数组。它是在程序的执行过程中根据需要有数据存储就向系统要求申请存储空间,决不构成对存储区的浪费。

链表是一种复杂的数据结构,其数据之间的相互关系使链表分成三种:单链表、循环链表、双向链表,下面将逐一介绍。

2,单向链表

单链表有一个头节点head,指向链表在内存的首地址。链表中的每一个节点的数据类型为结构体类型,节点有两个成员:整型成员(实际需要保存的数据)和指向下一个结构体类型节点的指针即下一个节点的地址(事实上,此单链表是用于存放整型数据的动态数组)。链表按此结构对各节点的访问需从链表的头找起,后续节点的地址由当前节点给出。无论在表中访问那一个节点,都需要从链表的头开始,顺序向后查找。链表的尾节点由于无后续节点,其指针域为空,写作为NULL

如图所示


上图还给出这样一层含义,链表中的各节点在内存的存储地址不是连续的,其各节点的地址是在需要时向系统申请分配的,系统根据内存的当前情况,既可以连续分配地址,也可以跳跃式分配地址。

3,单向链表程序的实现

(1),链表节点的数据结构定义

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. struct node  
  2. {  
  3. int num;  
  4. struct node *p;  
  5. } ;  

在链表节点的定义中,除一个整型的成员外,成员p是指向与节点类型完全相同的指针。

在链表节点的数据结构中,非常特殊的一点就是结构体内的指针域的数据类型使用了未定义成功的数据类型。这是在C中唯一规定可以先使用后定义的数据结构。


(2),链表的创建、输出步骤

单链表的创建过程有以下几步:

1 ) 定义链表的数据结构;

2 ) 创建一个空表;

3 ) 利用malloc ( )函数向系统申请分配一个节点;

4 ) 将新节点的指针成员赋值为空。若是空表,将新节点连接到表头;若是非空表,将新

节点接到表尾;

5 ) 判断一下是否有后续节点要接入链表,若有转到3 ),否则结束;

单链表的输出过程有以下几步

1) 找到表头;

2) 若是非空表,输出节点的值成员,是空表则退出;

3 ) 跟踪链表的增长,即找到下一个节点的地址;

4) 转到2 ).

[代码] 首先是借口定义 跳至 [1] [2]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
 *
 * @author xzf
 *
 */
publicinterfaceMyDeque<E> {
 
    /**
     * insert the specified element at the front of this deque if it is possible
     * to do so immediately without violating capacity restrictions.
     *
     * @param e the element to add
     */
    voidaddFirst(E e);
     
    /**
     * insert the specified element at the end of this deque if it is possible
     * to do so immediately without violating capacity restrictions.
     *
     * @param e the element to add
     */
    voidaddLast(E e);
     
    /**
     * retrieve and remove the first element of this deque.
     *
     * @return the head of this deque
     */
    E removeFirst();
     
    /**
     * retrieve and remove the last element of this deque.
     *
     * @return the tail of this deque
     */
    E removeLast();
     
    /**
     * insert the specified element into the queue represented by this deque
     * (in other words, at the tail of this deque) if it is possible
     * to do so immediately without violating capacity restrictions.
     *
     * @return true upon success
     */
    booleanadd(E e);
     
    /**
     * retrieve and remove the head of this queue represented by this deque
     * (in other words, the first element of this deque).
     *
     * @return the head of the queue represented by this deque
     */
    E remove();
 
    /**
     * push an element onto the stack represented by this deque
     * (in other words, at the head of this deque) if it is possible
     * to do so immediately without violating capacity restrictions.
     *
     * @param e the element to push
     */
    voidpush(E e);
     
    /**
     * pop an element from the stack represented by this deque. In other words,
     * removes and returns the first element of this deque.
     *
     * @return the element at the front of this deque
     */
    E pop();
     
    /**
     * return the number of elements of this dceque.
     *
     * @return the number of elements of this dceque
     */
    publicintsize();
}

[2].[代码] 自定义LinkedList实现类 跳至 [1] [2]

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/**
 *
 * @author xzf
 *
 * @param <E>
 */
publicclassMyLinkedList<E> implementsMyDeque<E>{
 
    privateEntry<E> header;
    privateintsize;
     
    publicMyLinkedList()
    {
        header = newEntry<E>(null,null,null);
        size = 0;
        header.next = header.privious = header;
    }
     
    /**
     * insert the specified element at the front of this deque if it is possible
     * to do so immediately without violating capacity restrictions.
     *
     * @param e the element to add
     */
    publicvoidaddFirst(E e) {
        addBefore(e, header.next);
    }
 
    /**
     * insert the specified element at the end of this deque if it is possible
     * to do so immediately without violating capacity restrictions.
     *
     * @param e the element to add
     */
    publicvoidaddLast(E e) {
        addBefore(e, header);
    }
 
    /**
     * retrieve and remove the first element of this deque.
     *
     * @return the head of this deque
     */
    publicE removeFirst() {
        returnremove(header.next);
    }
 
    /**
     * retrieve and remove the last element of this deque.
     *
     * @return the tail of this deque
     */
    publicE removeLast() {
        returnremove(header.privious);
    }
 
    /**
     * insert the specified element into the queue represented by this deque
     * (in other words, at the tail of this deque) if it is possible
     * to do so immediately without violating capacity restrictions.
     *
     * @return true upon success
     */
    publicbooleanadd(E e) {
        addBefore(e, header);
        returntrue;
    }
 
    /**
     * retrieve and remove the head of this queue represented by this deque
     * (in other words, the first element of this deque).
     *
     * @return the head of the queue represented by this deque
     */
    publicE remove() {
        returnremoveFirst();
    }
 
    /**
     * push an element onto the stack represented by this deque
     * (in other words, at the head of this deque) if it is possible
     * to do so immediately without violating capacity restrictions.
     *
     * @param e the element to push
     */
    publicvoidpush(E e) {
        addFirst(e);
    }
 
    /**
     * pop an element from the stack represented by this deque. In other words,
     * removes and returns the first element of this deque.
     *
     * @return the element at the front of this deque
     */
    publicE pop() {
        returnremoveFirst();
    }
 
    /**
     * return the number of elements of this dceque.
     *
     * @return the number of elements of this dceque
     */
    publicintsize() {
        returnsize;
    }
     
    /**
     * Returns an array containing all of the elements in this list
     * in proper sequence (from first to last element).
     *
     * <p>The returned array will be "safe" in that no references to it are
     * maintained by this list.  (In other words, this method must allocate
     * a new array).  The caller is thus free to modify the returned array.
     *
     * @return an array containing all of the elements in this list
     *         in proper sequence
     */
    publicObject[] toArray()
    {
        Object[] result = newObject[size];
        inti = 0;
         
        for(Entry<E> e=header.next; e!=header; e=e.next)
        {
            result[i++] = e.element;
        }
         
        returnresult;
    }
         
    privatestaticclass Entry<E>
    {
        E element;
        Entry<E> privious;
        Entry<E> next;
         
        Entry(E element, Entry<E> next, Entry<E> privious)
        {
            this.element = element;
            this.next = next;
            this.privious = privious;
        }
    }
     
    privateEntry<E> addBefore(E e, Entry<E> entry)
    {
        Entry<E> newEntry = newEntry<E>(e, entry, entry.privious);
        newEntry.privious.next = newEntry;
        newEntry.next.privious = newEntry;
         
        size ++;
         
        returnnewEntry;
    }
     
    privateE remove(Entry<E> e)
    {
        if(e == header)
        {
            System.out.println("No such element.");
            returnnull;
        }
         
        E result = e.element;
        e.privious.next = e.next;
        e.next.privious = e.privious;
         
        // let gc do its work
        e.privious = null;
        e.next = null;
        e.element = null;
        e = null;
         
        size --;
         
        returnresult;
    }
}

0 0
原创粉丝点击