赞
踩
五.栈与队列
栈定义:用来存储函数调用时各个函数的参数,返回地址及临时变量等。思路:自定义一个函数模板CQueue,它有public属性或方法:构造函数,析构函数,在尾部添加节点void appendTail(const T& node),删除队列的头节点T deleteHead().私有属性:stack<T> stack1;stack<T>stack2;由于定义CQueue,为模板的原因,在尾部添加节点实现函数为:template< typename T> void cQueue<T>::appendTail(const T& node){stack1.push(node)},删除队列头部的节点template<T> T cQueue<T> ::deleteHead()如果stack2<=0,当stack1.size()满足大于0时,将stack1,中的所有元素压入stack2.如果stack2==0,抛空。定义一个T类型的head并且赋初值为stack2.top,stack2.pop(),返回Head。
- #include <iostream>
- #include <stack>
- #include <exception>
- using namespace std;
-
- template <typename T> class CQueue
- {
- public:
- CQueue(void);
- ~CQueue(void);
-
- // 在队列末尾添加一个结点
- void appendTail(const T& node);
-
- // 删除队列的头结点
- T deleteHead();
-
- private:
- stack<T> stack1;
- stack<T> stack2;
- };
-
- //成员函数定义.
- template <typename T>
- CQueue<T>::CQueue(void)
- {
- }
-
- template <typename T>
- CQueue<T>::~CQueue(void)
- {
- }
-
- //向队列中插入元素.
- template <typename T>
- void CQueue<T>::appendTail(const T& node)
- {
- stack1.push(node);
- }
-
- //从队列中删除元素.
- template <typename T>
- T CQueue<T>::deleteHead()
- {
- //先判断stack2是否为空.
- //若其不为空,则从中弹出元素;
- //若为空,则将stack1中元素依次弹出并存入stack2中.
- if(stack2.size() <= 0)
- while (stack1.size() > 0)
- {//当stack2为空时,将stack1中所有元素存入stack2中.
- T data = stack1.top();
- stack1.pop();
- stack2.push(data);
- }
- if(stack2.size() == 0)
- throw new exception("queue is empty!");
-
- T head = stack2.top();
- stack2.pop();
-
- return head;
- }
-
- //测试函数.
- void Test(char actual, char expected)
- {
- if(actual == expected)
- cout << "Test passed." << endl;
- else
- cout << "Test failed.\n" << endl;
- }
-
- int main()
- {
- CQueue<char> queue;
-
- queue.appendTail(‘a‘);
- queue.appendTail(‘b‘);
- queue.appendTail(‘c‘);
-
- char head = queue.deleteHead();
- Test(head, ‘a‘);
-
- head = queue.deleteHead();
- Test(head, ‘b‘);
-
- queue.appendTail(‘d‘);
- head = queue.deleteHead();
- Test(head, ‘c‘);
-
- queue.appendTail(‘e‘);
- head = queue.deleteHead();
- Test(head, ‘d‘);
-
- head = queue.deleteHead();
- Test(head, ‘e‘);
-
- return 0;
- }

总结:
栈:
- #include <stdafx.h>
- #include <stdio.h>
- #include <iostream>
- #include <stack>
- using namespace std;
- int main()
- {
- stack<int> st;
- /*
- 对栈的操作无非就是:验证是否为空、返回栈中元素数目、对栈顶元素删除、获取以及压入新元素
- st.empty(); 验证是否为空
- st.size(); 栈中元素个数
- st.pop(); 删除栈顶元素,无返回值
- st.push(); 将新元素压入栈中
- st.top(); 返回栈顶元素
- st.size()为st对象调用stack类size函数
- st->size()针对于指针对象指向size函数
- */
- if(st.empty()){
- cout<<"stack is empty"<<endl;
- cout<<"刚进行初始化stack的大小: "<<st.size()<<endl; //输出size
- st.push(111);
- st.push(222); //压入栈顶,必须是同类型的int值
- cout<<"push后的stack大小: "<<st.size()<<endl;
- cout<<"取出stack顶元素: "<<st.top()<<endl<<endl;
- //取出stack中所有元素
- while(st.size()>0){
- cout<<st.top()<<endl;
- st.pop();
- //因声明的是stack静态对象st,不用考虑内存泄漏
- }
- cout<<"stack size : "<<st.size()<<endl;
- }
- getchar(); //程序暂停等待用户输入任意字符,让命令行窗口不会一闪而过
- return 0;
- }

