栈与队列的算法总结
- 栈与队列实现
- 含有最小值的栈
- 两个栈实现队列
- 一个栈排序另一个栈
含有最小值的栈
思路:用一个辅助栈来记录主栈的最小值,对于主栈来说有两种操作:插入,弹出。
插入:当向主栈插入元素时,有三种情况:
- 1.当向主栈插入元素后,如果辅助栈为空,则直接将此元素插入辅助栈顶。
- 2.当向主栈插入元素后,辅助栈不为空,需要判断辅助栈栈顶元素与插入元素大小,如果辅助栈栈顶元素大于插入元素,则将插入元素插入到辅助栈栈顶。
- 3.如果辅助栈栈顶元素小于或者等于插入元素,则把辅助栈栈顶元素插入到辅助栈的栈顶。
如图,stockData为主栈,stackMin为辅助栈,当向主栈插入元素时:
弹出:当弹出主栈元素时,辅助栈也需要弹出元素。
#include#include<malloc.h> //声明链表节点类型 typedef struct LISTtag LISTtagNode; struct LISTtag{ int value; LISTtagNode *next; }; int size=0; int sizeminor = 0; //创建链表 LISTtagNode * create(){ LISTtagNode *head; head = (LISTtagNode*)malloc(sizeof(LISTtagNode)); head->next = NULL; return head; } //在链表头新增节点 int push(LISTtagNode *head,int value){ if(head == NULL){ return -1; } //新建节点 LISTtagNode *node; node = (LISTtagNode*)malloc(sizeof(LISTtagNode)); //节点赋值,此节点跟在头节点后 node->value = value; node->next = head->next; head->next = node; size++; return 1; } //打印链表 int PrindLinKList(LISTtagNode *head){ if(head == NULL){ return -1; } printf("\n "); LISTtagNode *t = head; while (t->next != NULL) { t = t->next; printf("%d ", t->value); } return 1; } int pop(LISTtagNode *head){ if(head ==NULL){ return -1; } LISTtagNode *node; int index = 0; while(head->next!=NULL&&index<1){ node = head->next; index++; } if(index == 1){ printf("\n主栈弹出元素:%d \n",node->value); if(head->next->next != NULL){ head->next = head->next->next; }else{ head->next =NULL; } free(node); size--; return 1; } return -1; } //打印栈顶元素 int top(LISTtagNode *head){ if(head ==NULL){ return -1; } LISTtagNode *node; int index = 0; while(head->next!=NULL&&index<1){ node = head->next; index++; } if(index == 1){ printf("\n栈顶元素:%d\n",node->value); return 1; } return -1; } int empty(LISTtagNode *head){ if(head ==NULL){ return -1; } if(head->next!=NULL){ return 0; } return 1; } //链表长度 int length(LISTtagNode *head){ if(head ==NULL){ return -1; } return size; } //在链表头新增节点 int pushminor(LISTtagNode *head,int value){ if(head == NULL){ return -1; } if(head->next ==NULL){ //新建节点 LISTtagNode *node; node = (LISTtagNode*)malloc(sizeof(LISTtagNode)); //节点赋值,此节点跟在头节点后 node->value = value; node->next = head->next; head->next = node; sizeminor++; return 1; }else{ if(head->next->value >= value){ //新建节点 LISTtagNode *node; node = (LISTtagNode*)malloc(sizeof(LISTtagNode)); //节点赋值,此节点跟在头节点后 node->value = value; node->next = head->next; head->next = node; sizeminor++; return 1; }else{ //新建节点 LISTtagNode *node; node = (LISTtagNode*)malloc(sizeof(LISTtagNode)); //节点赋值,此节点跟在头节点后 node->value = head->next->value; node->next = head->next; head->next = node; sizeminor++; return 1; } } } int popminor(LISTtagNode *head){ if(head ==NULL){ return -1; } LISTtagNode *node; int index = 0; while(head->next!=NULL&&index<1){ node = head->next; index++; } if(index == 1){ printf("辅助栈弹出元素:%d\n",node->value); if(head->next->next != NULL){ head->next = head->next->next; }else{ head->next =NULL; } free(node); sizeminor--; return 1; } return -1; } int main () { //主栈 LISTtagNode *head = create(); //辅助栈 LISTtagNode *headminor = create(); //向链表插入元素 push(head,7); pushminor(headminor,7); //PrindLinKList(headminor); top(headminor); //向主栈插入元素 push(head,9); //向辅助栈插入元素 pushminor(headminor,9); //打印辅助栈的栈顶元素,就是最小值 top(headminor); //向链表插入元素 push(head,23); pushminor(headminor,23); top(headminor); //向链表插入元素 push(head,2); pushminor(headminor,2); top(headminor); //弹出链表元素 pop(head); popminor(headminor); top(headminor); return 0; }
一个栈排序另一个栈
思路:需要排序的栈称为主栈,记录排序结果的栈为辅助栈。
每次从主栈弹出一个元素,与辅助栈栈顶元素比较,这里有一个特殊情况,就是辅助栈为空,如果辅助栈为空,则将主栈弹出的元素压入辅助栈。
如果辅助栈不为空,则比较:
- 如果主栈弹出的元素小于或者等于辅助栈栈顶元素,则将主栈元素压入辅助栈。
- 如果主栈弹出的元素大于辅助栈的元素,则将辅助栈的元素逐一弹出并压入到主栈,直到刚开始主栈弹出来的元素小于或者等于辅助栈栈顶元素时,再将主栈弹出来的元素压入辅助栈。
排序代码:
int sort(LISTtagNode *head,LISTtagNode *headminor){ if(head ==NULL || headminor == NULL){ return -1; } int Value; while(head->next!=NULL){ Value = head->next->value; if(headminor->next ==NULL){ push(headminor,Value); pop(head); } else{ pop(head); int valuetemp; LISTtagNode *nodetemp; nodetemp = headminor->next; //如果Value大于辅助栈栈顶元素: if(Value>nodetemp->value){ while((Value)>(nodetemp->value)&&(nodetemp->next !=NULL)){ valuetemp = nodetemp->value; push(head,valuetemp); nodetemp = nodetemp->next; popminor(headminor); } if(Value>nodetemp->value){ push(head,nodetemp->value); popminor(headminor); } push(headminor,Value); //如果Value小于或者等于辅助栈栈顶元素: }else{ push(headminor,Value); } } } return 1; }
#include#include<malloc.h> //声明链表节点类型 typedef struct LISTtag LISTtagNode; struct LISTtag{ int value; LISTtagNode *next; }; int size=0; //创建链表 LISTtagNode * create(){ LISTtagNode *head; head = (LISTtagNode*)malloc(sizeof(LISTtagNode)); head->next = NULL; return head; } //在链表头新增节点 int push(LISTtagNode *head,int value){ if(head == NULL){ return -1; } //新建节点 LISTtagNode *node; node = (LISTtagNode*)malloc(sizeof(LISTtagNode)); //节点赋值,此节点跟在头节点后 node->value = value; node->next = head->next; head->next = node; size++; return 1; } //打印链表 int PrindLinKList(LISTtagNode *head){ if(head == NULL){ return -1; } printf("\n "); LISTtagNode *t = head; while (t->next != NULL) { t = t->next; printf("%d ", t->value); } return 1; } int pop(LISTtagNode *head){ if(head ==NULL){ return -1; } LISTtagNode *node; int index = 0; while(head->next!=NULL&&index<1){ node = head->next; index++; } if(index == 1){ printf("\n主栈弹出元素:%d \n",node->value); if(head->next->next != NULL){ head->next = head->next->next; }else{ head->next =NULL; } free(node); size--; return 1; } return -1; } int popminor(LISTtagNode *head){ if(head ==NULL){ return -1; } LISTtagNode *node; int index = 0; while(head->next!=NULL&&index<1){ node = head->next; index++; } if(index == 1){ printf("\n辅助栈弹出元素:%d \n",node->value); if(head->next->next != NULL){ head->next = head->next->next; }else{ head->next =NULL; } free(node); size--; return 1; } return -1; } //打印栈顶元素 int top(LISTtagNode *head){ if(head ==NULL){ return -1; } LISTtagNode *node; int index = 0; while(head->next!=NULL&&index<1){ node = head->next; index++; } if(index == 1){ printf("\n栈顶元素:%d\n",node->value); return 1; } return -1; } int empty(LISTtagNode *head){ if(head ==NULL){ return -1; } if(head->next!=NULL){ return 0; } return 1; } //链表长度 int length(LISTtagNode *head){ if(head ==NULL){ return -1; } return size; } //在链表头新增节点 int pushminor(LISTtagNode *head,int value){ if(head == NULL){ return -1; } if(head->next ==NULL){ //新建节点 LISTtagNode *node; node = (LISTtagNode*)malloc(sizeof(LISTtagNode)); //节点赋值,此节点跟在头节点后 node->value = value; node->next = head->next; head->next = node; return 1; }else{ if(head->next->value >= value){ //新建节点 LISTtagNode *node; node = (LISTtagNode*)malloc(sizeof(LISTtagNode)); //节点赋值,此节点跟在头节点后 node->value = value; node->next = head->next; head->next = node; return 1; }else{ //新建节点 LISTtagNode *node; node = (LISTtagNode*)malloc(sizeof(LISTtagNode)); //节点赋值,此节点跟在头节点后 node->value = head->next->value; node->next = head->next; head->next = node; return 1; } } } int sort(LISTtagNode *head,LISTtagNode *headminor){ if(head ==NULL || headminor == NULL){ return -1; } int Value; while(head->next!=NULL){ Value = head->next->value; if(headminor->next ==NULL){ push(headminor,Value); pop(head); } else{ pop(head); int valuetemp; LISTtagNode *nodetemp; nodetemp = headminor->next; //如果Value大于辅助栈栈顶元素: if(Value>nodetemp->value){ while((Value)>(nodetemp->value)&&(nodetemp->next !=NULL)){ valuetemp = nodetemp->value; push(head,valuetemp); nodetemp = nodetemp->next; popminor(headminor); } if(Value>nodetemp->value){ push(head,nodetemp->value); popminor(headminor); } push(headminor,Value); //如果Value小于或者等于辅助栈栈顶元素: }else{ push(headminor,Value); } } } return 1; } int main () { //主栈 LISTtagNode *head = create(); //辅助栈 LISTtagNode *headminor = create(); push(head,2); push(head,5); push(head,32); push(head,22); push(head,6); push(head,1); push(head,3); PrindLinKList(head); sort(head,headminor); PrindLinKList(headminor); return 0; }
分析:
1.每次从主栈弹出一个元素,直到主栈元素弹完。
while(head->next!=NULL){ //。。。 }
2.辅助栈为空。
if(headminor->next ==NULL){ push(headminor,Value); pop(head); }
3.弹出主栈元素。
pop(head);
4.当主栈弹出的元素大于辅助栈的元素,则将辅助栈的元素逐一弹出并压入到主栈,直到刚开始主栈弹出来的元素小于或者等于辅助栈栈顶元素时,再将主栈弹出来的元素压入辅助栈。
//如果Value大于辅助栈栈顶元素: if(Value>nodetemp->value){ while((Value)>(nodetemp->value)&&(nodetemp->next !=NULL)){ valuetemp = nodetemp->value; push(head,valuetemp); nodetemp = nodetemp->next; popminor(headminor); } if(Value>nodetemp->value){ //这里是为了判断辅助栈最后一个元素是否也满足条件 push(head,nodetemp->value); popminor(headminor); } push(headminor,Value); //最后将主栈元素压入辅助栈
5.主栈弹出的元素小于或者等于辅助栈栈顶元素,则将主栈元素压入辅助栈。
//如果Value小于或者等于辅助栈栈顶元素: }else{ push(headminor,Value); }