算法4 用链表实现栈及队列

链表的内涵简单,使用不简单

链表就是一段内存颗粒的连接,如同珍珠项链。珠子就是存放的内容,线就是单向或双向指针。

链表相对于c数组,好处是内存全是散的,不需要整块内存,只处理头部或尾部数据很简单,中间加减数据不复杂。

但好处就是坏处,散在的内存就无法随机定位,对于随机操作就成了弟弟。而且对于巨大的数据量,析构都是问题。

想起一个故事,韩信要与项羽决战,但刘邦怎么催都不出战,因为缺少一个工具,战车

战车不难造,又快又能抗打的没有,但是如果不想死,必须造出这种战车。铁车抗造,但马拉不动,只能挨打。木车轻快,但一箭穿心,车里的人都玩完。

怎么办?

结合,取其精华,去其糟粕,将木车防箭的地方镶上铁板,整体下来,依然没有铁车结实,没有木车轻快,但吸收了二者的优点,去除了二者的缺陷,已经可以一战了。

故事归故事,瞎说的,但道理是实在的。数组加链表的组合体,因该是对付大数据最合适的战车。

以下是纯单向链表实现的队列和栈,非常简单,不过我照着《算法4》这本书扣了半天,愣是没弄出来,最大的问题是java和C++的变量差的太远,其实java的变量更像C++的指针。怪不得C语言满天飞指针,因为在实现底层数据结构的时候,所有的玩法都是内存的玩法。

动态数组,说白了就是一段连续内存。链表就是不连续内存。对付内存,只能用指针,否则实现难度直接升一个量级,一点不夸张。

多说无益,见代码:再多说两句,链表析构比构造要慢太多了。C++写类的时候,一定给基础变量初始值,指针是nullptr,数值是0,否则就等着找bug吧。

#ifndef STACK
#define STACK

#include <assert.h>


template <typename T>
struct ListStack;

template <typename T>
struct ListQueue;

template <typename T>
struct Node
{
private:
    T item;
    Node *next = nullptr;
    friend class ListStack<T>;
    friend class ListQueue<T>;
};

template <typename T>
struct ListStack
{
    bool isEmpty() { return N == 0; }
    int size() { return N; }
    void push(const T &item)
    {
        Node<T> *oldfirst = first;
        first = new Node<T>();
        first->item = item;
        first->next = oldfirst;
        ++N;
    }
    T pop()
    {
        assert(first);
        T item = first->item;
        Node<T> *temp = first;
        first = first->next;
        --N;
        delete temp;
        return item;
    }
    ~ListStack()
    {
        while (first)
        {
            Node<T> *temp = first;
            first = first->next;
            delete temp;
        }
    }

private:
    Node<T> *first = nullptr;
    unsigned N = 0;
};

template <typename T>
struct ListQueue
{
    bool isEmpty() { return N == 0; }
    int size() { return N; }
    void enqueue(const T &item)
    {
        Node<T> *oldlast = last;
        last = new Node<T>();
        last->item = item;
        if (first)
        {
            oldlast->next = last;
        }
        else
        {
            first = last;
        }
        ++N;
    }
    T dequeue()
    {
        assert(first);
        Node<T> *df = first;
        T item = first->item;
        first = first->next;
        delete df;
        --N;
        return item;
    }
    ~ListQueue()
    {
        while (first)
        {
            Node<T> *df = first;
            first = first->next;
            delete df;
        }
        last = nullptr;
    }

private:
    Node<T> *first = nullptr;
    Node<T> *last = nullptr;
    unsigned N = 0;
};

#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
是的,队列算法可以用链表实现,这种实现方式被称为队列(Linked Queue)。 队列使用链表来存储元素,不需要预先指定队列的容量,因此可以动态地增加或减少元素。队列有两个指针,一个指向队头,一个指向队尾,插入和删除元素只需要更新这两个指针即可。 下面是使用Java实现队列算法代码: ```java public class LinkedQueue { private Node front; // 队头指针 private Node rear; // 队尾指针 // 节点类 private class Node { private int data; private Node next; public Node(int data) { this.data = data; } } // 构造方法,初始化队列 public LinkedQueue() { front = null; rear = null; } // 插入元素,从队尾插入 public void insert(int value) { Node newNode = new Node(value); if (rear == null) { front = newNode; rear = newNode; } else { rear.next = newNode; rear = newNode; } } // 删除元素,从队头删除 public int remove() { if (front == null) { throw new NoSuchElementException(); } int value = front.data; front = front.next; if (front == null) { rear = null; } return value; } // 判断队列是否为空 public boolean isEmpty() { return (front == null); } // 返回队列大小 public int size() { int count = 0; Node current = front; while (current != null) { count++; current = current.next; } return count; } } ``` 此代码实现了一个简单的队列,包括插入、删除、判断队列是否为空和返回队列大小等基本操作。需要注意的是,队列插入和删除元素只需要更新队尾指针和队头指针即可,不需要像数组实现那样移动元素。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不停感叹的老林_<C 语言编程核心突破>

不打赏的人, 看完也学不会.

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值