队列:
- #include <stdafx.h>
- #include <stdio.h>
- #include <iostream>
- #include <queue>
- using namespace std;
- int main(){
- queue<int> p;
- /*
- q.empty() 如果队列为空
- q.size() 返回队列中元素的个数
- q.pop() 删除队列首元素无返回值
- q.front() 返回队首元素的值,但不删除该元素
- q.push() 在队尾压入新元素
- q.back() 返回队列尾元素的值,但不删除该元素
- */
- if(p.empty()){
- cout<<"pop is empty"<<endl;
- cout<<"刚进行初始化pop的大小: "<<p.size()<<endl; //输出size
- p.push(111);
- p.push(222); //压入栈顶,必须是同类型的int值
- cout<<"push后的pop大小: "<<p.size()<<endl;
- cout<<"取出pop顶元素: "<<p.front()<<endl<<endl;
- //取出pop中所有元素
- while(p.size()>0){
- cout<<p.front()<<endl;
- p.pop();
- //因声明的是pop静态对象p,不用考虑内存泄漏
- }
- cout<<"pop size : "<<p.size()<<endl;
- }
- getchar();
- return 0;
- }

栈的数组实现 (利用栈的基本操作来实现对数组的操作) 栈:后进先出 数组:按 (索引->值) 依次存储
- #include <stdafx.h>
- #include <stdio.h>
- #include <malloc.h>
- #define maxsize 10
- typedef struct //定义结构体,并且在
- {
- int data[maxsize]; //数组大小
- int top; //栈顶坐标
- int base; //栈底坐标
- }seqstack; //seqstack为结构体的别名而已,还可以使用多个别名,且多个别名创建的对象使用的不是同一个内存空间, 并根据数组的结构定义成员
- seqstack * s; //栈
- void initstack(seqstack * s)
- {
- s->top = 0;
- s->base = 0;
- }
- int empty(seqstack * s)
- {
- if(s->top == s->base)
- return 1;
- else
- return 0;
- }
- //入栈:赋值 , 索引++
- void push(seqstack * s, int x)
- {
- if(s->top >= maxsize-1)
- {
- printf("ERROR!\n");
- }
- else
- {
- s->data[s->top] = x;
- s->top++;
- }
- }
- //获取栈顶元素data[s->top--] 这里需要top--是因为入栈时top索引++了
- void pop(seqstack * s)
- {
- if(empty(s))
- {
- printf("ERROR!\n");
- }
- else
- {
- s->top--;
- printf("%d\n",s->data[s->top]);
- }
- }
- int main()
- {
- seqstack * s;
- //(seqstack *)强转,malloc(size)申请大小为size动态内存空间,sizeof(seqstack),seqstack类型占多少字节sizeof的值就是多大,如:sizeof(int) = 4
- s = (seqstack *)malloc(sizeof(seqstack));
- //此时s为空,s为指针对象,会以传址的方式将s传递给initstack函数
- initstack(s);
- push(s,1);
- push(s,3);
- pop(s);
- push(s,2);
- pop(s);
- pop(s);
- pop(s);
- return 0;
- }

