selection_sort()
单指针遍历法
注意走到tail时的情况
void IntList::selection_sort(){ // take care of the tail!
IntNode* tmp = head; // 从头开始
while(tmp){
IntNode* min = tmp;
IntNode* curr = tmp->next;
// 开始查找
while(curr){
// 每一次遍历找到的最小值
if (min->value > curr->value){
min = curr; // min node address is assigned by curr node
}
curr = curr->next; // 下一次遍历开始
}
// 交换最小节点和tmp的值
int tmpV = tmp->value; // store the value of index node
tmp->value = min->value;
min->value = tmpV;
// 如果tmp已经是tail,则停止遍历
if (tmp->next == nullptr){
break;
}
tmp = tmp->next;
}
}
insert_ordered(int)
双指针遍历法
前后两个指针,前一个指针找到比tmp大的第一个值时将新节点插入当前两个指针中间
该用多指针就用多指针,正确率第一
void IntList::insert_ordered(int num){
IntNode* curr = this->head;
IntNode* prev = nullptr;
IntNode* newNode = new IntNode(num);
while(curr != nullptr && curr->value < num){
prev = curr;
curr = curr->next;
}
if (curr == nullptr){
// 如果已经过了tail还没找到比新节点大的节点,则新节点成为tail
tail = newNode;
}
// 如果head就比新节点大,则新节点成为head
if (prev == nullptr){
head = newNode;
newNode->next = curr;
}else{
// 将新节点与右边的节点连接
newNode->next = curr;
// 将新节点与左边的节点(prev)连接
prev->next = newNode;
}
}
remove_duplicates()
双指针遍历法
考虑移去节点后双指针的相对位置的变化
void IntList::remove_duplicates(){
if (!empty() && head != tail){
IntNode* temp = head;
// 遍历方法与insert_ordered()类似
while(temp != nullptr){
IntNode* curr = temp->next;
IntNode* prev = temp;
while(curr != nullptr){
if(curr->value == temp->value){
IntNode* node = curr;
prev->next = curr->next;
// 前一个指针到达tail时发现tail重复
if (curr->next == nullptr){
// 去掉tail
tail = prev;
// 注意要设为nullptr
tail->next = nullptr;
}
node->next = nullptr;
delete node;
node = nullptr;
// 直接到删除后的next节点(现在是prev的next节点)
curr = prev->next;
}else{
prev = curr; // 找不到的话就继续前进
curr = curr->next;
}
}
temp = temp->next;
}
}
<< operator
打印整个链表
(尾节点的判断方式是node->next
是否为空)检查当前节点的下一个节点是否为nullptr
ostream & operator<<(ostream &out, const IntList &list){
IntNode* node = list.head;
while(node != nullptr){
out << node->value;
if (node->next == nullptr){
break;
}
out << " ";
node = node->next;
}
return out;
}