【问题标题】:Linked List implementation of a StackStack的链表实现
【发布时间】:2019-06-01 00:59:58
【问题描述】:

对实现堆栈相当陌生,正在寻找一些可能的反馈。我的代码给出了正确的输出,但我知道这并不总是意味着它按预期工作。我选择采用使用链表实现堆栈的方法与您的常规链表实现基本相同,只是所有操作都在列表的末尾完成。我不太确定这种方法是否正确,但它遵循先进后出的方法,并且访问和搜索(O(n))以及插入和删除 O(1)具有相同的复杂性。例如 pop() 只是从链表的末尾删除一个节点,而 push() 只是将一个节点附加到链表的末尾。我在下面粘贴了我的代码,其中包含 cmets,解释了我正在做什么或试图做什么(如果不正确)。

#include <iostream>

struct Node{
    int data;
    Node* next;
};

bool isEmpty(Node** stack){
    if(*stack == NULL){
        return true;
    }
    return false;
}
void push(Node** stack, int data){
    Node* new_node = new Node();
    new_node->data = data;
    new_node->next=NULL;
    // stack similar to "head" 
    if(isEmpty(&(*stack))){
        *stack = new_node;
        return;
    }
    Node* temp = *stack;
    while(temp->next != NULL){
        temp = temp->next;
    }
    temp->next = new_node;
}


void pop(Node** stack){
    // checking if stack is empty
    if(isEmpty(&(*stack))){
        std::cout<<"Stack underflow"<<std::endl;
        return;
    }
    Node* deleteMe = *stack;
    // if at the first element in the stack
    if(deleteMe->next == NULL){
        *stack = (*stack)->next;
        delete deleteMe;
        return;
    }
    while(deleteMe->next != NULL){
        if(deleteMe->next->next==NULL){
            // saving the current location of the node before the node which I want to delete
            Node* temp = deleteMe;
            // updating the deleteMe pointer to the node which I want to delete
            deleteMe = deleteMe->next;
            // setting the current node before the deleteMe node to point to NULL instead of the node which I want to delete
            temp->next = NULL;
            delete deleteMe;
            return;
        }
        deleteMe = deleteMe->next;
    }
}

void printList(Node* stack){
    Node* temp = stack;
    while(temp!=NULL){
        std::cout<<temp->data<<" ";
        temp = temp->next;
    }
    std::cout<<"\n";
}

int top(Node** stack){
    Node* top = *stack;
    while(top->next!=NULL){
        top = top->next;
    }
    return top->data;
}


int main(){
    Node* stack = NULL;
    // testing implementation below
    push(&stack,10);
    std::cout<<top(&stack)<<std::endl;
    push(&stack,20);
    std::cout<<top(&stack)<<std::endl;
    push(&stack,30);
    push(&stack,40);
    printList(stack);
    std::cout<<top(&stack)<<std::endl;
    pop(&stack);
    pop(&stack);
    push(&stack,40);
    std::cout<<top(&stack)<<std::endl;
}

【问题讨论】:

  • 顺便说一句,在c++ 中,我们更喜欢通过引用而不是双指针来传递指针。
  • 为什么不在列表的头部而不是尾部添加和删除节点?将使一切更容易。就像推一个节点:new_node-&gt;next = *stack; *stack = new_node; 不需要检查它是否为空,无需循环查找结束。
  • 如果你出于某种原因必须在尾部添加,那么创建一个新的Stack结构,包含指向头部的指针尾巴。
  • @Someprogrammerdude 我什至没有想到这一点。也可以快速更改,谢谢。
  • 鉴于这是似乎可以工作的代码,并且您最希望 cmets 进行潜在的改进,它似乎是为 Code Review 发帖的好人选。

标签: c++ algorithm data-structures linked-list stack


【解决方案1】:

您的实现看起来不错,可以通过维护头尾指针来完成一项额外的改进,以便您可以根据需要删除第一个和最后一个元素。这是示例 C++ 代码。

#include <iostream>
using namespace std;

template <class T> class node {
public:
  node<T>() {}
  ~node<T>() {}

  T data;
  node<T> *next;
};

template <class T> class linked_list {

public:
  linked_list<T>() : head(NULL), tail(NULL) {}
  ~linked_list<T>() {}

  virtual void addFirst(T data) {
    node<T> *n = new node<T>();

    if (head == NULL)
      tail = n;
    n->data = data;
    n->next = head;
    head = n;

    size++;
  }

  virtual void addLast(T data) {
    node<T> *n = new node<T>();

    n->data = data;

    if (tail == NULL) {
      head = n;
    } else {
      tail->next = n;
    }
    n->next = NULL;
    tail = n;
  }

  virtual void reverse() {
    if ((head == NULL) || (head->next == NULL))
      return;

    node<T> *current = head;
    node<T> *previous = NULL;
    node<T> *next = current->next;

    tail = current;

    while (current) {
      next = current->next;
      current->next = previous;
      previous = current;
      current = next;
    }

    head = previous;
  }

  virtual void print_nodes() {

    node<T> *temp = head;

    while (temp) {
      cout << temp->data << " " << flush;
      temp = temp->next;
    }

    cout << endl;
  }

  virtual void removeLast() {
    node<T> *temp = head;

    while (temp->next->next) {
      temp = temp->next;
    }
    tail = temp;
    delete temp->next;
    temp->next = NULL;
  }

  virtual void removeFirst() {
    node<T> *temp = head;
    head = head->next;
    delete temp;
  }

private:
  node<T> *head;
  node<T> *tail;
  uint32_t size;
};

int main(int argc, const char *argv[]) {

  linked_list<uint32_t> *llist = new linked_list<uint32_t>();

  llist->addLast(1);

  llist->addFirst(5);
  llist->addFirst(10);
  llist->addFirst(15);
  llist->addFirst(20);

  llist->addLast(30);

  llist->addFirst(40);

  llist->print_nodes();

  llist->reverse();

  llist->print_nodes();

  llist->removeLast();

  llist->print_nodes();

  llist->removeFirst();

  llist->print_nodes();

  return 0;
}

【讨论】:

  • 发布的代码与问题中的代码几乎没有相似之处。不仅仅是添加一个last 指针。
猜你喜欢
  • 1970-01-01
  • 2014-04-07
  • 1970-01-01
  • 1970-01-01
  • 2013-02-11
  • 2013-11-26
  • 2020-09-08
  • 2016-01-06
  • 1970-01-01
相关资源
最近更新 更多