栈的链表实现 (利用栈的基本操作来实现对链表的操作)
- #include <stdafx.h>
- #include <stdio.h>
- #include <malloc.h>
- #include <stdlib.h>
- typedef struct node
- {
- int data;
- struct node *next;
- }node,linkstack; //使用多个别名,在这里node为节点
- //初始化
- void InitStack(linkstack * top)
- {
- top->next = NULL;
- }
- //是否为空 只用想想链表的结构就很清楚了,节点与节点之间通过指针关联,只要top->next为NULL即可
- int IsEmpty(linkstack * top)
- {
- if(top->next == NULL) return 1;
- return 0;
- }
- //入栈:新建一个节点赋值,让新节点的next指针指向NUll,栈内top->next指向新节点即可
- int Push(linkstack * top, int x)
- {
- node * p;
- p = (node *)malloc(sizeof(node));
- if(p == NULL) return 0;
- p->data = x;
- p->next = top->next; //top->next = null
- top->next = p;
- return 1;
- }
- //删除栈顶元素:
- int Pop(linkstack * top, int *x)
- {
- node * p;
- if(IsEmpty(top))
- {
- printf("ERROE!\n");
- return 0;
- }
- p = top->next;
- *x = p->data;
- top->next = p->next;
- free(p);
- return 1;
- }
- int main()
- {
- int x;
- linkstack * s;
- s = (linkstack *)malloc(sizeof(linkstack));
- InitStack(s);
- Push(s,1);
- Push(s,3);
- Pop(s,&x);
- printf("%d\n",x);
- Push(s,2);
- Pop(s,&x);
- printf("%d\n",x);
- Pop(s,&x);
- printf("%d\n",x);
- Pop(s,&x);
- return 0;
- }

- #include <stdafx.h>
- #include <stdio.h>
- #include <malloc.h>
- #define maxsize 66 //定义变量
- typedef struct //type define 结构定义
- {
- int data[maxsize];
- int front,rear; //front来记录列首,rear来记录列尾
- }sequeue;
- sequeue *q; //循环链表
- void initqueue(sequeue *q)
- {
- q->front = -1; //q指针指向sequeue对象中的front方法
- q->rear = -1;
- }
- int del(sequeue *q)
- {
- if(q->front == q->rear) //列首列尾元素是否相等,若相等则是空的循环队列和数组
- return NULL;
- else
- {
- q->front++; //->优先级比++大,故先执行->然后++
- return q->data[q->front]; //实现对数组的删除操作,没调用此方法一次就让front记录的值+1
- }
- }
- int insertqueue(sequeue *q,int x) //向队列中插入元素,思路:先判断列尾是否超出maxsize大小,然后让索引rear+1,对应的给数组data[rear+1]赋值,来实现插入
- {
- if(q->rear >= maxsize-1)
- return NULL;
- else
- {
- (q->rear)++; //列尾+1
- q->data[q->rear] = x;
- return 1;
- }
- }
- int empty(sequeue * q) //简单判断队列是否为空,也就是数组data是否为空
- {
- if(q->front == q->rear)
- return 0;
- else
- return 1; //这里也可扩展,返回队列元素大小,前提是需要让rear递增
- }
- void print(sequeue * q) //遍历输出数据元素
- {
- if(q->front == q->rear)
- printf("ERROR!\n");
- else
- {
- while(empty(q))
- {
- q->front++;
- printf("%d\n",q->data[q->front]);
- }
- }
- }
- int main()
- {
- int i;
- sequeue *q;
- q = (sequeue *)malloc(sizeof(sequeue));
- initqueue(q);
- for(i = 0; i < 6; i++)
- insertqueue(q,i);
- printf("front is %d\n\n",del(q));
- printf("Then the last data is:\n");
- print(q);
- return 0;
- }

