c++实现不带头结点的双向非循环链表(代码即注释,超详细版)

c++实现不带头结点的双向非循环链表(代码即注释,超详细版)

直接上代码

#include <iostream>

using namespace std;

class Node
{
public:
    int _data;
    Node *_pre;
    Node *_next;
    // 初始化节点
    Node(int data = 0) : _data(data), _pre(nullptr), _next(nullptr)
    {
        // cout << "Node()" << endl;
    }

    ~Node()
    {
        // cout << "~Node()" << endl;
    }
};

class List
{
private:
    Node *_head;
    Node *_tail;
    int _size;

public:
	// 初始话链表
    List() : _head(nullptr), _tail(nullptr), _size(0)
    {
        // cout << "List()" << endl;
    }

    // 不带头节点的非循环双向链表头部插入操作
    void headInsertNode(int data)
    {
    	// 如果此时链表为空,插入第一个节点
        if (0 == _size)
        {
        	// 申请空间,将头尾指针指向该节点,链表大小加1
            Node *newNode = new Node(data);
            _head = newNode;
            _tail = newNode;
            ++_size;
        }
        else
        {
            Node *newNode = new Node(data);
            newNode->_next = _head;  // 新节点插入到头节点前
            _head->_pre = newNode;
            _head = newNode;         // 头指针指向新插入的节点
            ++_size;
        }
    }

    //尾部插入
    void tailInsertNode(int data)
    {
        if (0 == _size)
        {
            Node *newNode = new Node(data);
            _head = newNode;
            _tail = newNode;

            ++_size;
        }
        else
        {
            Node *newNode = new Node(data);
            _tail->_next = newNode;
            newNode->_pre = _tail;
            _tail = newNode;       // 尾指针指向新插入的节点
            ++_size;
        }
    }

    // 指定位置插入数据,插入元素data到第pos的位置
    int posInsert(int pos, int data)
    {
        // 判断非法位置
        if (pos < 1 || pos > (_size + 1))
        {
            cout << "posInsert(" << pos << ", " << data << "): error pos!" << endl;
            return -1;
        }

        // 如果插入位置是1,表示插在链表最开始位置
        if (1 == pos)
        {
            headInsertNode(data);
        }

        // 如果插入位置是链表的长度+1,表示插在链表的最后面
        else if (_size + 1 == pos)
        {
            tailInsertNode(data);
        }
        else
        {
            // 偏移指针到指定位置
            Node *pIns = _head;
            while ((--pos) > 1)
            {
                cout << "pos = " << pos << endl;
                pIns = pIns->_next;
            }

            // 申请新的节点空间
            Node *newNode = new Node(data);
            newNode->_next = pIns->_next;
            newNode->_pre = pIns;

            pIns->_next->_pre = newNode;
            pIns->_next = newNode;
            ++_size;
        }

        return 0;
    }

    // 从头部删除元素
    void deleteHead()
    {
    	// 判断链表是否为空,空则无法删除数据
        if (_size)
        {
            Node *pDel = _head;
            _head = _head->_next;

            delete pDel;
            pDel = nullptr;
            --_size;
        }
        else
        {
            cout << "list is empty, can not delete any data!" << endl;
        }
    }

    // 从尾部删除元素
    void deleteTail()
    {
        if (_size)
        {
            Node *pDel = _tail;
            _tail = _tail->_pre;
            delete pDel;
            pDel = nullptr;
            --_size;
        }
        else
        {
            cout << "list is empty, can not delete any data!" << endl;
        }
    }

    // 删除指定位置元素,
    int posDelete(int pos)
    {
        // 判断非法位置
        if (pos < 1 || pos > _size)
        {
            cout << "posDelete(" << pos << "): error pos!" << endl;
            return -1;
        }

        if (1 == pos)
        {
            deleteHead();
        }

        else if (_size == pos)
        {
            deleteTail();
        }

        else
        {
        	// 将指针指向头节点,准备进行偏移到待删除位置
            Node *pDel = _head;
            while ((pos--) > 1)
            {
                pDel = pDel->_next;
            }

            pDel->_pre->_next = pDel->_next;
            pDel->_next->_pre = pDel->_pre;

            delete pDel;
            pDel = nullptr;
            --_size;
        }
        return 0;
    }
    // 打印节点,从头开始打印
    void printList()
    {
        // cout << "list size = " << _size << endl;
        if (_size)
        {
            Node *pNode = _head;
            cout << "链表元素: ";
            for (int i = 0; i < _size; ++i)
            {
                cout << pNode->_data << " ";
                pNode = pNode->_next;
            }
            cout << endl;
        }
        else
        {
            cout << "empty list!" << endl;
        }
    }

