C++ 关于 single linked list 单链表的创建和执行(头尾节点,考虑动态存储和内存泄漏问题)(2)

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值