C++实现链表的基本操作【单、双、循环】

一、单向

#include <iostream>
#include <stdexcept>
using namespace std;

#define eleType int

class ListNode // 结点
{
public:
    eleType data;                                // 数据域
    ListNode* next;                              // 指针域
    ListNode(eleType x) : data(x), next(NULL) {}; // 构造
};

class LinkedList // 链表
{
private:
    ListNode* head; // 头结点
    int size;       // 链表长度

public:
    LinkedList() : head(NULL), size(0) {}; // 构造
    ~LinkedList();                        // 析构
    void insert(int i, eleType value);    // 插入
    void remove(int i);                   // 删除
    ListNode* find(eleType value);        // 查找(需要返回)
    ListNode* get(int i);                 // 获取(需要返回)
    void update(int i, eleType value);    // 修改
    void print();                         // 输出
};

LinkedList::~LinkedList() // 析构
{
    ListNode* curr = head;
    while (curr != NULL)
    {
        ListNode* temp = curr;
        curr = curr->next;
        delete temp;
    }
}
void LinkedList::insert(int i, eleType value) // 插入
{
    if (i < 0 || i > size)
    {
        throw std::out_of_range("Invalid position");
    }
    ListNode* newNode = new ListNode(value);
    if (i == 0)
    {
        newNode->next = head;
        head = newNode;
    }
    else
    {
        ListNode* curr = head;
        for (int j = 0; j < i - 1; j++)
        {
            curr = curr->next;
        }
        newNode->next = curr->next;
        curr->next = newNode;
    }
    ++size;
}
void LinkedList::remove(int i) // 删除指定元素
{
    if (i < 0 || i > size)
    {
        throw std::out_of_range("Invalid position");
    }
    if (i == 0)
    {
        ListNode* temp = head;
        head = head->next;
        delete temp;
    }
    else
    {
        ListNode* curr = head;
        for (int j = 0; j < i - 1; j++)
        {
            curr = curr->next;
        }
        ListNode* temp = curr->next;
        curr->next = temp->next;
        delete temp;
    }
    --size;
}
ListNode* LinkedList::find(eleType value) // 查找
{
    ListNode* curr = head;
    while (curr && curr->data != value)
    {
        curr = curr->next;
    }
    return curr;
}
ListNode* LinkedList::get(int i) // 获取
{
    if (i < 0 || i > size)
    {
        throw std::out_of_range("Invalid position");
    }
    ListNode* curr = head;
    for (int j = 0; j < i; ++j)
    {
        curr = curr->next;
    }
    return curr;
}
void LinkedList::update(int i, eleType value) // 修改
{
    if (i < 0 || i > size)
    {
        throw std::out_of_range("Invalid position");
    }
    get(i)->data = value;
}
void LinkedList::print() // 输出
{
    ListNode* curr = head;
    while (curr != NULL)
    {
        cout << curr->data << "  ";
        curr = curr->next;
    }
}
int main()
{
    LinkedList List;
    List.insert(1, 100);
    List.insert(2, 100);
    List.insert(3, 100);
    List.insert(4, 100);
    List.remove(1);
    List.find(100);
    List.get(100);
    List.update(2, 200);
    List.print();
    return 0;
}

二、双向

#include <iostream>
#include <stdexcept>
using namespace std;

#define eleType int

class DNode // 结点
{
public:
    eleType data;                                          // 数据域
    DNode* prior;                                          // 前驱指针
    DNode* next;                                           // 后继指针
    DNode(eleType x) : data(x), next(NULL), prior(NULL) {}; // 构造
};

class DoubleList // 链表
{
private:
    DNode* head; // 头指针
    DNode* tail; // 尾指针
    int size;    // 链表长度
    /*注意:
    D Node 类中的 prior 和 next 指针是每个节点特有的,用于节点之间的连接关系
    DoubleList 类中的 head 和 tail 指针是整个链表共享的,用于表示整个链表的起始和结束位置。*/
public:
    DoubleList() : head(new DNode(NULL)), tail(new DNode(NULL)), size(0) {}; // 构造
    ~DoubleList();                                                          // 析构
    void insert(int i, eleType value);                                      // 插入
    void remove(int i);                                                     // 删除
    DNode* find(eleType value);                                             // 查找(需要返回)
    DNode* get(int i);                                                      // 获取(需要返回)
    void update(int i, eleType value);                                      // 修改
    void print();                                                           // 输出
};

