// 知识点【浅谈单链表与双链表的区别】:https://blog.csdn.net/kangxidagege/article/details/80211225
链表由节点构成;所以编程的时候得有一个类是Node,还需要一个链表类来维护size等等状态;
请你搞清楚链表和线性表区别,前者不支持随机访问(或者说随机访问效率不如后者);前者erase/remove效率高,后者低。
我们仅介绍 构造函数、插入、打印、析构、删除 等等基本功能,其他功能都同理。
一、单项链表
1、构造函数初始化链表:
1 class Node 2 { 3 public: 4 int data_;//数据阈 5 Node* next_;//指针阈 6 }; 7 8 ...... 9 List() 10 { 11 this->head_ = new Node();12 //this->head_->data_ = 0;//多余? 13 this->head_->next_ = nullptr; 14 this->size_ = 0; 15 }; 16 ......
2、插入:看上图绿色箭头,不管插入多少元素,尾部指针必须是NULL,所以插入其实就是将绿色箭头指向的线掐断,然后放入元素,最后链接前驱节点和后(由于是尾部元素,所以没有后驱节点)
1 //在第pos个元素前一个位置插入 2 void List::insert(int pos, int value) 3 { 4 if (pos < 0 || pos > size_) 5 return; 6 7 //创建新的节点接受数据 8 Node* newnode = new Node(); 9 newnode->data_ = value; 11 newnode->next_ = nullptr; 12 13 //利用辅助指针找到pos前一个节点 14 // 其实这里不断next,无非就是希望p_curr = nullptr 15 // 然后24行 让newnode->next_ = nullptr(这个nullptr是从head_->next 传过来的);也就是尾部插入嘛 16 // 而循环链表 同理 让newnode->next_ = &(head_)(这个 &(head_) 是从head_->next 传过来的); 17 Node* p_curr = head_; 18 for (int i = 0; i < pos; i++) //这个for循环本质上是head_->next_->next_...... 19 { 20 p_curr = p_curr->next_; 21 } 22 //现在p_curr就是pos前一个节点的指针阈 23 //新节点入链表 24 newnode->next_ = p_curr->next_; 25 p_curr->next_ = newnode; 26 size_++; 27 }
3、打印:
1 void List::print() 2 { 3 if (size_ == 0) 4 { 5 cout << "size = 0" << endl; 6 return; 7 } 8 //遍历 9 Node* p_curr = head_->next_; 10 while (p_curr != nullptr) 11 { 12 cout << p_curr->data_ << " "; 13 p_curr = p_curr->next_; 14 } 15 cout << endl; 16 }
4、析构:
1 List::~List() 2 { 3 while (size_ != 0) 4 { 5 Node* p_curr = head_; 6 for (int i = 0; i < (size_ - 1); i++)// 012345 i < 5 7 { 8 p_curr = p_curr->next_;//for循环执行完,p_curr指向4 9 } 10 delete p_curr->next_;//删除最后一个元素 11 p_curr->next_ = nullptr;//末尾元素 空指针 12 size_--; 13 print(); 14 } 15 delete head_; //这个容易忘记! 16 cout << "delete!" << endl; 17 }
单项链表代码实现:
1 #include<iostream> 2 #include<set> 3 using namespace std; 4 5 class Node 6 { 7 public: 8 int data_;//数据阈 9 Node* next_;//指针阈 10 }; 11 12 class List 13 { 14 public: 15 List() 16 { 17 this->head_ = new Node();// 不分配空间,下面赋值是不合理的! 18 //this->head_->data_ = 0;//多余? 19 this->head_->next_ = nullptr; 20 this->size_ = 0; 21 }; 22 void insert(int pos, int value); 23 //重载下表[] 24 int operator[](int i); 25 void print(); 26 ~List(); 27 28 29 public: 30 Node* head_; 31 int size_; 32 }; 33 //在第pos个元素前一个位置插入 34 void List::insert(int pos, int value) 35 { 36 if (pos < 0 || pos > size_) 37 return; 38 39 //创建新的节点接受数据 40 Node* newnode = new Node(); 41 newnode->data_ = value; 42 //cout << "newnode->data_ = " << *newnode->data_ << endl; 43 newnode->next_ = nullptr; 44 45 //利用辅助指针找到pos前一个节点 46 // 其实这里不断next,无非就是希望p_curr = nullptr 47 // 然后56行 让newnode->next_ = nullptr(这个nullptr是从head_->next 传过来的);也就是尾部插入嘛 48 // 而循环链表 同理 让newnode->next_ = &(head_)(这个 &(head_) 是从head_->next 传过来的); 49 Node* p_curr = head_; 50 for (int i = 0; i < pos; i++) //这个for循环本质上是head_->next_->next_...... 51 { 52 p_curr = p_curr->next_; 53 } 54 //现在p_curr就是pos前一个节点的指针阈 55 //新节点入链表 56 newnode->next_ = p_curr->next_;//右边 57 p_curr->next_ = newnode;//左边 58 size_++; 59 } 60 int List::operator[](int i) 61 { 62 Node* p_curr = head_; 63 int count = 0; 64 while (count <= i) 65 { 66 p_curr = p_curr->next_; 67 count++; 68 } 69 return p_curr->data_; 70 } 71 void List::print() 72 { 73 if (size_ == 0) 74 { 75 cout << "size = 0" << endl; 76 return; 77 } 78 //遍历 79 Node* p_curr = head_->next_; 80 while (p_curr != nullptr) 81 { 82 cout << p_curr->data_ << " "; 83 p_curr = p_curr->next_; 84 } 85 cout << endl; 86 } 87 List::~List() 88 { 89 while (size_ != 0) 90 { 91 Node* p_curr = head_; 92 for (int i = 0; i < (size_ - 1); i++)// 012345 i < 5 93 { 94 p_curr = p_curr->next_;//for循环执行完,p_curr指向4 95 } 96 delete p_curr->next_;//删除最后一个元素 97 p_curr->next_ = nullptr;//末尾元素 空指针 98 size_--; 99 print(); 100 } 101 delete head_; //这个容易忘记! 102 cout << "delete!" << endl; 103 } 104 105 int main() 106 { 107 List list1; 108 //<1>插入 109 for (int i = 0; i < 11; i++) 110 { 111 list1.insert(i, i*i); 112 } 113 list1.print(); 114 list1.insert(2, 9999); 115 //<2>重载符[] 116 for (int i = list1.size_ - 1; i >= 0; i--) 117 { 118 cout << list1[i] << " "; 119 } 120 cout << endl; 121 122 List list2; 123 list2.insert(0, 10); 124 list2.insert(1, 20); 125 list2.insert(2, 30); 126 list2.print(); 127 int size2 = list2.size_; 128 return 1; 129 }
二、循环链表
1、构造函数初始化:
1 class Node 2 { 3 public: 4 int data; 5 Node* next_; 6 }; 7 ...... 8 public: 9 CircleList() 10 { 11 head_ = new Node(); 12 //head_->data; 13 head_->next_ = head_; 14 size_ = 0; 15 } 16 ......
2、插入,同理插入还是将上图绿色箭头断开,放入节点,前驱连接,节点->next指向head_
1 void CircleList::insert(int pos, int value) 2 { 3 Node* newnode = new Node(); 4 newnode->data = value; 5 newnode->next_ = head_;//其实同上链表 6 7 Node* p_curr = head_; 8 for (int i = 0; i < pos; i++) 9 { 10 p_curr = p_curr->next_; 11 } 12 13 newnode->next_ = p_curr->next_; 14 p_curr->next_ = newnode; 15 size_++; 16 }
3、打印
1 void CircleList::print() 2 { 3 Node* p_curr = head_->next_; 4 for (int i = 0; i < size_*3; i++) 5 { 6 if (p_curr == head_)//关键 7 { 8 p_curr = p_curr->next_; 9 } 10 cout << p_curr->data << " "; 11 p_curr = p_curr->next_; 12 } 13 cout << endl; 14 }
4、析构
1 ~CircleList() 2 { 3 while (size_ != 0) 4 { 5 Node* p_curr = head_; 6 for (int i = 0; i < (size_ - 1); i++)//012345 7 { 8 p_curr = p_curr->next_;//最终指向4 9 } 10 delete p_curr->next_;//删除5 11 p_curr->next_ = head_; 12 size_--; 13 } 14 delete head_; 15 cout << "delete!" << endl; 16 }
循环链表代码示例:
1 // 知识点【浅谈单链表与双链表的区别】:https://blog.csdn.net/kangxidagege/article/details/80211225 2 #include<iostream> 3 4 using namespace std; 5 6 class Node 7 { 8 public: 9 int data; 10 Node* next_; 11 }; 12 13 class CircleList 14 { 15 public: 16 CircleList() 17 { 18 head_ = new Node(); 19 //head_->data; 20 head_->next_ = head_; 21 size_ = 0; 22 } 23 ~CircleList() 24 { 25 while (size_ != 0) 26 { 27 Node* p_curr = head_; 28 for (int i = 0; i < (size_ - 1); i++)//012345 29 { 30 p_curr = p_curr->next_;//最终指向4 31 } 32 delete p_curr->next_;//删除5 33 p_curr->next_ = head_; 34 size_--; 35 } 36 delete head_; 37 cout << "delete!" << endl; 38 } 39 void insert(int pos, int value); 40 void remove(int pos); 41 void print(); 42 public: 43 Node* head_; 44 int size_; 45 }; 46 47 void CircleList::insert(int pos, int value) 48 { 49 Node* newnode = new Node(); 50 newnode->data = value; 51 newnode->next_ = head_; 52 53 Node* p_curr = head_; 54 for (int i = 0; i < pos; i++) 55 { 56 p_curr = p_curr->next_; 57 } 58 59 newnode->next_ = p_curr->next_; 60 p_curr->next_ = newnode; 61 size_++; 62 } 63 64 void CircleList::remove(int pos) 65 { 66 Node* p_curr = head_; 67 for (int i = 0; i < pos; i++) 68 { 69 p_curr = p_curr->next_;//找到要被删除元素的前一个 70 } 71 p_curr->next_ = p_curr->next_->next_; 72 size_--; 73 } 74 75 void CircleList::print() 76 { 77 Node* p_curr = head_->next_; 78 for (int i = 0; i < size_*3; i++) 79 { 80 if (p_curr == head_)//关键 81 { 82 p_curr = p_curr->next_; 83 } 84 cout << p_curr->data << " "; 85 p_curr = p_curr->next_; 86 } 87 cout << endl; 88 } 89 90 int main() 91 { 92 CircleList clist; 93 for (int i = 0; i < 4; i++) 94 { 95 clist.insert(i, i + 1); 96 } 97 clist.insert(2, 999); 98 clist.print(); 99 clist.remove(0); 100 clist.print(); 101 clist.remove(2); 102 clist.print(); 103 clist.remove(1); 104 clist.print(); 105 return 1; 106 }