1.栈
栈是一种数据结构,它是一种只允许在一端进行插入或删除操作的线性表。这一端被称为栈顶,另一端被称为栈底。栈的插入操作被称为入栈,删除操作被称为出栈。栈的特点是后进先出(Last-In-First-Out,LIFO),即最后进入的元素最先被删除,而最先进入的元素最后被删除
此处用单链表的形式来表达栈,根据栈的特性,向栈里(入栈)添加元素时就相当于单链表的头插法添加元素,出栈就相当于不断的除去链表第一个节点(即头节点与第二节点链接)。
主要代码实现:
节点类
class Node
{
public:
Node* Next;
string item;
Node(Node* n, string str)
{
Next = n;
item = str;
}
};
栈类主要部分
class Stack
{
private:
Node *Head;
int N;
public:
Stack()
{
Head = new Node(NULL, "");
N = 0;
}
string pop() //出栈
{
if (isEmpty())
{
return "";
}
Node* first_node = Head->Next;
Head->Next = first_node->Next;
N--;
return first_node->item;
}
void push(string str) //入栈
{
Node* first_node = Head->Next;
Node* new_node = new Node(first_node, str);//new_node->Next=first_node;
Head->Next = new_node;
N++;
return;
}
……
一些辅助函数:
全出栈函数与展示函数
void bounce()
{
int count = N;
cout << "出栈清空进行:" << endl;
for (int i = 0; i < count; i++)
{
cout << "当前元素量为:" << N << endl;
cout << "出栈元素:" << pop() << endl;//pop()在上块代码有定义
}
}
void disAll()
{
Node* n = Head->Next;
cout << "当前栈内记录:" << endl;
while (n!= NULL)
{
cout << n->item << endl;
n = n->Next;
}
}
实现验证与结果:
int main()
{
Stack stack;
stack.push("str1");
stack.push("str2");
stack.push("str3");
stack.push("str4");
stack.push("str5");
stack.disAll();
stack.bounce();
stack.disAll();
}
运行结果:
当前栈内记录:
str5
str4
str3
str2
str1
出栈清空进行:
当前元素量为:5
出栈元素:str5
当前元素量为:4
出栈元素:str4
当前元素量为:3
出栈元素:str3
当前元素量为:2
出栈元素:str2
当前元素量为:1
出栈元素:str1
当前栈内记录:
栈通常用于实现函数调用、表达式求值、括号匹配等算法。
2.括号匹配
判断一串字符串中括号的使用是否正确,左括号是否有对应数量的右括号。
主要思路,遍历每一个字符,对"("与")"进行操作。因为左括号在右括号的左边(废话),那么当遍历到左括号时便把它存入栈中,遇到右括号时便从栈中出栈一个元素,不是左括号或遍历完成后左括号有剩余都判断括号使用错误。
匹配函数:
bool isMatch(string str)
{
const char* ch;
ch = str.c_str(); //转字符便于遍历
for (int i = 0; ch[i] != '\0]'; i++)
{
if (ch[i] == ')')
{
if (pop() != "(") //判断出栈元素
{
return false;
}
}
if (ch[i] == '(') //进栈左括号
{
push("(");
}
}
if (isEmpty()) //是否剩余左括号
{
return true;
}
return false;
}
实现验证与结果:
int main()
{
Stack stack;
string str = "(abc)(de)g)(";
cout << "括号匹配结果:"<<stack.isMatch(str);
}
运行结果:
括号匹配结果:0