- #include <stdafx.h>
- #include <stdio.h>
- #include <malloc.h>
- #define maxsize 66 //定义变量
- typedef struct //type define 结构定义
- {
- int data[maxsize];
- int front,rear; //front来记录列首,rear来记录列尾
- }sequeue;
- sequeue *q; //循环链表
- void initqueue(sequeue *q)
- {
- q->front = -1; //q指针指向sequeue对象中的front方法
- q->rear = -1;
- }
- int del(sequeue *q)
- {
- if(q->front == q->rear) //列首列尾元素是否相等,若相等则是空的循环队列和数组
- return NULL;
- else
- {
- q->front++; //->优先级比++大,故先执行->然后++
- return q->data[q->front]; //实现对数组的删除操作,没调用此方法一次就让front记录的值+1
- }
- }
- int insertqueue(sequeue *q,int x) //向队列中插入元素,思路:先判断列尾是否超出maxsize大小,然后让索引rear+1,对应的给数组data[rear+1]赋值,来实现插入
- {
- if(q->rear >= maxsize-1)
- return NULL;
- else
- {
- (q->rear)++; //列尾+1
- q->data[q->rear] = x;
- return 1;
- }
- }
- int empty(sequeue * q) //简单判断队列是否为空,也就是数组data是否为空
- {
- if(q->front == q->rear)
- return 0;
- else
- return 1; //这里也可扩展,返回队列元素大小,前提是需要让rear递增
- }
- void print(sequeue * q) //遍历输出数据元素
- {
- if(q->front == q->rear)
- printf("ERROR!\n");
- else
- {
- while(empty(q))
- {
- q->front++;
- printf("%d\n",q->data[q->front]);
- }
- }
- }
- int main()
- {
- int i;
- sequeue *q;
- q = (sequeue *)malloc(sizeof(sequeue));
- initqueue(q);
- for(i = 0; i < 6; i++)
- insertqueue(q,i);
- printf("front is %d\n\n",del(q));
- printf("Then the last data is:\n");
- print(q);
- return 0;
- }

队列的链表实现 (利用链表的数据结构来实现对队列的操作) 先想想链表的实现原理,要知道链表中某个节点,那就必须要知道它上一个节点
节点: [值 | 指针] (指向下一个节点的内存地址)front -> rear (假设队列顺序从左往右)
- #include <stdafx.h>
- #include <stdio.h>
- #include <malloc.h>
- typedef struct node //节点
- {
- int data; //值
- struct node * next; //指针
- }linklist; //节点对象
- typedef struct
- {
- linklist * front, * rear; //定义结构对象的两个指针,front表示上一个节点,rear表示下一个节点
- }linkqueue;
- linkqueue * q; //链表
- //建立队列
- void initqueue(linkqueue * q)
- {
- q->front = (linkqueue *)malloc(sizeof(linklist)); //动态分配,初始化为0
- q->front->next = NULL; //将首节点中指向下一节点的指针置空
- q->rear = q->front; //队列首位
- }
- //判断队列空否
- int empty(linkqueue * q)
- {
- if(q->front == q->rear)
- return 1;
- else
- return 0;
- }
- //入队列 先定义一个与listlink相同的节点对象,然后再将它加入链表队列中(rear->next指向新建的节点)
- void inqueue(linkqueue * q, int x)
- {
- q->rear->next = (linklist *)malloc(sizeof(linklist)); //q->rear->next本来是NULL的,现在将对它赋予节点对象,也就连接了rear和rear->next
- q->rear->next->data = x;
- q->rear = q->rear->next; //让rear没有下一个节点
- q->rear->next = NULL; //确定操作的rear节点位于链尾
- }
- //出队列 从front节点开始一节一节的取,此方法每调用一个就取一个,一直取到最后一个时,就会一直返回q->rear
- int outqueue(linkqueue * q)
- {
- linklist * s;
- if(empty(q))
- return NULL;
- else
- {
- s = q->front->next;
- printf("%d\n",s->data);
- if(s == q->rear)
- q->front = q->rear;
- else
- q->front->next = s->next;
- free(s);
- return 1;
- }
- }
- //main
- int main()
- {
- int i;
- linkqueue * l;
- l = (linkqueue *)malloc(sizeof(linkqueue));
- initqueue(l);
- for(i = 0; i < 10; i++)
- inqueue(l,i);
- for(i = 0; i < 10; i++)
- outqueue(l);
-
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。