对于单链表的介绍部分参考自博文。
1. 单链表介绍
单向链表(单链表)是链表的一种,它由节点组成,每个节点都包含下一个节点的指针。
1.1 单链表的示意图
表头为空,表头的后继节点是"节点10"(数据为10的节点),"节点10"的后继节点是"节点20"(数据为10的节点),...
1.2 单链表添加节点
在"节点10"与"节点20"之间添加"节点15"
添加之前:"节点10" 的后继节点为"节点20"。
添加之后:"节点10" 的后继节点为"节点15",而"节点15" 的后继节点为"节点20"。
需要注意的是在链表头部和其他地方添加结点是不一样的。
在链表头部添加结点的关键代码为:
1 NodePointer ptr = new Node(); 2 ptr->data = val; 3 ptr->next = head; 4 head = ptr;
在其他地方添加结点的关键代码为:
1 NodePointer ptr = new Node(), tmpPtr = head; 2 ptr->data = val; 3 while(...){...} 4 ptr->next = tmpPtr->next; 5 tmpPtr->next = ptr;
1.3 单链表删除节点
删除"节点30"
删除之前:"节点20" 的后继节点为"节点30",而"节点30" 的后继节点为"节点40"。
删除之后:"节点20" 的后继节点为"节点40"。
需要注意的是在链表首部、尾部和其他地方删除结点是不一样的。
在链表首部删除结点的关键代码为:
1 NodePointer ptr = head, tmpPtr; 2 ...if (pos == 0) // 在链表第一个位置 3 { 4 head = ptr->next; 5 delete ptr; 6 }
在链表尾部删除结点的关键代码为:
1 NodePointer ptr = head, tmpPtr; 2 while (...){...} 3 tmpPtr = ptr->next; 4 ptr->next = NULL; 5 delete tmpPtr;
在其他地方删除结点的关键代码为:
1 NodePointer ptr = head, tmpPtr; 2 while(...){...} 3 tmpPtr = ptr->next; 4 ptr->next = tmpPtr->next; 5 delete tmpPtr;
2. 代码实现
对于单链表,我定义了一个这样的类LinkedList:
1 // linkedlist.h 2 #ifndef LINKEDLIST 3 #define LINKEDLIST 4 5 #include <iostream> 6 #include <cassert> 7 8 using namespace std; 9 10 typedef int ElementType; 11 12 class Node 13 { 14 public: 15 ElementType data; 16 Node * next; 17 }; 18 typedef Node * NodePointer; 19 20 21 class LinkedList 22 { 23 public: 24 LinkedList(); 25 virtual ~LinkedList(); 26 LinkedList(const LinkedList& origlist); // 拷贝构造函数 27 LinkedList& operator=(const LinkedList& origlist); // 赋值运算符重载 28 void initList(ElementType * arr, int len); 29 bool isEmpty(); 30 bool addNode(const int pos, const ElementType val); 31 bool deleteNode(const int pos); 32 void displayNodes(); 33 NodePointer getNode(const int pos); 34 int getLenOfList(); 35 36 private: 37 NodePointer head; 38 39 }; 40 41 #endif // LINKEDLIST
实现代码如下:
1 // linkedlist.cpp 2 #include "linkedlist.h" 3 4 LinkedList::LinkedList() 5 { 6 head = NULL; 7 } 8 9 LinkedList::~LinkedList() 10 { 11 NodePointer ptr = head, tmpPtr; 12 while (ptr != NULL) 13 { 14 tmpPtr = ptr; 15 ptr = ptr->next; 16 delete tmpPtr; 17 } 18 } 19 20 LinkedList::LinkedList(const LinkedList& origlist) 21 { 22 //head = origlist.head; // 很容易写成这样,这样会造成浅拷贝 23 NodePointer ptr = origlist.head; 24 int i = 0; 25 while (ptr != NULL) 26 { 27 addNode(i, ptr->data); 28 ptr = ptr->next; 29 i++; 30 } 31 } 32 33 LinkedList& LinkedList::operator=(const LinkedList& origlist) 34 { 35 //head = origlist.head; // 很容易写成这样,这样会造成浅拷贝 36 NodePointer ptr = origlist.head; 37 int i = 0; 38 while (ptr != NULL) 39 { 40 addNode(i, ptr->data); 41 ptr = ptr->next; 42 i++; 43 } 44 return *this; 45 } 46 47 void LinkedList::initList(ElementType * arr, int len) 48 { 49 for (int i = 0; i < len; i++) 50 { 51 addNode(i, arr[i]); 52 } 53 } 54 55 bool LinkedList::isEmpty() 56 { 57 return head == NULL; 58 } 59 60 bool LinkedList::addNode(const int pos, const ElementType val) 61 { 62 bool success = true; 63 int len = getLenOfList(); 64 // assert(0 <= pos <= len); 65 if (pos < 0 || pos > len) 66 { 67 cerr << "The node at position " << pos << " you want to add is less than zero or larger than " 68 << "the length of list ." << endl; 69 success = false; 70 throw out_of_range("out_of_range"); 71 } 72 else 73 { 74 NodePointer ptr = new Node(); 75 ptr->data = val; 76 if (pos == 0) // 如果添加的元素在第1个 77 { 78 ptr->next = head; 79 head = ptr; 80 } 81 else // 其他 82 { 83 NodePointer tmpPtr = head; 84 int count = 0; 85 while (tmpPtr != NULL && count < pos - 1) 86 { 87 tmpPtr = tmpPtr->next; 88 count++; 89 } 90 ptr->next = tmpPtr->next; 91 tmpPtr->next = ptr; 92 } 93 94 } 95 96 return success; 97 } 98 99 bool LinkedList::deleteNode(const int pos) 100 { 101 bool success = true; 102 int len = getLenOfList(); 103 if (len == 0) 104 { 105 cerr << "There is no element in the list." << endl; 106 success = false; 107 } 108 else 109 { 110 NodePointer ptr = head, tmpPtr; 111 int count = 0; 112 // assert(0 <= pos <= len); 113 if (pos < 0 || pos > len - 1) 114 { 115 cerr << "The node at position " << pos << " you want to delete is less than zero or larger than " 116 << "the length of list ." << endl; 117 success = false; 118 throw out_of_range("out_of_range"); 119 } 120 else if (pos == 0) // 在链表第一个位置 121 { 122 head = ptr->next; 123 delete ptr; 124 } 125 else if (pos == len - 1) // 在链表最后一个位置 126 { 127 while (ptr != NULL && count < pos - 1) 128 { 129 ptr = ptr->next; 130 count++; 131 } 132 tmpPtr = ptr->next; 133 ptr->next = NULL; 134 delete tmpPtr; 135 } 136 else // 其他 137 { 138 while (ptr != NULL && count < pos - 1) 139 { 140 ptr = ptr->next; 141 count++; 142 } 143 tmpPtr = ptr->next; 144 ptr->next = tmpPtr->next; 145 delete tmpPtr; 146 } 147 } 148 return success; 149 } 150 151 void LinkedList::displayNodes() 152 { 153 int len = getLenOfList(); 154 if (len == 0) 155 { 156 cerr << "There is no element in the list." << endl; 157 } 158 else 159 { 160 NodePointer ptr = head; 161 int sequence = 0; 162 while (ptr != NULL) 163 { 164 cout << "Seq: " << sequence << "; Data: " << ptr->data << "."<< endl;; 165 ptr = ptr->next; 166 sequence++; 167 } 168 } 169 170 } 171 172 NodePointer LinkedList::getNode(const int pos) 173 { 174 int len = getLenOfList(); 175 if (len == 0) 176 { 177 cerr << "There is no element in the list." << endl; 178 return NULL; 179 } 180 else 181 { 182 // assert(0 <= pos <= len); 183 if (pos < 0 || pos > len - 1) 184 { 185 cerr << "The item at position " << pos << " you want to get is less than zero or " 186 << "larger than the length of list." << endl; 187 throw out_of_range("out_of_range"); 188 // return NULL; 189 } 190 else 191 { 192 NodePointer ptr = head; 193 int count = 0; 194 while (ptr != NULL && count < pos) 195 { 196 ptr = ptr->next; 197 count++; 198 } 199 return ptr; 200 } 201 } 202 } 203 204 int LinkedList::getLenOfList() 205 { 206 int len = 0; 207 NodePointer ptr = head; 208 while (ptr != NULL) 209 { 210 len++; 211 ptr = ptr->next; 212 } 213 return len; 214 }