Data Structures & Algorithm Lecture 4
Information
- date: 2024.07.26
- time: 09:29
Index
Content
Performance and Limitations
Performance
- Let n be the number of elements in the stack
- The space used is
O(n)
- Each operation runs in constant time, O(1)
Limitations
- The maximum size of the stack must be defined a priori and can’t be changed
- Trying to push a new element into a full stack causes an implementation-specific error
Advantages
Reversal of an Array Using Stack
What We Are Trying to Do
We are trying to reverse an array using a stack for efficient memory management.
Process
First, push all the elements to a stack using a loop. For example, with A[5] = {1,2,3,4,5}
:
Code
77777777777
Logic
Imagine the array elements as a stacked up paper. ( Notice the word Stack ). The last paper is on the top since first goes first down and second goes second and vice versa. So 1 is on surface, 2 is on 1 … 5 is on 4. This is your array.
now take the top 5 ( s.push(a[5])) put it in another stack. Now 5 is ur first element. We are already going in track with what we wanted to do. Now do same for 4 now 5 is on surface and 4 is on top of 5. You do this till u reach the last element.
ReverseArrayUsingStack.excalidraw
⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠ You can decompress Drawing data with the command palette: ‘Decompress current Excalidraw file’. For more info check in plugin settings under ‘Saving’
Excalidraw Data
Text Elements
I = 4
I = 3
…
I = 0
Your array
Empty / Surface
Taking the last element And putting it in a stack
T = -1
T = 0
T = 1
…
T = 4
After that we keep taking one element and adding it to the stack we get this reversed Stack
`
T = -1
T = 0
T = 1
…
T = 4
1
2
3
4
5
5
4
3
2
1
1
Before getting confused read the indexing…
Memory Representation of Array = {1,2,3,4,5}
Take the Top Element and add it in an array in the first index.
I = 4
I = 3
…
I = 0
5
Memory Representation of Array = {5, … }
1
2
3
4
5
I = 4
I = 3
…
I = 0
{5,4,3,2,1}
Resultant Array
Link to original
Decimal to Binary Conversion
What We Are Trying to Do
Convert a decimal number into binary by dividing the number by two and storing the remainder.
Process
#include <stack>
#include <iostream>
int main() {
int dec = 256;
std::stack<int> s;
while (dec > 0) {
int digit = dec % 2;
s.push(digit);
dec /= 2;
}
while (!s.empty()) {
std::cout << s.top();
s.pop();
}
return 0;
}
Binary To Decimal.excalidraw
⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠ You can decompress Drawing data with the command palette: ‘Decompress current Excalidraw file’. For more info check in plugin settings under ‘Saving’
Excalidraw Data
Text Elements
Convert 256 Base 10 to Binary
T = -1
T = 0
T = 1
…
T = 4
0
Formula for one digit is number%2 Push the remainder in stack store the quotient in the same variable again
256%2=0 Push 0 Var = 256/2=128
128%2=0 Push 0 Var = 128/2=64
64%2=0 Push 0 Var 64/2=32
32%2=0; Push 0 Var 32/2=16
16%2=0
Push 0
Var 16/2=8
8%2=0
Push 0
Var = 8/2=4
4%2=0
Push 0
Var = 4/2=2
2%2=0
Push 0
Var = 2/2=1
1%2=1
Push 1
Var = 1/2=0 (Stop here, as Var = 0)
0
0
0
0
0
0
0
1
T = 9
…
T = -1
T = 0
T = 1
…
T = 4
0
0
0
0
0
0
0
0
1
T = 9
…
Result Stack. Pop the top one by one and then stick it in an array or a number Result will be 100000000
Link to original
Parenthesis Matching
What We Are Doing
- Checking if each opening parenthesis has a corresponding closing parenthesis.
- Ensuring the number of opening and closing parentheses match.
- Detecting mismatched parentheses.
Solution
#include <iostream>
#include <stack>
#include <map>
bool isBalanced(const std::string& expr) {
std::stack<char> s;
std::map<char, char> par = {{')', '('}, {']', '['}, {'}', '{'}, {'>', '<'}};
std::string open = "([{<";
for (char ch : expr) {
if (open.find(ch) != std::string::npos) {
s.push(ch);
} else if (par.find(ch) != par.end()) {
if (s.empty() || s.top() != par[ch]) {
return false;
}
s.pop();
}
}
return s.empty();
}
int main() {
std::string expr;
std::cout << "Enter the string to check for balancing: ";
std::cin >> expr;
if (isBalanced(expr)) {
std::cout << "Balanced\n";
} else {
std::cout << "Not Balanced\n";
}
return 0;
}
For eveery character in the expression check if that character exists in the open string if it does push in stack If else
HTML Tag Matching
What We Are Doing
Checking if HTML tags are properly nested and matched.
Solution
#include <iostream>
#include <stack>
#include <string>
bool isHTMLBalanced(const std::string& html) {
std::stack<std::string> s;
size_t pos = 0;
while (pos < html.size()) {
if (html[pos] == '<') {
size_t end = html.find('>', pos);
if (end == std::string::npos) {
return false;
}
std::string tag = html.substr(pos, end - pos + 1);
if (tag[1] != '/') {
s.push(tag);
} else {
if (s.empty() || s.top().substr(1) != tag.substr(2)) {
return false;
}
s.pop();
}
pos = end + 1;
} else {
pos++;
}
}
return s.empty();
}
int main() {
std::string html;
std::cout << "Enter the HTML string to check for balancing: ";
std::cin >> html;
if (isHTMLBalanced(html)) {
std::cout << "Balanced\n";
} else {
std::cout << "Not Balanced\n";
}
return 0;
}
Conversion of Arithmetic Expressions
Infix to Postfix Conversion
#include <iostream>
#include <stack>
#include <string>
int precedence(char op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
return 0;
}
std::string infixToPostfix(const std::string& infix) {
std::stack<char> s;
std::string postfix;
for (char ch : infix) {
if (isdigit(ch)) {
postfix += ch;
} else if (ch == '(') {
s.push(ch);
} else if (ch == ')') {
while (!s.empty() && s.top() != '(') {
postfix += s.top();
s.pop();
}
s.pop();
} else {
while (!s.empty() && precedence(s.top()) >= precedence(ch)) {
postfix += s.top();
s.pop();
}
s.push(ch);
}
}
while (!s.empty()) {
postfix += s.top();
s.pop();
}
return postfix;
}
int main() {
std::string infix = "3+(2*4)-5";
std::cout << "Postfix: " << infixToPostfix(infix) << std::endl;
return 0;
}
Evaluation of Arithmetic Expressions
Evaluating Postfix Expression
#include <iostream>
#include <stack>
#include <string>
int evaluatePostfix(const std::string& postfix) {
std::stack<int> s;
for (char ch : postfix) {
if (isdigit(ch)) {
s.push(ch - '0');
} else {
int val2 = s.top(); s.pop();
int val1 = s.top(); s.pop();
switch (ch) {
case '+': s.push(val1 + val2); break;
case '-': s.push(val1 - val2); break;
case '*': s.push(val1 * val2); break;
case '/': s.push(val1 / val2); break;
}
}
}
return s.top();
}
int main() {
std::string postfix = "324*+5-";
std::cout << "Result: " << evaluatePostfix(postfix) << std::endl;
return 0;
}
Traversal Algorithm
DFS Traversal using Stack
#include <iostream>
#include <stack>
#include <vector>
void DFS(int start, const std::vector<std::vector<int>>& adj) {
std::vector<bool> visited(adj.size(), false);
std::stack<int> s;
s.push(start);
while (!s.empty()) {
int node = s.top();
s.pop();
if (!visited[node]) {
visited[node] = true;
std::cout << node << " ";
for (int neighbor : adj[node]) {
if (!visited[neighbor]) {
s.push(neighbor);
}
}
}
}
}
int main() {
std::vector<std::vector<int>> adj = {
{1, 2},
{0, 3, 4},
{0, 5, 6},
{1},
{1},
{2},
{2}
};
DFS(0, adj);
return 0;
}
Function Invocations
Recursion
Recursion is a function calling itself directly or indirectly to solve a problem. It can be used in various algorithms such as tree traversals, sorting, and more.