数据结构 - 栈和队列
Posted 123zhh-helloworld
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 - 栈和队列相关的知识,希望对你有一定的参考价值。
数据结构 - 栈和队列
介绍
- 栈和队列是两种很简单, 但也很重要的数据结构, 在之后的内容也会用到的
- 栈的特点就是FILO(first in last out)
- 而队列则是FIFO(first in first out)
栈和队列也是列表
- 栈和队列都可以认为是链表, 只是插入删除的方式做了改变
- 栈的插入删除都在尾部, 如果是头插法的话, 则是在头部
- 队列的插入在尾部, 删除在头部
栈的两种实现方式
数组
- 第一种 - 数组, 对于知道了栈最大长度的情况, 我建议用数组
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MaxLength = 10000 + 20; 4 5 struct Stack { 6 int s[MaxLength]; 7 int index; 8 9 Stack():index(0){} 10 bool Empty(){ return index == 0; } 11 void Push(int d){ s[index++] = d; } 12 void Pop(){ 13 if (index) --index; 14 else printf("Stack is Empty! "); 15 } 16 int Top(){ 17 if (index) return s[index - 1]; 18 else { 19 printf("Stack is Empty!!! "); 20 return -1; 21 } 22 } 23 void Clear(){ index = 0; } 24 void Print() { 25 for (int i = 0; i < index - 1; i++) 26 printf("%d ", s[i]); 27 if (index) printf("%d ", s[index - 1]); 28 } 29 }; 30 31 int main () { 32 int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 33 Stack myStack; 34 for (int i = 0; i < 10; i++) myStack.Push(a[i]); 35 36 myStack.Print(); 37 myStack.Push(11); 38 myStack.Print(); 39 printf("top = %d ", myStack.Top()); 40 myStack.Pop(); 41 myStack.Pop(); 42 myStack.Pop(); 43 myStack.Print(); 44 myStack.Clear(); 45 myStack.Pop(); 46 myStack.Top(); 47 return 0; 48 }
链表
- 第二种 - 链表, 对于不知道最大长度情况可以用
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 struct Node { 5 int data; 6 Node *next; 7 Node(int d, Node *nxt = nullptr):data(d), next(nxt){} 8 }; 9 10 ///创建栈, 并用头插法插入dat的前n个元素 11 Node* Create(int n, int dat[]) { 12 Node *head = new Node(-1); 13 14 for (int i = 0; i < n; i++) { 15 head -> next = new Node(dat[i], head -> next); 16 } 17 return head; 18 } 19 20 ///在栈的头部添加dat 21 void Push(Node *head, int dat) { 22 head -> next = new Node(dat, head -> next); 23 } 24 25 ///判断栈是否为空 26 bool Empty(Node *head) { 27 return head -> next == nullptr; 28 } 29 30 ///弹出栈的第一个元素-栈顶元素 31 void Pop(Node *head) { 32 if (head -> next) head -> next = head -> next -> next; 33 else printf("栈已为空, 无法再弹出元素! "); 34 } 35 36 ///返回栈顶元素, 不删除 37 int Top(Node *head) { 38 if (head -> next) return head -> next -> data; 39 else printf("栈已为空, 无栈顶元素! "); 40 } 41 42 ///清空栈 43 void Clear(Node *head) { 44 head -> next = nullptr; 45 } 46 47 ///输出栈, 由于是头插法, 所以这里用一下递归 48 ///递归其实也用到了栈 49 void Print(Node *head) { 50 if (head -> next) { 51 Print(head -> next); 52 printf(" %d", head -> data); 53 } else printf("%d", head -> data); 54 } 55 56 ///用这个函数补一个回车 57 void PrintStack(Node *head) { 58 Print(head -> next); 59 printf(" "); 60 } 61 62 int main () { 63 int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 64 Node *head = Create(10, a); 65 PrintStack(head); 66 Push(head, 11); 67 PrintStack(head); 68 printf("top = %d ", Top(head)); 69 Pop(head); 70 Pop(head); 71 Pop(head); 72 PrintStack(head); 73 Clear(head); 74 Pop(head); 75 Top(head); 76 return 0; 77 }
队列的两种实现方式
数组
- 第一种, 数组, 在知道队列最大长度时, 使用数组会很简单
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MaxLength = 10000 + 20; 4 5 struct Queue { 6 int myQueue[MaxLength]; 7 int head, tail; 8 9 Queue():head(0), tail(0){} 10 11 bool Empty() { 12 return head == tail; 13 } 14 15 void Push(int dat) { 16 myQueue[tail++] = dat; 17 } 18 19 void Pop() { 20 if (head != tail) head++; 21 else printf("This Queue is Empty!! "); 22 } 23 24 void Clear() { 25 head = tail = 0; 26 } 27 28 int Front() { 29 if (!Empty()) return myQueue[head]; 30 else printf("The Queue is Empty! "); 31 } 32 33 void Print() { 34 if (Empty()) printf("Queue is Empty!!! "); 35 else { 36 for (int i = head; i < tail - 1; i++) printf("%d ", myQueue[i]); 37 printf("%d ", myQueue[tail - 1]); 38 } 39 } 40 }; 41 42 int main () { 43 int a[10] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 4}; 44 Queue Q; 45 for (int i = 0; i <10; i++) Q.Push(a[i]); 46 Q.Print(); 47 printf("front is : %d ", Q.Front()); 48 49 Q.Pop(); Q.Pop(); Q.Pop(); 50 Q.Print(); 51 52 Q.Clear(); 53 Q.Print(); 54 55 return 0; 56 }
链表
- 第二种, 链表, 在不知道队列最大长度时可以使用, 我觉得很麻烦
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 struct Node { 5 int data; 6 Node *next; 7 Node(int d, Node *nxt = nullptr):data(d), next(nxt){} 8 }; 9 10 Node* CreateQueue(int n, int dat[]) { 11 Node *head = new Node(-1); 12 Node *temp = head; 13 14 for (int i = 0; i < n; i++) { 15 temp -> next = new Node(dat[i]); 16 temp = temp -> next; 17 } 18 return head; 19 } 20 21 void Push(Node *head, int dat) { 22 Node *temp = head; 23 while (temp -> next) temp = temp -> next; 24 temp -> next = new Node(dat); 25 } 26 27 bool Empty(Node *head) { 28 return head -> next == nullptr; 29 } 30 31 void Pop(Node *head) { 32 if (head -> next) head -> next = head -> next -> next; 33 else printf("This Queue is Empty! "); 34 } 35 36 void Clear(Node *head) { 37 head -> next = nullptr; 38 } 39 40 int Front(Node *head) { 41 if (head -> next) return head -> next -> data; 42 else printf("This Queue is Empty!!! "); 43 } 44 45 void Print(Node *head) { 46 Node *temp = head -> next; 47 if (temp) { 48 while (temp -> next) { 49 printf("%d ", temp -> data); 50 temp = temp -> next; 51 } 52 printf("%d ", temp -> data); 53 } else printf("Queue is Empty! "); 54 } 55 56 int main () { 57 int a[10] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 4}; 58 Node *Q = CreateQueue(10, a); 59 Print(Q); 60 printf("Queue is Empty? : %s ", Empty(Q) ? "true" : "false"); 61 while (!Empty(Q)) Pop(Q); 62 Print(Q); 63 for (int i = 0; i < 10; i++) Push(Q, a[i]); 64 Print(Q); 65 return 0; 66 }
小结
- 对于一个惯用数组的我来说, 我当然是喜欢用数组了, 然而在实际上, 我会直接用STL里面的queue, 栈的话, 我还用得比较少, 队列用得比较多
- 从这个码量都看得出来, 数组实现的栈和队列实在是非常的简单, 所以我觉得只看数组的就够了
以上是关于数据结构 - 栈和队列的主要内容,如果未能解决你的问题,请参考以下文章