C++实现循环单链表

源码:

#include <iostream>
using namespace std;

// 定义节点类
class Node {
public:
    int data;   // 数据域
    Node* next; // 指针域,指向下一个节点

    // 构造函数
    Node(int value) {
        data = value;
        next = nullptr;
    }
};

// 定义循环单链表类
class CircularLinkedList {
private:
    Node* head; // 指向头节点的指针

public:
    // 构造函数
    CircularLinkedList() {
        head = nullptr;
    }

    // 在头部插入节点
    void insertAtHead(int value)
    {
        Node* newNode = new Node(value);
        if (head == nullptr)
        {
            head = newNode;
            head->next = head; // 自己指向自己,形成循环
        }
        else
        {
            Node* temp = head;
            while (temp->next != head)
            {
                temp = temp->next;
            }
            newNode->next = head;
            temp->next = newNode;
            head = newNode;
        }
    }

    // 在尾部插入节点
    void insertAtTail(int value) {
        Node* newNode = new Node(value);
        if (head == nullptr) {
            head = newNode;
            head->next = head;
        }
        else {
            Node* temp = head;
            while (temp->next != head) {
                temp = temp->next;
            }
            temp->next = newNode;
            newNode->next = head;
        }
    }

    // 删除指定值的节点
    void deleteValue(int value)
    {
        if (head == nullptr)
            return;

        if (head->data == value)
        {
            if (head->next == head)
            { // 只有一个节点
                delete head;
                head = nullptr;
            }
            else
            {
                Node* temp = head;
                while (temp->next != head)
                {
                    temp = temp->next;
                }
                Node* toDelete = head;
                head = head->next;
                temp->next = head;
                delete toDelete;
            }
            return;
        }

        Node* current = head;
        while (current->next != head && current->next->data != value)
        {
            current = current->next;
        }
        if (current->next->data == value)
        {
            Node* toDelete = current->next;
            current->next = toDelete->next;
            delete toDelete;
        }
    }

    // 修改指定位置的节点值
    void updateValue(int position, int newValue)
    {
        if (head == nullptr)
            return;

        Node* current = head;
        int count = 1;
        while (count != position && current->next != head)
        {
            current = current->next;
            count++;
        }
        if (count == position)
        {
            current->data = newValue;
        }
    }

    // 查找指定值的节点
    bool searchValue(int value)
    {
        if (head == nullptr) return false;

        Node* current = head;
        do
        {
            if (current->data == value)
            {
                return true;
            }
            current = current->next;
        } while (current != head);
        return false;
    }

    // 打印链表
    void printList() const
    {
        if (head == nullptr) return;

        Node* current = head;
        do
        {
            cout << current->data << " ";
            current = current->next;
        } while (current != head);
        cout << endl;
    }

    // 链表逆置
    void reverseList()
    {
        if (head == nullptr || head->next == head) return;

        Node* prev = nullptr;
        Node* current = head;
        Node* next = nullptr;
        Node* tail = head;

        do 
        {
            next = current->next;
            current->next = prev;
            prev = current;
            current = next;
        } while (current != head);

        head->next = prev;
        head = prev;
    }

    // 析构函数,释放链表内存
    ~CircularLinkedList()
    {
        if (head == nullptr) return;

        Node* current = head;
        while (current->next != head)
        {
            Node* toDelete = current;
            current = current->next;
            delete toDelete;
        }
        delete current;
        head = nullptr;
    }
};

// 主函数
int main()
{
    CircularLinkedList list;

    int choice, value, position;

    while (true)
    {
        cout << "1. 在头部插入节点" << endl;
        cout << "2. 在尾部插入节点" << endl;
        cout << "3. 删除节点" << endl;
        cout << "4. 修改节点" << endl;
        cout << "5. 查找节点" << endl;
        cout << "6. 打印链表" << endl;
        cout << "7. 逆置链表" << endl;
        cout << "8. 退出" << endl;
        cout << "请输入你的选择: ";
        cin >> choice;

        switch (choice) {
        case 1:
            cout << "请输入要插入的值: ";
            cin >> value;
            list.insertAtHead(value);
            system("pause");
            system("cls");
            break;
        case 2:
            cout << "请输入要插入的值: ";
            cin >> value;
            list.insertAtTail(value);
            system("pause");
            system("cls");
            break;
        case 3:
            cout << "请输入要删除的值: ";
            cin >> value;
            list.deleteValue(value);
            system("pause");
            system("cls");
            break;
        case 4:
            cout << "请输入要修改的位置和新值: ";
            cin >> position >> value;
            list.updateValue(position, value);
            system("pause");
            system("cls");
            break;
        case 5:
            cout << "请输入要查找的值: ";
            cin >> value;
            if (list.searchValue(value)) {
                cout << "找到节点: " << value << endl;
            }
            else {
                cout << "未找到节点: " << value << endl;
            }
            system("pause");
            system("cls");
            break;
        case 6:
            list.printList();
            system("pause");
            system("cls");
            break;
        case 7:
            list.reverseList();
            cout << "链表已逆置。" << endl;
            system("pause");
            system("cls");
            break;
        case 8:
            return 0;
        default:
            cout << "无效选择,请重试。" << endl;
        }
    }

    system("pause");
    return 0;
}

关于元素逆置


链表逆置的目标是将链表中所有节点的指针方向反转。例如,给定一个链表:

head -> 0x001(1, 0x002) -> 0x002(2, 0x003) -> 0x003(3, 0x001)

逆置后的链表应该变成:

head -> 0x003(3, 0x002) -> 0x002(2, 0x001) -> 0x001(1, 0x003)
 

核心思路
逆置链表的核心在于逐个改变每个节点的 `next` 指针,使其指向前一个节点。为了实现这一点,我们需要:
1. 遍历链表。
2. 记录当前节点的前一个节点和下一个节点。
3. 更新当前节点的 `next` 指针。

使用的指针
prev:记录前一个节点的位置。初始值为 `nullptr`,因为第一个节点逆置后将成为新链表的尾节点,它的 next 应为 nullptr。
current:记录当前节点,从头节点开始逐个遍历链表。
next:临时保存当前节点的下一个节点的位置,以便在改变 `current->next` 后还能继续遍历链表。
tail:保存原始链表的头节点,在逆置完成后更新新链表的末尾节点指向新头节点,实现循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值