【发布时间】:2015-06-11 10:17:50
【问题描述】:
晚上好!
我目前正在尝试使用单链表为大学作业创建自定义堆栈。
我创建了一个删除 mHead 元素(列表的开头)的有效弹出窗口,尽管我现在尝试修改该函数以删除 mTail(列表中的最新节点)。我创建了节点 mPrev 来替换 mNext 的功能。想法是将当前尾部设置为 NULL,并将新尾部设置为 mPrev,这将是倒数第二个节点。 我相信每当我使用 push(插入节点)时,我都需要将 mPrev 设置为 mHead 的值。
Pop 和 Push 是有问题的主要功能,大多数其他功能在大多数情况下都可以安全地忽略。
每当我按原样运行代码时,我都会收到访问冲突。不言而喻,我对内容感到不安,所以任何澄清或提示将不胜感激!
#include "stack.h"
Stack::Stack(){ //Constructor
mHead = NULL;
mTail = NULL;
mPrev = NULL;
}
Stack::~Stack(){ //Deconstructor
}
/*
Function: int Stack::charConverter(char convertee)
* Purpose : Convert char to numerical equivilent
* Pre: A char to convert
* Post : An integer is returned
****************************************************************/
int Stack::charConverter(char convertee){
switch (convertee){
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
default: return 9;
}
}
/*
Function: bool Stack::checker(char searchKey)
* Purpose : To determine whether a given character is a usable character (num or operator_
* Pre: A character
* Post : A bool is returned indicating whether or not the given is a usable character
****************************************************************/
bool Stack::checker(char searchKey){
if ((searchKey == '1') || (searchKey == '2') || (searchKey == '3') || (searchKey == '4') || (searchKey == '5')
|| (searchKey == '6') || (searchKey == '7') || (searchKey == '8') || (searchKey == '9') || (searchKey == '+')
|| (searchKey == '-') || (searchKey == '*') || (searchKey == '/') || (searchKey == '^') || (searchKey == '=')){
return true;
}
else {
return false;
}
}
/*
Function: void Stack::display()
* Purpose : To display the entirety of the list
* Pre: None (Though a populated list wouldn't hurt)
* Post : The list is displayed
****************************************************************/
void Stack::display(){
cout << "\n\nThe List: \n";
Node *tmp = mHead;
while (tmp != NULL){
cout << tmp->mData;
if (tmp->mNext != NULL)
cout << "";
tmp = tmp->mNext;
}
delete(tmp);
}
/*
Function: bool Stack::push(int data)
* Purpose : To push a given character/number into the list
* Pre: A character/number to add and a list to add to
* Post : A new character/number is added
****************************************************************/
bool Stack::push(int data){
Node *newNode;
if (mHead == NULL){
mHead = new Node(data); //new case
if (mHead == NULL)
return false;
mTail = mHead; //add to end of case
}
else{
if (isExist(data))
return false;
newNode = new Node(data);
mTail->mNext = newNode;
mTail = newNode;
return true;
} //for else
return true;
} //either way, it is entered successfully
/*
Function: bool Stack::isExist(int searchKey)
* Purpose : To determine whether a given character exists within the list
* Pre: A populated list and character to search for
* Post : A bool is returned indicating whether or not the given character exists
****************************************************************/
bool Stack::isExist(int searchKey){
Node *tmp = mHead;
while (tmp != NULL){
if (tmp->mData == searchKey)
return true;
tmp = tmp->mNext;
}
return false;
}
/*
Function: bool Stack::isNumber(char searchKey)
* Purpose : To determine whether a given character is a number
* Pre: A character
* Post : A bool is returned indicating whether or not the given is a number
****************************************************************/
bool Stack::isNumber(char searchKey){
if ((searchKey == '1') || (searchKey == '2') || (searchKey == '3') || (searchKey == '4') || (searchKey == '5')
|| (searchKey == '6') || (searchKey == '7') || (searchKey == '8') || (searchKey == '9')){
return true;
}
else {
return false;
}
}
/*
Function: bool Stack::operate(int num1, int num2, char function)
* Purpose : Perform mathematical functions
* Pre: 2 numbers to operate on and an operator
* Post : An integer is returned
****************************************************************/
int Stack::operate(int num1, int num2, char function){
switch (function){
case '*': return (num1*num2);
case '-': return (num1-num2);
case '+': return (num1+num2);
case '^': return (num1^num2);
case '/': return (num1/num2);
}
}
/*
Function: char Stack::pop()
* Purpose : To pop the top of the list
* Pre: A list with at least 1 character
* Post : The list has 1 less character
****************************************************************/
char Stack::pop(){
Node *tmp;
char data; //when nothing to pop, it will return this value
if (mTail != NULL){
tmp = mTail; //tmp pointing at node to be deleted
if (mHead == mTail){
mHead = NULL;
mTail = NULL;
}
else{
mTail = mTail->mPrev;
}
tmp->mPrev = NULL;
data = tmp->mData;
delete tmp;
}
return data;
}
/*
Function: char Stack::returnNumber(char searchKey)
* Purpose : To recieve a char input and output the corresponding int
* Pre: A char that has been checked using isNumber()
* Post : An int is returned
****************************************************************/
int Stack::returnNumber(char searchKey){
//Before using this function, be sure to make sure the input is a number using isNumber()
switch (searchKey){
case '1': return 1;
break;
case '2': return 2;
break;
case '3': return 3;
break;
case '4': return 4;
break;
case '5': return 5;
break;
case '6': return 6;
break;
case '7': return 7;
break;
case '8': return 8;
break;
default: return 9;
}
}
/*
Function: int Stack::top()
* Purpose : To return the value of the top member of the stack
* Pre: A stack with node(s)
* Post : An int is returned
****************************************************************/
int Stack::top(){ //Essentiall a get function
Node *tmp = mTail;
return tmp->mData;
}
void Stack::userInput(){
bool validation = false;
string userInput, junk;
int lengthCheck = 1;
while (validation == false){
cout << "\nEnter your equation in postfix: ";
getline(cin, userInput);
for (char & input : userInput)
{
if (((lengthCheck == 1) || (lengthCheck == 2)) && (isNumber(input) == 0)){ //Make sure first character is a number is a number
cout << ERROR_INVALID_FIRST_LAST << endl;
break;
} else if (checker(input) == 0){
cout << ERROR_INVALID_INPUT; //Make sure everything is a valid character
break;
} else {
push(input);
}
lengthCheck++;
}
}
}
#ifndef _STACK_H
#define _STACK_H
#include <string>
#include <iostream>
#include <iomanip>
#include "header.h"
using namespace std;
const string ERROR_INVALID_INPUT = "\nError: The input you have entered is invalid, remember to use only operators and single digits. ";
const string ERROR_INVALID_FIRST_LAST = "\nError: First and last character must always be a number, and last a '='. ";
class Stack{
private:
struct Node{
int mData;
Node *mNext, *mPrev; //Node gives int and next pointer
Node(){ //Default constructor
mNext = NULL;
mPrev = NULL;
}
Node(int value){
mData = value;
mNext = NULL;
}
};
Node *mHead, *mTail, *mPrev; //Start and end of list
public:
Stack();
~Stack();
int charConverter(char convertee);
bool checker(char searchKey);
void display();
bool push(int data);
bool isExist(int searchKey);
bool isNumber(char searchKey);
int operate(int num1, int num2, char function);
char pop();
int returnNumber(char searchKey);
int top();
void userInput();
};
#endif
【问题讨论】:
-
您应该使用
atoi将数字的文本表示转换为内部表示。 -
使用
isdigit函数验证字符是否为数字。 -
在你的 pop 方法中:看看你的 main else。如果到达那里,则意味着 mtail = null,但是您正在访问 mTail->mPrev(或 null->mPrev),这就是引发异常的原因。
-
如果您的
Node对象同时包含mNext和mPrev,则您有一个双向链表,而不是单链表。 -
顺便说一下,
num1^num2是num1 XOR num2。也许你想要pow(num1, num2)?
标签: c++ linked-list stack singly-linked-list