C++数组模拟之单链表与双链表和栈和队列的实现过程

yizhihongxing

下面是一个完整的攻略。

1. 单链表的实现

单链表是一种常用的链式结构,其核心是节点(Node)和指针(pointer):

  • 节点:保存数据和指向下一个节点的指针
  • 指针:用于连接各个节点

以下是单链表的核心代码:

// 节点结构体
struct Node {
    int data;
    Node* next;
    Node(int d): data(d), next(nullptr) {}
};

// 单链表类
class LinkedList {
public:
    LinkedList(): head(nullptr) {}

    void add_front(int data); // 在链表头添加节点
    void add_back(int data); // 在链表尾添加节点
    void remove(int data); // 删除指定数据的节点
    void print(); // 打印链表内容

private:
    Node* head; // 头节点
};

其中,add_frontadd_back方法分别是在链表头和链表尾添加节点,核心思路如下:

  • 在链表头添加节点:

    1. 新建节点
    2. 将head节点作为新节点的下一个节点
    3. 将head更新为新节点
  • 在链表尾添加节点:

    1. 新建节点
    2. 找到链表的最后一个节点
    3. 将最后一个节点的next指针指向新节点

remove方法的核心是找到要删除的节点以及更新节点的next指针。

print方法的核心是遍历链表,并输出每个节点的数据。

以下是add_front方法的示例:

void LinkedList::add_front(int data) {
    Node* new_node = new Node(data);
    new_node->next = head;
    head = new_node;
}

2. 双链表的实现

双链表和单链表类似,不同之处在于:

  • 节点(Node)保存了指向上一个节点的指针(prev)和下一个节点的指针(next)
  • add_front方法需要更新原head节点的prev指针,remove方法需要更新相关节点的prev和next指针

以下是双链表的核心代码:

// 双链表节点结构体
struct Node {
    int data;
    Node* prev;
    Node* next;
    Node(int d): data(d), prev(nullptr), next(nullptr) {}
};

// 双链表类
class DoublyLinkedList {
public:
    DoublyLinkedList(): head(nullptr), tail(nullptr) {}

    void add_front(int data); // 在链表头添加节点
    void add_back(int data); // 在链表尾添加节点
    void remove(int data); // 删除指定数据的节点
    void print(); // 打印链表内容

private:
    Node* head; // 头节点
    Node* tail; // 尾节点
};

以下是add_front方法的示例:

void DoublyLinkedList::add_front(int data) {
    Node* new_node = new Node(data);
    if (head == nullptr) { // 空链表
        head = new_node;
        tail = new_node;
    } else {
        new_node->next = head;
        head->prev = new_node;
        head = new_node;
    }
}

3. 栈的实现

栈(Stack)是一种基于先进后出(LIFO)的数据结构,其核心操作是压入(push)和弹出(pop)元素:

  • 压入元素:将元素放在栈顶
  • 弹出元素:取出栈顶元素

以下是栈的核心代码:

// 栈类
class Stack {
public:
    Stack(): top(-1) {}

    void push(int data); // 压入元素
    int pop(); // 弹出元素
    bool is_empty(); // 判断栈是否为空
    void print(); // 打印栈内容

private:
    static const int MAXSIZE = 100; // 栈最大容量
    int data[MAXSIZE]; // 栈数据
    int top; // 栈顶索引
};

其中,push方法的实现:

void Stack::push(int data) {
    if (top >= MAXSIZE - 1) { // 栈满
        cout << "Stack is full!" << endl;
        return;
    }
    data[++top] = data;
}

pop方法的实现:

int Stack::pop() {
    if (top < 0) { // 栈空
        cout << "Stack is empty!" << endl;
        return -1;
    }
    return data[top--];
}

4. 队列的实现

队列(Queue)是一种基于先进先出(FIFO)的数据结构,其核心操作是入队(enqueue)和出队(dequeue):

  • 入队:将元素加入队尾
  • 出队:取出队头元素

以下是队列的核心代码:

// 队列类
class Queue {
public:
    Queue(): front(0), rear(0) {}

    void enqueue(int data); // 入队
    int dequeue(); // 出队
    bool is_empty(); // 判断队列是否为空
    void print(); // 打印队列内容

private:
    static const int MAXSIZE = 100; // 队列最大容量
    int data[MAXSIZE]; // 队列数据
    int front; // 队头索引
    int rear; // 队尾索引
};

其中,enqueue方法的实现:

void Queue::enqueue(int data) {
    if ((rear + 1) % MAXSIZE == front) { // 队列已满
        cout << "Queue is full!" << endl;
        return;
    }
    data[rear] = data; // 将数据放到队尾
    rear = (rear + 1) % MAXSIZE; // 更新尾指针
}

dequeue方法的实现:

int Queue::dequeue() {
    if (front == rear) { // 队列为空
        cout << "Queue is empty!" << endl;
        return -1;
    }
    int res = data[front]; // 取出队头元素
    front = (front + 1) % MAXSIZE; // 更新头指针
    return res;
}

5. 示例说明

以下是一个示例程序,分别展示了单链表、双链表、栈和队列的基本操作:

