①不带头结点的单链表的实现(类模板)
1 #include <iostream> 2 #include <cstdlib> 3 #include <ctime> 4 ///无头结点 5 using namespace std; 6 //typedef int T; 7 8 template <class T> 9 struct LinkNode //结点定义 10 { 11 T data;//数据域 12 LinkNode<T>* next;//链域 13 LinkNode(const T& item, LinkNode<T>* ptr=NULL) 14 { 15 data = item; 16 next = ptr; 17 } 18 LinkNode(LinkNode<T>* ptr=NULL) 19 { 20 next = ptr; 21 } 22 }; 23 24 template <class T> 25 class List 26 { 27 private: 28 LinkNode<T>* first; 29 public: 30 List();//构造函数 31 List(const T& x); 32 List(const List<T>& L);//拷贝构造函数 33 List<T>& operator=(const List<T>& L);//赋值运算符函数 34 ~List();//析构函数 35 36 void InputFront(const T& elem);//头插法 37 void InputRear(const T& elem);//尾插法 38 39 void MakeEmpty();//清空链表 40 int Length() const;//返回链表中结点个数 41 42 LinkNode<T>* Search(const T& x);//在链表中查找元素x,找到返回它所在结点的地址,否则返回空 43 LinkNode<T>* Locate(int i);//返回链表中第i个结点的地址,i取值不合法则返回空 44 LinkNode<T>* getHead()const; 45 46 bool GetData(int i, T& x)const;//获取链表第i个元素,将它赋值给x 47 void SetData(int i, const T& x);//设置链表第i个元素为x 48 49 bool Insert(int i, const T& x);//在链表的第i个位置上插入元素x 50 bool Remove(int i, T& x);//删除链表第i个位置的元素,并将它的值赋值给x 51 52 bool IsEmpty() const;//返回链表是否为空 53 bool IsFull() const;//返回链表是否为满 54 55 void CopyList(const List<T>& L);//复制链表 56 57 void Sort();//对链表中结点进行排序 58 59 friend ostream& operator<<(ostream& out, const List<T>& L)//输出流运算符重载 60 { 61 LinkNode<T> *p=L.first; 62 // p = p->next; 63 while(p!=NULL) 64 { 65 cout << p->data << ' '; 66 p = p->next; 67 } 68 cout << endl; 69 return out; 70 } 71 // friend istream& operator>>(istream& in, List& L);//输入流运算符重载 72 }; 73 74 template <class T> 75 List<T>::List()//构造函数 76 { 77 first = NULL; 78 } 79 80 template <class T> 81 List<T>::List(const T& x) //构造函数 82 { 83 first = new LinkNode<T>(x); 84 } 85 86 template <class T> 87 List<T>::List(const List<T>& L)//拷贝构造函数 88 { 89 T temp; 90 LinkNode<T>* strL = L.getHead(); 91 //cout <<L.getHead()<<endl; 92 temp = strL->data; 93 LinkNode<T>* strthis = first = new LinkNode<T>(temp); 94 //cout <<first<<endl; 95 while(strL->next) 96 { 97 temp = strL->next->data; 98 // cout<<temp<<endl; 99 strthis->next = new LinkNode<T>(temp); 100 strthis = strthis->next; 101 strL = strL->next; 102 } 103 strthis->next = NULL; 104 } 105 106 template <class T> 107 LinkNode<T>* List<T>::getHead()const 108 { 109 return first; 110 } 111 112 113 template <class T> 114 List<T>& List<T>::operator=(const List<T>& L)//赋值运算符函数 115 { 116 T temp; 117 LinkNode<T>* strL = L.getHead(); 118 //cout <<L.getHead()<<endl; 119 temp = strL->data; 120 LinkNode<T>* strthis = first = new LinkNode<T>(temp); ///注意在这里要附上初值,要不然会多一个 121 //cout <<first<<endl; 122 while(strL->next) 123 { 124 temp = strL->next->data; 125 // cout<<temp<<endl; 126 strthis->next = new LinkNode<T>(temp); 127 strthis = strthis->next; 128 strL = strL->next; 129 } 130 strthis->next = NULL; 131 return *this; 132 } 133 134 template <class T> 135 List<T>::~List()//析构函数 136 { 137 MakeEmpty(); 138 } 139 140 template <class T> 141 void List<T>::InputFront(const T& elem)//头插法 142 { 143 MakeEmpty(); 144 LinkNode<T> *temp = new LinkNode<T>(elem); 145 if(temp == NULL) 146 exit(1); 147 temp->next = first; 148 first = temp; 149 } 150 151 template <class T> 152 void List<T>::InputRear(const T& elem)//尾插法 153 { 154 LinkNode<T> *temp; 155 MakeEmpty(); 156 temp = new LinkNode<T>(elem); 157 if(first == NULL) //要考虑没有元素的情况 158 first = temp; 159 else 160 { 161 LinkNode<T> *current = first; 162 while(current->next) 163 { 164 current = current->next; 165 } 166 current->next = temp; 167 } 168 return; 169 } 170 171 template <class T> 172 void List<T>::MakeEmpty()//清空链表 173 { 174 LinkNode<T> *q; 175 while(first != NULL) 176 { 177 q = first; 178 first = q->next; 179 delete q; 180 } 181 } 182 183 template <class T> 184 int List<T>::Length() const//返回链表中结点个数 185 { 186 int len = 0; 187 LinkNode<T> *p = first; 188 while(p) 189 { 190 p=p->next; 191 len++; 192 } 193 return len; 194 } 195 196 template <class T> 197 LinkNode<T>* List<T>::Search(const T& x)//在链表中查找元素x,找到返回它所在结点的地址,否则返回空 198 { 199 LinkNode<T> *p = first; 200 while(p) 201 { 202 if(p->data == x) 203 return p; 204 p = p->next; 205 } 206 } 207 208 template <class T> 209 LinkNode<T>* List<T>::Locate(int i)//返回链表中第i个结点的地址,i取值不合法则返回空 210 { 211 if(i<=0) 212 return NULL; 213 LinkNode<T> *p = first; 214 int m = 1; 215 while(p->next != NULL && m<i) 216 { 217 p = p->next; 218 m++; 219 } 220 return p; 221 } 222 223 template <class T> 224 bool List<T>::GetData(int i, T& x)const//获取链表第i个元素,将它赋值给x 225 { 226 if(i <= 0) 227 return NULL; 228 LinkNode<T> *p = Locate(i); 229 if(p == NULL) 230 return false; 231 x = p->data; 232 return true; 233 } 234 235 template <class T> 236 void List<T>::SetData(int i, const T& x)//设置链表第i个元素为x 237 { 238 if(i <= 0) 239 return; 240 LinkNode<T> *p = Locate(i); 241 if(p == NULL) 242 return; 243 p->data = x; 244 } 245 246 template <class T> 247 bool List<T>::Insert(int i, const T& x)//在链表的第i个位置上插入元素x 248 { 249 if((first == NULL) || (i == 0)) 250 { 251 LinkNode<T> *newNode = new LinkNode<T>(x); 252 if(newNode == NULL) 253 { 254 cerr << "存储分配错误!"; 255 exit(1); 256 } 257 newNode->next = first; 258 first = newNode; 259 } 260 else 261 { 262 LinkNode<T> *pre = first; 263 for(int j = 1; j < i; j++) 264 { 265 if(pre->next == NULL) 266 break; 267 else 268 pre = pre -> next; 269 } 270 if(pre == NULL) 271 { 272 cout << "无效的插入位置" << endl; 273 return false; 274 } 275 else 276 { 277 LinkNode<T> *newNode = new LinkNode<T>(x); 278 newNode -> next = pre -> next; 279 pre -> next = newNode; 280 } 281 } 282 return true; 283 } 284 285 template <class T> 286 bool List<T>::Remove(int i, T& x)//删除链表第i个位置的元素,并将它的值赋值给x 287 { 288 LinkNode<T> *p = Locate(i-1); 289 if(p == NULL) 290 return false; 291 LinkNode<T> *del = p->next; 292 x = del->next->data; 293 p->next = del->next; 294 295 delete del; 296 return true; 297 } 298 299 template <class T> 300 bool List<T>::IsEmpty() const//返回链表是否为空 301 { 302 if(first = NULL) 303 return true; 304 else 305 return false; 306 } 307 308 template <class T> 309 bool List<T>::IsFull() const//返回链表是否为满 310 { 311 return false; 312 } 313 314 template <class T> 315 void List<T>::CopyList(const List& L) //复制链表 316 { 317 LinkNode<T> *iter = new LinkNode<T>; 318 LinkNode<T> *rear = new LinkNode<T>; 319 if(L.first == NULL) 320 return; 321 LinkNode<T> *newNode = new LinkNode<T>(L.first -> data); 322 first = newNode; 323 iter = L.first -> next; 324 rear = newNode; 325 while(iter) 326 { 327 LinkNode<T> *newNode = new LinkNode<T>(iter -> data); 328 rear -> next = newNode; 329 iter = iter -> next; 330 rear = rear -> next; 331 } 332 } 333 334 335 template <class T> 336 void List<T>::Sort()//对链表中结点进行排序 337 { 338 LinkNode<T> *current = this->first; 339 int temp; 340 while(current->next != NULL) 341 { 342 LinkNode<T>* second = current->next; 343 while(second != NULL) 344 { 345 if((current->data) > (second->data)) 346 { 347 temp = current->data; 348 current->data = second->data; 349 second->data = temp; 350 } 351 second = second->next; 352 } 353 current = current->next; 354 } 355 } 356 357 358 //template <class T> 359 //friend istream& operator>>(istream& in, List& L)//输入流运算符重载 360 //{ 361 362 //} 363 364 int main() 365 { 366 List<int> lst; 367 srand(time(NULL)); 368 for(int i=1; i<=5; i++) 369 lst.Insert(i,rand()%50); 370 cout << "past: " <<lst; 371 cout <<endl; 372 373 lst.SetData(3,999); 374 cout<<"SetData,No.3=99: "<<lst; 375 cout <<endl; 376 377 lst.Sort(); 378 cout << "sort: " << lst; 379 cout <<endl; 380 381 int val; 382 lst.Remove(2,val); 383 cout << "remove:(second) " << lst; 384 // cout<<"FIRST: "<<lst.getHead()<<endl; 385 cout <<endl; 386 387 List<int> lst1 = lst; 388 // cout<<"FIRST: "<<lst1.getHead()<<endl; 389 cout << lst1; 390 lst.MakeEmpty(); 391 lst = lst1; 392 // cout<<"FIRST: "<<lst.getHead()<<endl; 393 cout << lst; 394 395 return 0; 396 }
#调试结果#
②带头结点的单链表的实现(类模板)
1 #include <iostream> 2 #include <cstdlib> 3 #include <ctime> 4 ///带头结点 5 using namespace std; 6 //typedef int T; 7 8 template <class T> 9 struct LinkNode //结点定义 10 { 11 T data;//数据域 12 LinkNode<T>* next;//链域 13 LinkNode(const T& item, LinkNode<T>* ptr=NULL) 14 { 15 data = item; 16 next = ptr; 17 } 18 LinkNode(LinkNode<T>* ptr=NULL) 19 { 20 next = ptr; 21 } 22 }; 23 24 template <class T> 25 class List 26 { 27 private: 28 LinkNode<T>* first; 29 public: 30 List();//构造函数 31 List(const T& x); 32 List(const List<T>& L);//拷贝构造函数 33 List<T>& operator=(const List<T>& L);//赋值运算符函数 34 ~List();//析构函数 35 36 void InputFront(const T& elem);//头插法 37 void InputRear(const T& elem);//尾插法 38 39 void MakeEmpty();//清空链表 40 int Length() const;//返回链表中结点个数 41 42 LinkNode<T>* Search(const T& x);//在链表中查找元素x,找到返回它所在结点的地址,否则返回空 43 LinkNode<T>* Locate(int i);//返回链表中第i个结点的地址,i取值不合法则返回空 44 LinkNode<T>* getHead()const; 45 46 bool GetData(int i, T& x)const;//获取链表第i个元素,将它赋值给x 47 void SetData(int i, const T& x);//设置链表第i个元素为x 48 49 bool Insert(int i, const T& x);//在链表的第i个位置上插入元素x 50 bool Remove(int i, T& x);//删除链表第i个位置的元素,并将它的值赋值给x 51 52 bool IsEmpty() const;//返回链表是否为空 53 bool IsFull() const;//返回链表是否为满 54 55 void CopyList(const List<T>& L);//复制链表 56 57 void Sort();//对链表中结点进行排序 58 59 friend ostream& operator<<(ostream& out, const List<T>& L)//输出流运算符重载 60 { 61 LinkNode<T> *p=L.first; 62 p = p->next; 63 while(p!=NULL) 64 { 65 cout << p->data << ' '; 66 p = p->next; 67 } 68 cout << endl; 69 return out; 70 } 71 // friend istream& operator>>(istream& in, List& L);//输入流运算符重载 72 }; 73 74 template <class T> 75 List<T>::List()//构造函数 76 { 77 first = new LinkNode<T>; //first不指向NULL了,指向一个头结点 78 } 79 80 template <class T> 81 List<T>::List(const T& x) //构造函数 82 { 83 first = new LinkNode<T>(x); 84 } 85 86 template <class T> 87 List<T>::List(const List<T>& L)//拷贝构造函数 88 { 89 T temp; 90 LinkNode<T>* strL = L.getHead(); 91 //cout <<L.getHead()<<endl; 92 // temp = strL->data; 93 LinkNode<T>* strthis = first = new LinkNode<T>; //这里也进行了更改 94 //cout <<first<<endl; 95 while(strL->next) 96 { 97 temp = strL->next->data; //change 98 // cout<<temp<<endl; 99 strthis->next = new LinkNode<T>(temp); 100 strthis = strthis->next; 101 strL = strL->next; 102 } 103 strthis->next = NULL; 104 } 105 106 template <class T> 107 LinkNode<T>* List<T>::getHead()const 108 { 109 return first; 110 } 111 112 113 template <class T> 114 List<T>& List<T>::operator=(const List<T>& L)//赋值运算符函数 115 { 116 T temp; 117 LinkNode<T>* strL = L.getHead(); 118 //cout <<L.getHead()<<endl; 119 //temp = strL->data; 120 LinkNode<T>* strthis = first = new LinkNode<T>; 121 //cout <<first<<endl; 122 while(strL->next) 123 { 124 temp = strL->next->data; 125 // cout<<temp<<endl; 126 strthis->next = new LinkNode<T>(temp); 127 strthis = strthis->next; 128 strL = strL->next; 129 } 130 strthis->next = NULL; 131 return *this; 132 } 133 134 template <class T> 135 List<T>::~List()//析构函数 136 { 137 MakeEmpty(); 138 } 139 140 template <class T> 141 void List<T>::InputFront(const T& elem)//头插法 142 { 143 MakeEmpty(); 144 LinkNode<T> *temp = new LinkNode<T>(elem); 145 if(temp == NULL) 146 exit(1); 147 temp->next = first; 148 first = temp; 149 } 150 151 template <class T> 152 void List<T>::InputRear(const T& elem)//尾插法 153 { 154 LinkNode<T> *temp; 155 MakeEmpty(); 156 temp = new LinkNode<T>(elem); 157 if(first == NULL) //要考虑没有元素的情况 158 first = temp; 159 else 160 { 161 LinkNode<T> *current = first; 162 while(current->next) 163 { 164 current = current->next; 165 } 166 current->next = temp; 167 } 168 return; 169 } 170 171 template <class T> 172 void List<T>::MakeEmpty()//清空链表 173 { 174 LinkNode<T> *q; 175 while(first->next != NULL) ///这里所有的first都要修改->next 176 { 177 q = first->next; 178 first->next = q->next; 179 delete q; 180 } 181 } 182 183 template <class T> 184 int List<T>::Length() const//返回链表中结点个数 185 { 186 int len = 0; 187 LinkNode<T> *p = first->next; ///++++++ 188 while(p) 189 { 190 p=p->next; 191 len++; 192 } 193 return len; 194 } 195 196 template <class T> 197 LinkNode<T>* List<T>::Search(const T& x)//在链表中查找元素x,找到返回它所在结点的地址,否则返回空 198 { 199 LinkNode<T> *p = first->next; ///++++++ 200 while(p) 201 { 202 if(p->data == x) 203 return p; 204 p = p->next; 205 } 206 } 207 208 template <class T> 209 LinkNode<T>* List<T>::Locate(int i)//返回链表中第i个结点的地址,i取值不合法则返回空 210 { 211 if(i<0) 212 return NULL; 213 LinkNode<T> *p = first; 214 int m = 1; 215 while(p != NULL && m<i) ///直接操作就行 216 { 217 p = p->next; 218 m++; 219 } 220 return p; 221 } 222 223 template <class T> 224 bool List<T>::GetData(int i, T& x)const//获取链表第i个元素,将它赋值给x 225 { 226 if(i <= 0) 227 return NULL; 228 LinkNode<T> *p = Locate(i); 229 if(p == NULL) 230 return false; 231 x = p->data; 232 return true; 233 } 234 235 template <class T> 236 void List<T>::SetData(int i, const T& x)//设置链表第i个元素为x 237 { 238 if(i <= 0) 239 return; 240 LinkNode<T> *p = Locate(i+1); 241 if(p == NULL) 242 return; 243 p->data = x; 244 } 245 246 template <class T> 247 bool List<T>::Insert(int i, const T& x)//在链表的第i个位置上插入元素x 248 { 249 250 LinkNode<T> *pre = Locate(i); ///有的时候不要自己写那么麻烦,直接使用函数,再比如copyList 251 252 if(pre == NULL) 253 return false; 254 255 LinkNode<T> *newNode = new LinkNode<T>(x); 256 newNode -> next = pre -> next; 257 pre -> next = newNode; 258 259 return true; 260 } 261 262 template <class T> 263 bool List<T>::Remove(int i, T& x)//删除链表第i个位置的元素,并将它的值赋值给x 264 { 265 LinkNode<T> *p = Locate(i); 266 if(p == NULL || p->next == NULL) 267 return false; 268 LinkNode<T> *del = p->next; 269 x = del->data; 270 p->next = del->next; 271 272 delete del; 273 return true; 274 } 275 276 template <class T> 277 bool List<T>::IsEmpty() const//返回链表是否为空 278 { 279 if(first->next = NULL) 280 return true; 281 else 282 return false; 283 } 284 285 template <class T> 286 bool List<T>::IsFull() const//返回链表是否为满 287 { 288 return false; 289 } 290 291 template <class T> 292 void List<T>::CopyList(const List& L) //复制链表 293 { 294 LinkNode<T> *iter = new LinkNode<T>; 295 LinkNode<T> *rear = new LinkNode<T>; 296 if(L.first == NULL) 297 return; 298 LinkNode<T> *newNode = new LinkNode<T>(L.first -> data); 299 first = newNode; 300 iter = L.first -> next; 301 rear = newNode; 302 while(iter) 303 { 304 LinkNode<T> *newNode = new LinkNode<T>(iter -> data); 305 rear -> next = newNode; 306 iter = iter -> next; 307 rear = rear -> next; 308 } 309 } 310 311 312 template <class T> 313 void List<T>::Sort()//对链表中结点进行排序 314 { 315 LinkNode<T> *current = this->first->next; 316 int temp; 317 while(current->next != NULL) 318 { 319 LinkNode<T>* second = current->next; 320 while(second != NULL) 321 { 322 if((current->data) > (second->data)) 323 { 324 temp = current->data; 325 current->data = second->data; 326 second->data = temp; 327 } 328 second = second->next; 329 } 330 current = current->next; 331 } 332 } 333 334 335 //template <class T> 336 //friend istream& operator>>(istream& in, List& L)//输入流运算符重载 337 //{ 338 339 //} 340 341 int main() 342 { 343 List<int> lst; 344 srand(time(NULL)); 345 for(int i=1; i<=5; i++) 346 lst.Insert(i,rand()%50); 347 cout << "past: " <<lst; 348 cout <<endl; 349 350 lst.SetData(3,999); 351 cout<<"SetData,No.3=999: "<<lst; 352 cout <<endl; 353 354 lst.Sort(); 355 cout << "sort: " << lst; 356 cout <<endl; 357 358 int val; 359 lst.Remove(2,val); 360 cout << "remove:(second) " << lst; 361 // cout<<"FIRST: "<<lst.getHead()<<endl; 362 cout <<endl; 363 364 List<int> lst1 = lst; 365 // cout<<"FIRST: "<<lst1.getHead()<<endl; 366 cout << lst1; 367 lst.MakeEmpty(); 368 lst = lst1; 369 // cout<<"FIRST: "<<lst.getHead()<<endl; 370 cout << lst; 371 372 return 0; 373 }