    int listSize() const
    {
        return _size;
    }

    void findNode(int data)
    {
        if (_size)
        {
            Node *findNode = _head;
            while (findNode->_next)
            {
                if (data == findNode->_data)
                {
                    cout << data << " is in the list!" << endl;
                    return;
                }
                findNode = findNode->_next;
            }
            cout << data << " is not in the list!" << endl;
        }
    }

    ~List()
    {
        // cout << "~List()" << endl;
        // 从头到尾依次删除节点,并释放空间
        while (_size)
        {
            Node *deleteNode = _head;
            _head = _head->_next;

            delete deleteNode;
            deleteNode = nullptr;
            _size--;
        }
    }
};

int main(int argc, char **argv)
{
    List lt;
    lt.printList();
    lt.tailInsertNode(10);
    lt.headInsertNode(11);
    lt.tailInsertNode(9);

    lt.printList();
    lt.posInsert(0, 1);
    lt.printList();
    lt.posInsert(1, 2);
    lt.printList();
    lt.posInsert(2, 3);
    lt.printList();

    lt.findNode(11);
    lt.findNode(12);

    cout << "list size = " << lt.listSize() << endl;
    lt.posDelete(6);
    lt.printList();
    lt.posDelete(1);
    lt.printList();
    lt.deleteHead();
    lt.printList();

    return 0;
}

运行结果:

empty list!
链表元素: 11 10 9 
posInsert(0, 1): error pos!
链表元素: 11 10 9 
链表元素: 2 11 10 9 
链表元素: 2 3 11 10 9 
11 is in the list!
12 is not in the list!
list size = 5
posDelete(6): error pos!
链表元素: 2 3 11 10 9 
链表元素: 3 11 10 9 
链表元素: 11 10 9

本人能力有限,如有错误望不吝指正,原创不易,欢迎转载,转载请注明出处

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用 C++ 实现双向循环链表代码,已加入注释以加深理解: ```c++ #include <iostream> using namespace std; // 双向循环链表的结点类 class Node { public: int data; // 数据域 Node* prev; // 指向前一个结点的指针 Node* next; // 指向后一个结点的指针 Node(int d = 0, Node* p = nullptr, Node* n = nullptr) : data(d), prev(p), next(n) {} }; // 双向循环链表类 class DoubleLinkedList { private: Node* head; // 头结点指针 Node* tail; // 尾结点指针 public: // 构造函数,初始化头结点和尾结点 DoubleLinkedList() { head = new Node(); tail = new Node(); head->next = tail; tail->prev = head; } // 在链表尾部插入结点 void append(int d) { Node* newNode = new Node(d, tail->prev, tail); tail->prev->next = newNode; tail->prev = newNode; } // 在链表中指定位置插入结点 void insert(int pos, int d) { if (pos < 0 || pos > size()) { cout << "Invalid position!" << endl; return; } Node* cur = head->next; for (int i = 0; i < pos; i++) { cur = cur->next; } Node* newNode = new Node(d, cur->prev, cur); cur->prev->next = newNode; cur->prev = newNode; } // 在链表中删除指定位置的结点 void remove(int pos) { if (pos < 0 || pos >= size()) { cout << "Invalid position!" << endl; return; } Node* cur = head->next; for (int i = 0; i < pos; i++) { cur = cur->next; } cur->prev->next = cur->next; cur->next->prev = cur->prev; delete cur; } // 获取指定位置的结点的数据 int get(int pos) { if (pos < 0 || pos >= size()) { cout << "Invalid position!" << endl; return -1; } Node* cur = head->next; for (int i = 0; i < pos; i++) { cur = cur->next; } return cur->data; } // 获取链表的长度 int size() { int count = 0; Node* cur = head->next; while (cur != tail) { count++; cur = cur->next; } return count; } // 打印链表中所有结点的数据 void print() { Node* cur = head->next; while (cur != tail) { cout << cur->data << " "; cur = cur->next; } cout << endl; } }; int main() { DoubleLinkedList list; list.append(1); list.append(2); list.append(3); list.insert(1, 4); list.print(); // 输出:1 4 2 3 list.remove(2); list.print(); // 输出:1 4 3 cout << "The size of the list is " << list.size() << endl; // 输出:The size of the list is 3 cout << "The data of the first node is " << list.get(0) << endl; // 输出:The data of the first node is 1 return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值