C++封装一个简单的linklist实现。本来没有写的意思的,做一道题目顺便就稍稍写了一下。
简单的做了一下,只实现了几个常用的功能而已。没有做迭代器,有点麻烦。只是写写而已,平时用还是STL或者Boost库的好。
测试代码在最下面
1: #ifndef _17_LIST_JDFZ_H__
2: #include <iostream>
3:
4:
5: template<typename T>
6: struct listNode
7: {
8: listNode<T>* next; //后继指针
9: listNode<T>* prev; //前驱指针
10: T data; //数据域
11: };
12:
13: template<typename T>
14: class list
15: {
16: public:
17: list<T>();
18: ~list<T>();
19: list<T>& insertHead(T t); //头插入
20: list<T>& insertTail(T t); //尾插入
21: list<T>& merge(list& l); //合并
22: list<T>& reverse(); //逆置链表
23: void show()const; //显示
24:
25: list<T>& sort(bool(*less)(T t1 , T t2)); //排序
26: const listNode<T>* findValue(const T t)const; //查找节点
27: bool update(int index , const T t); //修改节点
28: list<T>& remove(const T t); //移除节点
29: private:
30: listNode<T> voidNode; //空的头节点
31: size_t size; //节点个数
32: };
33:
34:
35:
36:
37:
38: template<typename T>
39: list<T>::list()
40: {
41: //初始化头部空节点
42: voidNode.next = &voidNode;
43: voidNode.prev = &voidNode;
44: size = 0;
45: }
46:
47: template<typename T>
48: list<T>::~list()
49: {
50: listNode<T>* p = voidNode.next; //头节点指针
51: while (p != &voidNode) {//没有走回到空节点
52: p = p->next; //指向下一个
53: delete p->prev; //删除前驱
54: }
55: voidNode.next = &voidNode;
56: voidNode.prev = &voidNode;
57: size = 0;
58: }
59:
60: //#######################################################################
61: //头插入
62: template<typename T>
63: list<T>& list<T>::insertHead(T t)
64: {
65: listNode<T>* temp = new listNode<T>; //new 的时候一定要带类型
66: temp->data = t; //保存数据
67: temp->next = voidNode.next; //后继是原头节点
68: temp->prev = &voidNode; //前驱是空节点
69:
70: voidNode.next = temp; //空节点的后继是新的头节点
71: temp->next->prev = temp; //原头节点的前驱是新头节点
72: size += 1;
73: return *this;
74: }
75: //#######################################################################
76: //尾插入
77: template<typename T>
78: list<T>& list<T>::insertTail(T t)
79: {
80: listNode<T>* temp = new listNode<T>;
81: temp->data = t; //保存数据
82: temp->next = &voidNode; //后继是空节点
83: temp->prev = voidNode.prev; //前驱是原尾节点
84:
85: voidNode.prev = temp; //指向新的最后的节点
86: temp->prev->next = temp; //原本的最后节点的下一个指向新的尾节点
87:
88: size += 1;
89: return *this;
90: }
91: //#######################################################################
92: //合并
93: template<typename T>
94: list<T>& list<T>::merge(list& l)
95: {
96: voidNode.prev->next = l.voidNode.next; //尾节点的下一个是外部list的头节点
97: l.voidNode.next->prev = voidNode.prev;//外部list的头节点的上一个是这个的尾节点
98:
99: voidNode.prev = l.voidNode.prev; //新的尾节点是外部list的尾节点
100: l.voidNode.prev->next = &voidNode; //新尾部节点的下一个是空节点
101:
102: size += l.size;
103: //外部list清空
104: l.voidNode.next = &l.voidNode;
105: l.voidNode.prev = &l.voidNode;
106:
107: return *this;
108: }
109: //#######################################################################
110: // 排序链表 compare为判断函数
111: template<typename T>
112: list<T>& list<T>::sort(bool(*compare)(T t1 , T t2))
113: {
114: listNode<T>* pfind; //查找点指针
115: listNode<T>* ptemp; //临时节点指针
116: listNode<T>* p = voidNode.next; //头节点指针
117: while (p != &voidNode) {
118: //从头开始找可插入的位置
119: pfind = voidNode.next; //从头节点开始找
120: while (pfind != p && compare(pfind->data , p->data)) {
121: //pfind不是p,且符合compare
122: pfind = pfind->next; //走到下一个
123: }
124:
125: //temp要么等于p结束循环,要么不符合compare结束循环
126: ptemp = p->next; //p的后继。在外面赋值是防止没有进入if语句,ptemp是野指针
127: if (pfind != p) {
128: std::cout << pfind->data << "<--->" << p->data << std::endl;
129: //将p插入到pfind所指节点前
130: //将p从链表取下
131: ptemp->prev = p->prev; //p的下一个的前驱指向p的前驱
132: p->prev->next = ptemp; //p的前驱的后继指向p的后继
133: //将p插入到pfind所指节点前
134: p->next = pfind; //p的后继指向pfind
135: p->prev = pfind->prev; //p的前驱指向pfind的前驱
136: p->prev->next = p; //p(pfind)的前驱的后继是p
137: pfind->prev = p; //pfind的前驱指向p
138: }
139: p = ptemp;
140: }
141: return *this;
142: }
143:
144: //#######################################################################
145:
146: template<typename T>
147: void list<T>::show()const
148: {
149: //正向遍历
150: listNode<T>* p = voidNode.next; //头节点指针
151: while (p != &voidNode) {//没有走回到空节点
152: std::cout << p->data << " <==> ";
153: p = p->next; //下一个
154: }
155: std::cout << "\tvoidNode" << std::endl;
156:
157: //反向遍历
158: p = voidNode.prev; //尾节点指针
159: while (p != &voidNode) {//没有走回到空节点
160: std::cout << p->data << " <==> ";
161: p = p->prev; //前驱
162: }
163: std::cout << "\tvoidNode" << std::endl;
164: }
165: //#######################################################################
166:
167: template<typename T>
168: const listNode<T>* list<T>::findValue(const T t)const
169: {
170: listNode<T>* p = voidNode.next; //头节点指针
171: while (p != &voidNode && p->data != t) {//没有走回到空节点
172: p = p->next; //下一个
173: }
174: if (p == &voidNode) {
175: p = nullptr;
176: }
177: return p;
178: }
179: //#######################################################################
180:
181: template<typename T>
182: bool list<T>::update(int index , const T t)
183: {
184: if (index > size) {
185: return false;
186: }
187:
188: listNode<T>* p = voidNode.next; //头节点指针
189: while (--index) {
190: p = p->next;
191: }
192: p->data = t;
193: return true;
194: }
195: //#######################################################################
196:
197: template<typename T>
198: list<T>& list<T>::remove(const T t)
199: {
200: listNode<T> temp;
201: listNode<T>* p = voidNode.next; //头节点指针
202: while (p != &voidNode) {//没有走回到空节点
203: if (p->data != t) {
204: p = p->next; //下一个
205: continue;
206: }
207: //移除节点
208: temp = *p;
209: temp.prev->next = temp.next; //前驱的后继是本节点的后继
210: temp.next->prev = temp.prev; //后继的前驱是本节点的前驱
211: delete p; //删除节点
212: p = temp.next; //p指向下一个
213: }
214: return *this;
215: }
216:
217: //#######################################################################
218: //逆置链表
219: template<typename T>
220: list<T>& list<T>::reverse()
221: {
222: listNode<T>* temp=nullptr; //临时节点指针
223: listNode<T>* p = voidNode.next; //头节点指针
224:
225: while (p != &voidNode) {//没有走回到空节点
226: //前驱=后继,后继=前驱
227: temp = p->next; //保存下一个节点
228: p->next = p->prev; //后继变前驱
229: p->prev = temp; //前驱变后继
230: p = temp; //下一个
231: }
232: //voidNode的反转
233: temp = voidNode.next; //保存下一个节点
234: voidNode.next = voidNode.prev; //后继变前驱
235: voidNode.prev = temp; //前驱变后继
236:
237: return *this;
238: }
239:
240:
241: #endif // !_17_LIST_JDFZ_H__
242:
243:
244:
1: #include <stdlib.h>
2: #include "17-List 简单封装.h"
3:
4: int main()
5: {
6: /**
7: list<char> hello;
8: hello.insertHead('l');
9: hello.insertHead('e');
10: hello.insertHead('h');
11: hello.insertTail('l');
12: hello.insertTail('o');
13:
14: hello.show();
15:
16:
17: list<char> world;
18: world.insertTail('r');
19: world.insertTail('l');
20: world.insertTail('d');
21: world.insertHead('o');
22: world.insertHead('w');
23:
24: world.show();
25:
26: hello.merge(world);
27: hello.show();
28:
29: hello.reverse();
30: hello.show();
31:
32: std::cout<<hello.findValue('o')->data << std::endl;
33:
34: hello.update(3 , 'X');
35: hello.update(13 , 'Y');
36: hello.show();
37:
38:
39: hello.remove('o');
40: hello.remove('h');
41: hello.remove('l');
42: hello.remove('e');
43: hello.remove('d');
44: hello.remove('w');
45: hello.remove('X');
46: hello.show();
47:
48: */
49: list<char> shuzi;
50: shuzi.insertHead('1');
51: shuzi.insertHead('7');
52: shuzi.insertHead('5');
53: shuzi.insertHead('5');
54: shuzi.insertHead('4');
55: shuzi.insertHead('3');
56: shuzi.insertHead('6');
57: shuzi.show();
58: shuzi.sort([](char t1 , char t2)->bool{return t1 <= t2; });
59: shuzi.show();
60: system("pause");
61: return 0;
62: }