int main() {
    // 单链表示例
    LinkedList ll;
    ll.add_front(1);
    ll.add_front(2);
    ll.add_back(3);
    ll.add_back(4);
    ll.print();
    ll.remove(2);
    ll.print();

    // 双链表示例
    DoublyLinkedList dll;
    dll.add_front(1);
    dll.add_front(2);
    dll.add_back(3);
    dll.add_back(4);
    dll.print();
    dll.remove(2);
    dll.print();

    // 栈示例
    Stack s;
    s.push(1);
    s.push(2);
    s.push(3);
    s.print();
    s.pop();
    s.print();

    // 队列示例
    Queue q;
    q.enqueue(1);
    q.enqueue(2);
    q.enqueue(3);
    q.print();
    q.dequeue();
    q.print();

    return 0;
}

以上程序将输出以下结果:

2 -> 1 -> 3 -> 4
1 -> 3 -> 4
2 -> 1 -> 3 -> 4
1 -> 3 -> 4
3 -> 2 -> 1
3 -> 1
3 2 1
2 1
1 -> 2 -> 3
2 -> 3

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++数组模拟之单链表与双链表和栈和队列的实现过程 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • C++子类父类成员函数的覆盖和隐藏实例详解

    C++子类父类成员函数的覆盖和隐藏 覆盖(Override) 当子类定义了与父类相同名称、参数列表和返回类型的成员函数时,子类的成员函数会覆盖父类的同名函数,称之为覆盖。 实现方式是使用 override 关键字表明该函数是对基类函数的重写,子类中的该函数将取代基类中的同名函数。如果子类中未找到需要重写的函数,编译器会给出错误提示。 假设有一个基类 Shap…

    other 2023年6月26日
    00
  • Java实现一键获取Mysql所有表字段设计和建表语句的工具类

    我来详细讲解“Java实现一键获取Mysql所有表字段设计和建表语句的工具类”的完整攻略。 设计思路 该工具类主要实现以下流程:1. 连接Mysql数据库并获取表结构信息;2. 遍历表结构信息并生成建表语句和字段设计。 实现步骤 第一步:创建工具类文件 首先,我们需要创建一个Java文件作为我们的工具类。这里我创建了一个名为“MysqlTableUtil”的…

    other 2023年6月25日
    00
  • Android编程开发中ListView的常见用法分析

    Android编程开发中ListView的常见用法分析 1. ListView简介 ListView是Android开发中常用的控件之一,用于展示大量数据列表。它可以在垂直方向上滚动,并且可以自定义每个列表项的布局。 2. 常见用法分析 2.1 创建ListView 要创建一个ListView,首先需要在XML布局文件中定义ListView的位置和大小。例如…

    other 2023年8月21日
    00
  • Go语言基础结构体用法及示例详解

    以下是关于“Go语言基础结构体用法及示例详解”的完整攻略。 什么是结构体 在Go中,结构体是一种自定义数据类型,结构体中可以包含多个不同类型的字段,相当于Java中的Class或者C++中的结构体。结构体的定义方式如下: type 结构体名 struct { 字段1 数据类型1 字段2 数据类型2 … } 例如: type Person struct {…

    other 2023年6月27日
    00
  • 详解angularJs模块ui-router之状态嵌套和视图嵌套

    详解AngularJS模块UI-Router之状态嵌套和视图嵌套攻略 简介 在AngularJS中,UI-Router是一个强大的路由库,它提供了更灵活的路由功能,包括状态嵌套和视图嵌套。状态嵌套允许我们在应用程序中创建层次结构的状态,而视图嵌套则允许我们在页面中嵌套多个视图。 状态嵌套 状态嵌套是指在UI-Router中创建一个状态的子状态。子状态继承了父…

    other 2023年7月28日
    00
  • Golang原生rpc(rpc服务端源码解读)

    Golang原生rpc服务端源码解读 什么是RPC RPC是Remote Procedure Call的缩写,译为远程过程调用。它允许像调用本地函数一样调用远程函数。 在分布式系统中,不同的机器上运行着不同的进程,这些进程需要相互通信才能协同工作。RPC技术使得分布式系统中的进程间通信变得简单易行,让开发分布式系统的复杂性得以降低。 Golang原生rpc服…

    other 2023年6月27日
    00
  • CSS 实现网页图片的预加载

    下面是关于“CSS 实现网页图片预加载”的完整攻略: 什么是图片预加载? 图片预加载指的是在网页完成加载之前,提前加载页面所需的图片资源,从而达到更快的打开速度和更好的用户体验。通常在网页开发中,需要使用 JavaScript 或 CSS 实现图片预加载。 使用CSS 实现图片预加载 使用 CSS 实现图片预加载主要是通过 CSS 中的 :before 或 …

    other 2023年6月25日
    00
  • C++ Date类的具体使用(构建,重载等)

    下面我来详细讲解如何使用C++ Date类。 构建Date类对象 我们可以通过Date类的构造函数来构建一个Date类的对象,Date类的构造函数有以下两种形式: // 使用默认日期构造一个Date类对象 Date(); // 使用传入的年份、月份、日期构造一个Date类对象 Date(int year, int month, int day); 示例: #…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部