DoubleList::~DoubleList() // 析构
{
    DNode* curr = head;
    while (curr != NULL)
    {
        DNode* temp = curr;
        curr = curr->next;
        delete temp;
    }
}
void DoubleList::insert(int i, eleType value) // 插入
{
    if (i < 0 || i > size)
    {
        throw std::out_of_range("Invalid position");
    }
    DNode* newNode = new DNode(value);
    if (i == 0)
    {
        newNode->prior = head->next;
        newNode->next = tail->prior;
    }
    else
    {
        DNode* curr = head;
        for (int j = 0; j < i; j++)
        {
            curr = curr->next;
        }
        newNode->next = curr->next;
        curr->next->prior = newNode;
        newNode->prior = curr;
        curr->next = newNode;
    }
    delete newNode;
    ++size;
}
void DoubleList::remove(int i) // 删除
{
    if (i < 0 || i > size)
    {
        throw std::out_of_range("Invalid position");
    }
    if (i == 0)
    {
        DNode* temp1 = head;
        DNode* temp2 = tail;
        temp1->next = NULL;
        temp2->prior = NULL;
    }
    else
    {
        // 双指针便于交换指针指向
        DNode* curr1 = head; // 删除结点的前驱结点
        DNode* curr2 = head; // 删除的结点
        for (int j = 0; j < i; j++)
        {
            curr1 = curr1->next;
            curr2 = curr2->next;
        }
        curr2 = curr2->next; // curr2指向第i个结点curr1指向第i个结点的前驱结点
        curr1->next = curr2->next;
        curr2->next->prior = curr2->prior;
        delete curr2;
    }
    --size;
}
DNode* DoubleList::find(eleType value) // 查找(需要返回)
{
    DNode* curr = head;
    DNode* newNode = new DNode(value);
    for (int i = 0; i < size; i++)
    {
        if (curr->data = newNode->data)
        {
            return curr;
        }
        else
        {
            throw std::out_of_range("Invalid value");
        }
    }
}
DNode* DoubleList::get(int i) // 获取(需要返回)
{
    if (i < 0 || i > size)
    {
        throw std::out_of_range("Invalid position");
    }
    if (i == 0)
    {
        return head->next;
    }
    else
    {
        DNode* curr = head;
        for (int j = 0; j <= i; j++)
        {
            curr = curr->next;
        }
        return curr;
    }
}
void DoubleList::update(int i, eleType value) // 修改
{
    if (i < 0 || i > size)
    {
        throw std::out_of_range("Invalid position");
    }
    DNode* newNode = new DNode(value);
    if (i == 0)
    {
        head->next = newNode->prior;
        tail->prior = newNode->next;
        delete newNode;
    }
    else
    {
        DNode* curr = head;
        for (int j = 0; j <= i; j++)
        {
            curr = curr->next;
        }
        curr->data = newNode->data;
    }
    delete newNode;
}
void DoubleList::print() // 输出
{
    DNode* temp1 = head;
    DNode* temp2 = tail;
    while (temp1 != NULL && temp2 != NULL)
    {
        temp1 = temp1->next;
        cout << temp1->data << "     ";
    }
}

int main()
{
    DoubleList List;
    List.insert(1, 100);
    List.insert(2, 100);
    List.insert(3, 100);
    List.insert(4, 100);
    List.remove(1);
    List.find(100);
    List.get(100);
    List.update(2, 200);
    List.print();
    return 0;
}

三、循环单向

#include <iostream>
#include <stdexcept>
using namespace std;

#define eleType int

class ListNode // 结点
{
public:
    eleType data;                                // 数据域
    ListNode* next;                              // 指针域
    ListNode(eleType x) : next(NULL), data(x) {}; // 构造
};

class CirLinkedList // 循环单链表
{
private:
    ListNode* head; // 头指针
    int size;       // 链表长度
public:
    CirLinkedList() : head(new ListNode(0)), size(0) { head->next = head; }; // 构造
    ~CirLinkedList();                                                        // 析构
    void insert(int i, eleType value);                                            // 插入
    void remove(int i);                                                           // 删除
    ListNode* find(eleType value);                                                // 查找(需要返回)
    ListNode* get(int i);                                                         // 获取(需要返回)
    void update(int i, eleType value);                                            // 修改
    void print();                                                                 // 输出
};

CirLinkedList::~CirLinkedList()
{
    ListNode* curr = head->next;
    while (curr != head)
    {
        ListNode* temp = curr;
        curr = curr->next;
        delete temp;
    }
    delete head;
}

void CirLinkedList::insert(int i, eleType value)
{
    if (i < 0 || i > size)
    {
        throw std::out_of_range("Invalid position");
    }
    ListNode* newNode = new ListNode(value);
    ListNode* curr = head;
    for (int j = 0; j < i; j++)
    {
        curr = curr->next;
    }
    newNode->next = curr->next;
    curr->next = newNode;
    ++size;
}

