stack
链栈 / 链队列 没有 size限制,顺序栈 / 顺序队列有 size限制。
链系出入需要free,malloc,顺序系则是需要出判空,入判满。
如果有设置标志位 或 实时size,那么每一次出入操作完之后都要及时更新。
链栈的指针方向是从栈顶指向栈底。
链队列的指针方向是从队头指向队尾。
分为 顺序栈 和 链栈
只能在表尾 / 栈顶进行操作
表尾 ============================ 表头
top ============================ base
栈顶 ============================ 栈底
数组[n] ========================== 数组[0]
- 顺序栈
top指向当前栈顶元素的下一个位置。
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef struct
{
SElemType *base;
SElemType *top;
int stacksize; // 最大size,而top指向实时值
} SqStack;
Status InitStack(SqStack &s)
{
s.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if(!s.base)
{
return ERROR;
}
s.top = s.base;
s.stacksize = STACK_INIT_SIZE;
return OK;
}
Status GetTop(SqStack s,SElemType &e)
{
if(s.top == s.base)
{
return FALSE;
}
e = *(s.top - 1);
return OK;
}
Status Push(SqStack &s,SElemType e)
{
if(s.top - s.base >= s.stacksize)
{
s.base = (SElemType *)realloc(sizeof(SElemType) * (NEW_SIZE))
if(!s.base)
{
return ERROR;
}
s.top = s.base + s.size; //s.top此时绝对位置一定要更新!!!
s.size = NEW_SIZE; //s.top此时绝对位置一定要更新!!!
}
*(s.top) = e;
s.top++;
return OK;
}
Status Pop(SqStack &s,SElemType &e)
{
if(s.top == s.base)
{
return ERROR;
}
e = *(s.top - 1);
s.top--;
return OK;
}
- 链栈
s.top ------------------------------------------------> s.base
top指向栈顶,出栈入栈操作栈顶元素即可。
链的方向是从栈顶指向栈底。
typedef struct NodeType
{
ElemType data;
NodeType *next;
} NodeType,*LinkType;
typedef struct
{
LinkType top;
int size;
} Stack;
void InitStack(Stack &s)
{
s.top = NULL;
s.size = 0;
}
void DestroyStack(Stack &s)
{
LinkType p;
while(s.top)
{
p = s.top;
s.top = s.top->next;
free(p);
s.size--;
}
free(&s);
}
void ClearStack(Stack &s)
{
LinkType p;
while(s.top)
{
p = s.top;
s.top = p->next;
free(p);
s.size--;
}
}
Status StackEmpty(Stack s)
{
if(s.size)
{
return FALSE;
}
else
{
return TRUE;
}
//也可以通过 ---- s.top是否为NULL ----来判空
}
Status Push(Stack &s,ElemType e)
{
LinkType p;
p = (LinkType)malloc(sizeof(NodeType));
if(!p)
{
return ERROR;
}
p->data = e;
p->next = s.top;
s.top = p;
s.size++;
return OK;
}
Status Pop(Stack &s,ElemType &e)
{
LinkType p;
if(s.size == 0 || s.top == NULL)
{
return ERROR;
}
p = s.top;
e = p->data;
s.top = p->next;
free(p);
s.size--;
return OK;
}
void StackTraverse(Stack &s,Status (*Visit)(ElemType e))
{
LinkType p;
p = s.top;
while(p)
{
Visit(p->data);
p = p->next;
}
}
队列
队列:分为链队列和顺序队列
先进先出
队头出,队尾进
- 链队列
存在头节点,即 q.front -> next 存放第一个元素。
q.rear 指向队尾元素,而不是指向队尾元素的下一个位置。
typedef struct QNode
{
QElemType data;
struct QNode *next;
} QNode,*QueuePtr;
typedef struct
{
QueuePtr front;
QueuePtr rear;
} LinkQueue;
Status InitQueue(LinkQueue &q)
{
QueuePtr tmp;
tmp = (QueuePtr)malloc(sizeof(QNode));
if(!tmp)
{
return ERROR;
}
q.front = tmp;
q.rear = tmp;
q.front->next = NULL;
return OK;
}
Status DestroyQueue(LinkQueue &q)
{
while(q.front)
{
q.rear = q.front->next;
free(q.front);
q.front = q.rear;
}
return OK;
}
Status EnQueue(LinkQueue &q,QElemType e)
{
QueuePtr tmp;
tmp = (QueuePtr)malloc(sizeof(QNode));
if(!tmp)
{
return ERROR;
}
tmp->data = e;
tmp->next = q.rear->next;
q.rear->next = tmp;
q.rear = tmp;
return OK;
}
Status DeQueue_1(LinkQueue &q,QElemType &e)
{
// 不带头结点,即q.front 指向第一个队列元素
if(q.front == NULL && q.rear == NULL)
{
return ERROR;
}
e = q.front->data;
tmp = q.front->next;
free(q.front);
q.front = tmp;
if(!tmp)
{
q.rear = NULL;
}
return OK;
}
Status DeQueue_2(LinkQueue &q,QElemType &e)
{
//带有头节点,q.front->next 指向队列里面第一个元素
if(q.front == q.rear)
{
return ERROR;
}
p = q.front->next;
e = p->data;
q.front->next = p->next;
if(q.rear == p)
{
q.rear = q.front;
}
free(p);
return OK;
}
- 循环队列
利用取余实现数组的循环
可以设置判满标志位,也可以设置在顺序队列中空出一位来判满
下面采用的是在顺序队列中空出一位来判断
注意判满条件,判空条件。采用tag标志位时还要及时更新tag。如果有size也要及时更新。
#define MAXQSIZE 100
typedef struct
{
QElemType *base;
int front;
int rear;
}SqQueue;
Status InitQueue(SqQueue &q)
{
q.base = (QElemType *)malloc(sizeof(QElemType ) * MAXQSIZE);
if(!q.base)
{
return ERROR;
}
q.front = 0;
q.rear = 0;
return OK;
}
int QueueLength(SqQueue q)
{
return ((q.rear - q.front + MAXQSIZE) % MAXQSIZE);
}
Status EnQueue(SqQueue &q,QElemType e)
{
if((q.rear + 1) % MAXQSIZE == q.front)
{
return ERROR;
}
*(q.rear) = e;
q.rear = (q.rear + 1) % MAXQSIZE;
return OK;
}
Status DeQueue(SqQueue &q,QElemType &e)
{
if(q.rear == q.front)
{
return ERROR;
}
e = q.base[q.front];
q.front = (q.front + 1) % MAXQSIZE;
return OK;
}