数据结构:使用C++模板设计顺序栈和队列的抽象数据类型(ADT),结构体型,类型,链栈和链队列的实现
模板设计顺序栈和队列的抽象数据类型(ADT),结构体型,类型,链栈和链队列的实现
一、栈
1、Struct:
1 /***顺序栈的实现***/ 2 3 //顺序栈定义 4 #define OK 1 5 #define ERROR 0 6 #define OVERFLOW -2 7 #define MAXSIZE 100//顺序栈存储空间的初始分配量 8 typedef int Status; 9 typedef int SElemType; 10 11 typedef struct { 12 SElemType *base;//栈底指针 13 SElemType *top;//栈顶指针 14 int stacksize;//栈可用的最大容量 15 } SqStack; 16 17 //算法3.1 顺序栈的初始化 18 Status InitStack(SqStack &S) { 19 //构造一个空栈S 20 S.base = new SElemType[MAXSIZE];//为顺序栈动态分配一个最大容量为MAXSIZE的数组空间 21 if (!S.base) 22 return OVERFLOW; //存储分配失败 23 S.top = S.base; //top初始为base,空栈 24 S.stacksize = MAXSIZE; //stacksize置为栈的最大容量MAXSIZE 25 return OK; 26 } 27 //算法3.2 顺序栈的入栈 28 Status Push(SqStack &S, SElemType e) { 29 // 插入元素e为新的栈顶元素 30 if (S.top - S.base == S.stacksize) 31 return ERROR; //栈满 32 *(S.top++) = e; //元素e压入栈顶,栈顶指针加1 33 return OK; 34 } 35 //算法3.3 顺序栈的出栈 36 Status Pop(SqStack &S, SElemType &e) { 37 //删除S的栈顶元素,用e返回其值 38 if (S.base == S.top) 39 return ERROR;//栈空 40 e = *(--S.top); //栈顶指针减1,将栈顶元素赋给e 41 return OK; 42 } 43 //算法3.4 取顺序栈的栈顶元素 44 SElemType GetTop(SqStack S) {//返回S的栈顶元素,不修改栈顶指针 45 if (S.top != S.base) //栈非空 46 return *(S.top - 1); //返回栈顶元素的值,栈顶指针不变 47 } 48 bool StackEmpty( SqStack S ) 49 { 50 if(S.top == S.base) return true; 51 else return false; 52 } 53 int StackLength( SqStack S ) 54 { 55 return S.top - S.base; 56 } 57 Status ClearStack( SqStack S ) 58 { 59 if( S.base ) S.top = S.base; 60 return OK; 61 } 62 Status DestroyStack( SqStack &S ) 63 { 64 if( S.base ) 65 { 66 delete S.base ; 67 S.stacksize = 0; 68 S.base = S.top = NULL; 69 } 70 return OK; 71 }
2、Class
1 /***顺序栈的实现***/ 2 #include<iostream> 3 using namespace std; 4 //顺序栈定义 5 #define OK 1 6 #define ERROR 0 7 #define OVERFLOW -2 8 #define MAXSIZE 100//顺序栈存储空间的初始分配量 9 typedef int Status; 10 11 template<class SElemType> 12 class SqStack 13 { 14 private: 15 SElemType *base;//栈底指针 16 SElemType *top;//栈顶指针 17 int stacksize;//栈可用的最大容量 18 public: 19 SqStack(); 20 Status Push(SElemType e); 21 Status Pop(SElemType &e); 22 ~SqStack( ); 23 //重载函数:赋值 24 SqStack<SElemType> operator=(SqStack<SElemType> &s); 25 //拷贝构造函数 26 SqStack(const SqStack<SElemType> &s); 27 28 SElemType GetTop() //返回S的栈顶元素,不修改栈顶指针 29 { 30 if (top != base) //栈非空 31 return *(top - 1); //返回栈顶元素的值,栈顶指针不变 32 } 33 bool StackEmpty( ) 34 { 35 if(top == base) 36 return true; 37 else 38 return false; 39 } 40 int StackLength( ) 41 { 42 return top - base; 43 } 44 Status ClearStack( ) 45 { 46 if( base ) 47 top = base; 48 return OK; 49 } 50 } ; 51 52 template<class SElemType> 53 SqStack<SElemType>::SqStack() 54 { 55 //构造一个空栈S 56 base = new SElemType[MAXSIZE];//为顺序栈动态分配一个最大容量为MAXSIZE的数组空间 57 top = base; //top初始为base,空栈 58 stacksize = MAXSIZE; //stacksize置为栈的最大容量MAXSIZE 59 } 60 template<class SElemType> 61 Status SqStack<SElemType>::Push(SElemType e) 62 { 63 // 插入元素e为新的栈顶元素 64 if (top - base == stacksize) 65 return ERROR; //栈满 66 *(top++) = e; //元素e压入栈顶,栈顶指针加1 67 return OK; 68 } 69 template<class SElemType> 70 Status SqStack<SElemType>::Pop(SElemType &e) 71 { 72 //删除S的栈顶元素,用e返回其值 73 if (base == top) 74 return ERROR;//栈空 75 e = *(--top); //栈顶指针减1,将栈顶元素赋给e 76 return OK; 77 } 78 79 template<class SElemType> 80 SqStack<SElemType>::~SqStack( ) 81 { 82 if( base ) 83 { 84 delete []base ; 85 } 86 } 87 //重载函数:赋值 88 template<class SElemType> 89 SqStack<SElemType> SqStack<SElemType>::operator=(SqStack<SElemType> &s) 90 { 91 base = new SElemType[MAXSIZE];//为顺序栈动态分配一个最大容量为MAXSIZE的数组空间 92 top = base+s.StackLength(); 93 for(int i=0; i<s.StackLength(); i++) 94 { 95 base[i]=s.base[i]; 96 } 97 stacksize = MAXSIZE; //stacksize置为栈的最大容量MAXSIZE 98 return *this; 99 } 100 //拷贝构造函数 101 template<class SElemType> 102 SqStack<SElemType>::SqStack(const SqStack<SElemType> &s) 103 { 104 base = new SElemType[MAXSIZE];//为顺序栈动态分配一个最大容量为MAXSIZE的数组空间 105 top = base+s.StackLength(); 106 for(int i=0; i<s.StackLength(); i++) 107 { 108 base[i]=s.base[i]; 109 } 110 stacksize = MAXSIZE; //stacksize置为栈的最大容量MAXSIZE 111 }
3、Link
1 /***链栈的实现***/ 2 #include<iostream> 3 4 #define OK 1 5 #define ERROR 0 6 #define OVERFLOW -2 7 typedef int Status; 8 typedef char SElemType; 9 10 typedef struct StackNode { 11 SElemType data; 12 struct StackNode *next; 13 } StackNode, *LinkStack; 14 15 //算法3.5 链栈的初始化 16 Status InitStack(LinkStack &S) { // 构造一个空栈 S,栈顶指针置空 17 S = NULL; 18 return OK; 19 } 20 21 //算法3.6 链栈的入栈 22 Status Push(LinkStack &S, SElemType e) {//在栈顶插入元素e 23 LinkStack p; 24 p = new StackNode; //生成新结点 25 p->data = e; //将新结点数据域置为e 26 p->next = S; //将新结点插入栈顶 27 S = p; //修改栈顶指针为p 28 return OK; 29 } 30 31 //算法3.7 链栈的出栈 32 Status Pop(LinkStack &S, SElemType &e) {//删除S的栈顶元素,用e返回其值 33 LinkStack p; 34 if (S == NULL) 35 return ERROR; //栈空 36 e = S->data; //将栈顶元素赋给e 37 p = S; //用p临时保存栈顶元素空间,以备释放 38 S = S->next; //修改栈顶指针 39 delete p; //释放原栈顶元素的空间 40 return OK; 41 } 42 //算法3.8 取链栈的栈顶元素 43 SElemType GetTop(LinkStack S) {//返回S的栈顶元素,不修改栈顶指针 44 if (S != NULL) //栈非空 45 return S->data; //返回栈顶元素的值,栈顶指针不变 46 } 47 bool StackEmpty(LinkStack S) { 48 if (!S) 49 return true; 50 return false; 51 }
二、队列
1、Struct
1 /***循环队列基本操作***/ 2 3 #define MAXQSIZE 100 4 #define OK 1 5 #define ERROR 0 6 #define OVERFLOW -2 7 typedef char QElemType; 8 typedef int Status; 9 10 typedef struct { 11 QElemType *base;//初始化时动态分配存储空间 12 int front;//头指针 13 int rear;//尾指针 14 } SqQueue; 15 16 //算法3.11 循环队列的初始化 17 Status InitQueue(SqQueue &Q) {//构造一个空队列Q 18 Q.base = new QElemType[MAXQSIZE]; //为队列分配一个最大容量为MAXSIZE的数组空间 19 if (!Q.base) 20 return OVERFLOW; //存储分配失败 21 Q.front = Q.rear = 0; //头指针和尾指针置为零,队列为空 22 return OK; 23 } 24 25 //算法3.12 求循环队列的长度 26 int QueueLength(SqQueue Q) {//返回Q的元素个数,即队列的长度 27 return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE; 28 } 29 30 //算法3.13 循环队列的入队 31 Status EnQueue(SqQueue &Q, QElemType e) {//插入元素e为Q的新的队尾元素 32 if ((Q.rear + 1) % MAXQSIZE == Q.front) //尾指针在循环意义上加1后等于头指针,表明队满 33 return ERROR; 34 Q.base[Q.rear] = e; //新元素插入队尾 35 Q.rear = (Q.rear + 1) % MAXQSIZE; //队尾指针加1 36 return OK; 37 } 38 39 //算法3.14 循环队列的出队 40 Status DeQueue(SqQueue &Q, QElemType &e) {//删除Q的队头元素,用e返回其值 41 if (Q.front == Q.rear) 42 return ERROR; //队空 43 e = Q.base[Q.front]; //保存队头元素 44 Q.front = (Q.front + 1) % MAXQSIZE; //队头指针加1 45 return OK; 46 } 47 48 //算法3.15 取循环队列的队头元素 49 QElemType GetHead(SqQueue Q) {//返回Q的队头元素,不修改队头指针 50 if (Q.front != Q.rear) //队列非空 51 return Q.base[Q.front]; //返回队头元素的值,队头指针不变 52 }
2、Class
1 /***循环队列基本操作***/ 2 #include<iostream> 3 using namespace std; 4 #define MAXQSIZE 100 5 #define OK 1 6 #define ERROR 0 7 #define OVERFLOW -2 8 9 typedef int Status; 10 template<class QElemType> 11 class SqQueue 12 { 13 private: 14 QElemType *base;//初始化时动态分配存储空间 15 int front;//头指针 16 int rear;//尾指针 17 public: 18 SqQueue(); 19 Status EnQueue(QElemType e); 20 Status DeQueue(QElemType &e); 21 QElemType GetHead(); 22 ~SqQueue( ); 23 //重载函数:赋值 24 SqQueue<QElemType> operator=(SqQueue<QElemType> &q); 25 //拷贝构造函数 26 SqQueue(const SqQueue<QElemType> &q); 27 int QueueLength() //返回Q的元素个数,即队列的长度 28 { 29 return (rear - front + MAXQSIZE) % MAXQSIZE; 30 } 31 bool QueueEmpty() 32 { 33 if (front == rear) //队空 34 return true; 35 else 36 return false; 37 } 38 } ; 39 template<class QElemType> 40 SqQueue<QElemType>::SqQueue() //构造一个空队列Q 41 { 42 base = new QElemType[MAXQSIZE]; //为队列分配一个最大容量为MAXSIZE的数组空间 43 front = rear = 0; //头指针和尾指针置为零,队列为空 44 } 45 46 template<class QElemType> 47 Status SqQueue<QElemType>::EnQueue(QElemType e) //插入元素e为Q的新的队尾元素 48 { 49 if ((rear + 1) % MAXQSIZE == front) //尾指针在循环意义上加1后等于头指针,表明队满 50 return ERROR; 51 base[rear] = e; //新元素插入队尾 52 rear = (rear + 1) % MAXQSIZE; //队尾指针加1 53 return OK; 54 } 55 56 template<class QElemType> 57 Status SqQueue<QElemType>::DeQueue(QElemType &e) //删除Q的队头元素,用e返回其值 58 { 59 if (front == rear) 60 return ERROR; //队空 61 e = base[front]; //保存队头元素 62 front = (front + 1) % MAXQSIZE; //队头指针加1 63 return OK; 64 } 65 66 template<class QElemType> 67 QElemType SqQueue<QElemType>::GetHead() //返回Q的队头元素,不修改队头指针 68 { 69 if (front != rear) //队列非空 70 return base[front]; //返回队头元素的值,队头指针不变 71 } 72 template<class QElemType> 73 SqQueue<QElemType>::~SqQueue( ) 74 { 75 if( base ) 76 { 77 delete []base ; 78 } 79 } 80 //重载函数:赋值 81 template<class QElemType> 82 SqQueue<QElemType> SqQueue<QElemType>::operator=(SqQueue<QElemType> &q) 83 { 84 base = new QElemType[MAXQSIZE]; 85 front = q.front; 86 rear = q.rear; 87 88 for(int i=0; i<MAXQSIZE; i++)//复制整个数组 89 { 90 base[i]=q.base[i]; 91 } 92 return *this; 93 } 94 //拷贝构造函数 95 template<class QElemType> 96 SqQueue<QElemType>::SqQueue(const SqQueue<QElemType> &q) 97 { 98 base = new QElemType[MAXQSIZE]; 99 front = q.front; 100 rear = q.rear; 101 102 for(int i=0; i<MAXQSIZE; i++)//复制整个数组 103 { 104 base[i]=q.base[i]; 105 } 106 }
3、Link
1 /***链队的基本操作***/ 2 3 #define OK 1 4 #define ERROR 0 5 #define OVERFLOW -2 6 typedef char QElemType; 7 typedef int Status; 8 9 //- - - - - 队列的链式存储结构- - - - - 10 typedef struct QNode { 11 QElemType data; 12 struct QNode *next; 13 } QNode, *QueuePtr; 14 typedef struct { 15 QueuePtr front; //队头指针 16 QueuePtr rear; //队尾指针 17 } LinkQueue; 18 19 //算法3.16 链队的初始化 20 Status InitQueue(LinkQueue &Q) {//构造一个空队列Q 21 Q.front = Q.rear = new QNode; //生成新结点作为头结点,队头和队尾指针指向此结点 22 Q.front->next = NULL; //头结点的指针域置空 23 return OK; 24 } 25 26 //算法3.17 链队的入队 27 Status EnQueue(LinkQueue &Q, QElemType e) {//插入元素e为Q的新的队尾元素 28 QueuePtr p; 29 p = new QNode; //为入队元素分配结点空间,用指针p指向 30 p->data = e; //将新结点数据域置为e 31 p->next = NULL; 32 Q.rear->next = p; //将新结点插入到队尾 33 Q.rear = p; //修改队尾指针 34 return OK; 35 } 36 37 //算法3.18 链队的出队 38 Status DeQueue(LinkQueue &Q, QElemType &e) {//删除Q的队头元素,用e返回其值 39 QueuePtr p; 40 if (Q.front == Q.rear) 41 return ERROR; //若队列空,则返回ERROR 42 p = Q.front->next; //p指向队头元素 43 e = p->data; //e保存队头元素的值 44 Q.front->next = p->next; //修改头指针 45 if (Q.rear == p) 46 Q.rear = Q.front; //最后一个元素被删,队尾指针指向头结点 47 delete p; //释放原队头元素的空间 48 return OK; 49 } 50 51 //算法3.19 取链队的队头元素 52 QElemType GetHead(LinkQueue Q) {//返回Q的队头元素,不修改队头指针 53 if (Q.front != Q.rear) //队列非空 54 return Q.front->next->data; //返回队头元素的值,队头指针不变 55 }