void CirLinkedList::remove(int i)
{
    if (i < 0 || i >= size)
    {
        throw std::out_of_range("Invalid position");
    }
    ListNode* curr = head;
    for (int j = 0; j < i; j++)
    {
        curr = curr->next;
    }
    ListNode* temp = curr->next;
    curr->next = temp->next;
    delete temp;
    --size;
}

ListNode* CirLinkedList::find(eleType value)
{
    ListNode* curr = head->next;
    while (curr != head)
    {
        if (curr->data == value)
        {
            return curr;
        }
        curr = curr->next;
    }
    return NULL;
}

ListNode* CirLinkedList::get(int i)
{
    if (i < 0 || i >= size)
    {
        throw std::out_of_range("Invalid position");
    }
    ListNode* curr = head->next;
    for (int j = 0; j < i; j++)
    {
        curr = curr->next;
    }
    return curr;
}

void CirLinkedList::update(int i, eleType value)
{
    ListNode* node = get(i);
    if (node != NULL)
    {
        node->data = value;
    }
}

void CirLinkedList::print()
{
    ListNode* curr = head->next;
    while (curr != head)
    {
        cout << curr->data << " ";
        curr = curr->next;
    }
    cout << endl;
}

int main()
{
    CirLinkedList list;
    list.insert(0, 1);
    list.insert(1, 2);
    list.insert(2, 3);
    list.print(); // 输出: 1 2 3

    list.update(1, 4);
    list.print(); // 输出: 1 4 3

    list.remove(1);
    list.print(); // 输出: 1 3
    return 0;
}

四、循环双向

#include <iostream>
#include <stdexcept>
using namespace std;

#define eleType int

class ListNode // 结点
{
public:
    eleType data;                                            // 数据域
    ListNode* next;                                          // 后指针域
    ListNode* prev;                                          // 前指针域
    ListNode(eleType x) : next(NULL), prev(NULL), data(x) {}; // 构造
};

class CirDoubleListed // 循环双链表
{
private:
    ListNode* head; // 头指针
    int size;       // 链表长度
public:
    CirDoubleListed() : head(new ListNode(0)), size(0)
    {
        head->next = head;
        head->prev = head;
    };                                 // 构造
    ~CirDoubleListed();       // 析构
    void insert(int i, eleType value); // 插入
    void remove(int i);                // 删除
    ListNode* find(eleType value);     // 查找(需要返回)
    ListNode* get(int i);              // 获取(需要返回)
    void update(int i, eleType value); // 修改
    void print();                      // 输出
};

CirDoubleListed::~CirDoubleListed()
{
    ListNode* curr = head->next;
    while (curr != head)
    {
        ListNode* temp = curr;
        curr = curr->next;
        delete temp;
    }
    delete head;
}

void CirDoubleListed::insert(int i, eleType value)
{
    if (i < 0 || i > size)
    {
        throw std::out_of_range("Invalid position");
    }
    ListNode* newNode = new ListNode(value);
    ListNode* curr = head;
    for (int j = 0; j < i; j++)
    {
        curr = curr->next;
    }
    newNode->next = curr->next;
    newNode->prev = curr;
    curr->next->prev = newNode;
    curr->next = newNode;
    ++size;
}

void CirDoubleListed::remove(int i)
{
    if (i < 0 || i >= size)
    {
        throw std::out_of_range("Invalid position");
    }
    ListNode* curr = head;
    for (int j = 0; j < i; j++)
    {
        curr = curr->next;
    }
    ListNode* temp = curr->next;
    curr->next = temp->next;
    temp->next->prev = curr;
    delete temp;
    --size;
}

ListNode* CirDoubleListed::find(eleType value)
{
    ListNode* curr = head->next;
    while (curr != head)
    {
        if (curr->data == value)
        {
            return curr;
        }
        curr = curr->next;
    }
    return NULL;
}

ListNode* CirDoubleListed::get(int i)
{
    if (i < 0 || i >= size)
    {
        throw std::out_of_range("Invalid position");
    }
    ListNode* curr = head->next;
    for (int j = 0; j < i; j++)
    {
        curr = curr->next;
    }
    return curr;
}

void CirDoubleListed::update(int i, eleType value)
{
    ListNode* node = get(i);
    if (node != NULL)
    {
        node->data = value;
    }
}

void CirDoubleListed::print()
{
    ListNode* curr = head->next;
    while (curr != head)
    {
        cout << curr->data << " ";
        curr = curr->next;
    }
    cout << endl;
}

int main()
{
    CirDoubleListed list;
    list.insert(0, 1);
    list.insert(1, 2);
    list.insert(2, 3);
    list.print(); // 输出: 1 2 3

    list.update(1, 4);
    list.print(); // 输出: 1 4 3

    list.remove(1);
    list.print(); // 输出: 1 3
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值