目录
3.1 堆栈的基本概念
一、堆栈的定义
堆栈是一种只允许在表的一端进行插入操作和删除操作的线性表。允许操作的一端称为栈顶,栈顶元素的位置由一个称为栈顶指针的变量给出。当表中没有元素时,称之为空栈。
二、堆栈的基本操作
1. 插入(进栈、入栈)2. 删除(出栈、退栈) 3. 测试堆栈是否为空 4. 测试堆栈是否已满 5. 检索当前栈顶元素
3.2 堆栈的顺序存储结构
一、构造原理
描述堆栈的顺序存储结构最简单的方法是利用一维数组 STACK[ 0..M–1 ] 来表示,同时定义一个整型变量( 不妨取名为top) 给出栈顶元素的位置。
上溢——当堆栈已满时做插入操作。(top=M–1);下溢——当堆栈为空时做删除操作。(top=–1)
二、代码实现
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define MaxSize 100
using namespace std;
//定义栈
typedef struct stack
{
int data[MaxSize];//数组实现栈内元素定位
int top;//作为数组下标
}*Stack,SNode;
//创建一个空栈
Stack creatStack()
{
Stack s = (Stack)malloc(sizeof(Stack));
s->top = 0;
return s;
}
//入栈
bool Push(Stack &s, int x)
{
if(s->top == MaxSize)
return false;
s->data[s->top++] = x;
return true;
}
//出栈
bool isEmpty(Stack s)
{
return (s->top == 0);
}
int Pop(Stack &s)
{
return s->data[--s->top];
}
int main()
{
int n;
int x;
cin>>n;
Stack s = creatStack();
while(n--)
{
int x;
cin>>x;
Push(s,x);
}
while(!isEmpty(s))
{
cout<<Pop(s)<<" ";
}
cout<<endl;
return 0;
}
三. 多栈共享连续空间问题
#include <stdio.h>
#include <stdlib.h>
#define ERROR 1e8
typedef int ElementType;
typedef enum { push, pop, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
struct SNode {
ElementType *Data;
Position Top1, Top2;
int MaxSize;
};
typedef struct SNode *Stack;
Stack CreateStack( int MaxSize )//要写
{
Stack s = (Stack)malloc(sizeof(struct SNode));
s->Top1 = -1;
s->Top2 = MaxSize;
s->Data = (int *)malloc(sizeof(int)*(MaxSize+5));
s->MaxSize = MaxSize;
return s;
}
bool Push( Stack S, ElementType X, int Tag )//要写
{
if(S->Top1+1 == S->Top2)
{
printf("Stack Full\n");
return false;
}
if(Tag == 1)
{
S->Top1++;
S->Data[S->Top1] = X;
}
else
{
S->Top2--;
S->Data[S->Top2] = X;
}
return true;
}
ElementType Pop( Stack S, int Tag )//要写
{
if((Tag == 1 && S->Top1 == - 1) ||(Tag == 2 && S->Top2 == S->MaxSize))
{
printf("Stack %d Empty\n",Tag);
return ERROR;
}
if(Tag == 1)
{
S->Top1--;
return S->Data[S->Top1+1];
}
else
{
S->Top2++;
return S->Data[S->Top2-1];
}
}
Operation GetOp(); /* details omitted */
void PrintStack( Stack S, int Tag ); /* details omitted */
int main()
{
int N, Tag, X;
Stack S;
int done = 0;
scanf("%d", &N);
S = CreateStack(N);
while ( !done ) {
switch( GetOp() ) {
case push:
scanf("%d %d", &Tag, &X);
if (!Push(S, X, Tag)) printf("Stack %d is Full!\n", Tag);
break;
case pop:
scanf("%d", &Tag);
X = Pop(S, Tag);
if ( X==ERROR ) printf("Stack %d is Empty!\n", Tag);
break;
case end:
PrintStack(S, 1);
PrintStack(S, 2);
done = 1;
break;
}
}
return 0;
}
3.3 堆栈的链式存储结构
一.构造原理
链接堆栈就是用一个线性链表来实现一个堆栈结构, 同时设置一个指针变量( 这里不妨仍用top表示)指出当前栈顶元素所在链结点的位置。栈为空时,有top=NULL。
二、代码实现
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
typedef struct SNode
{
int data;
struct SNode *next;
}*Stack,SNode;
Stack createStack()
{
Stack s = (Stack)malloc(sizeof(Stack));
s->next = NULL;
return s;
}
//入栈
bool isEmpty(Stack s)
{
if(s->next)
return false;
return true;
}
void push(Stack &s,int e)
{
SNode *p = new SNode;
p->data = e;
p->next = s->next;
s->next = p;
}
//出栈
int pop(Stack &s)
{
SNode *p = s->next;
s->next = p->next;
return p->data;
}
int main()
{
int n;
cin>>n;
Stack s = createStack();
while(n--)
{
int x;
cin>>x;
push(s,x);
}
while(!isEmpty(s))
{
cout<<pop(s)<<" ";
}
cout<<endl;
}
3.4 队列的基本概念
一. 队列的定义
队列简称队 。是一种只允许在表的一端进行插入操作,而在表的另一端进行删除操作的线性表。允许插入的一端称为队尾,队尾元素的位置由rear指出; 允许删除的一端称为队头, 队头元素的位置由front指出。
二. 队列的基本操作1. 队列的插入(进队、入队) √ 2. 队列的删除(出队、退队) √ 3. 测试队列是否为空 √ 4. 检索当前队头元素 5. 创建一个空队
3.5队列的顺序存储结构
一.构造原理
在实际程序设计过程中,通常借助一个一维数组QUEUE[0..M–1]来描述队列的顺序存储结构,同时,设置两个变量 front与rear分别指出当前队头元素与队尾元素的位置。
约定
rear 指出实际队尾元素所在的位置,
front 指出实际队头元素所在位置的前一个位置。
二、代码实现
#include <stdio.h>
#include <malloc.h>
typedef struct sq
{
int maxsize;
int front, rear;
int *quence;
}Qs;
void init_quence(Qs *s, int ms) /*初始化队列*/
{
s->maxsize = ms;
s->quence = (int *)malloc(ms*sizeof(int));
s->front = s->rear = 0;
}
void in_quence(Qs *s, int val) /*入队函数*/
{
if((s->rear+1)%s->maxsize == s->front)
{
printf("Quence is full.\n");
return;
}
s->rear = (s->rear+1)%s->maxsize;
s->quence[s->rear] = val;
}
int out_quence(Qs *s) /*出队函数*/
{
if(s->rear != s->front)
{
s->front = (s->front+1)%s->maxsize;
return s->quence[s->front];
}
}
void print_quence(Qs *s) /*打印队列中元素*/
{
int i;
i = s->front;
if(s->rear == s->front)
return;
do
{
printf("%d ", s->quence[(i+1)%s->maxsize]);
i = (i+1)%s->maxsize;
}while(i != s->rear);
}
void clear_quence(Qs *s) /*清除队列*/
{
free(s->quence);
s->quence = 0;
s->maxsize = 0;
s->front = s->rear = 0;
}
int count_quence(Qs *s) /*统计队列个数*/
{
int i, count = 0;
i = s->front;
if(s->rear == s->front)
return 0;
do
{
count ++;
i = (i+1)%s->maxsize;
}while(i != s->rear);
return count;
}
int main()
{
Qs s;
int i;
int dat[7] = {1, 2, 3, 4, 5, 6, 7};
init_quence(&s, 7);
for(i = 0; i < 7; i++)
{
in_quence(&s, dat[i]);
printf("Quence number is: %d. ", count_quence(&s));
print_quence(&s);
printf("\n");
}
printf("Out quence number is: %d.\n", out_quence(&s));
print_quence(&s);
clear_quence(&s);
return 0;
}
三.循环队列
把队列(数组)设想成头尾相连的循环表,使得数组前部由于删除操作而导致的无用空间尽可能得到重复利用,这样的队列称为循环队列。
3.5 队列的链式存储结构
一.构造原理
队列的链式存储结构是用一个线性链表表示一个队列,指针front与rear分别指向实际队头元素与实际队尾元素所在的链结点。
二、代码实现
#include <stdio.h>
#include <stdlib.h>
typedef int LQEletype;
typedef struct QueueNode{
LQEletype data;
struct QueueNode *next;
}QueueNode;
typedef QueueNode *QueueP;//定义指向队列节点的指针(相当于头指针)
typedef struct LinkQueue{
QueueP front,rear;//定义队头指针(相当于头指针)、队尾指针
}LinkQueue;
void init(LinkQueue *q){
QueueP p=(QueueP)malloc(sizeof(QueueNode));
p->next=NULL;
q->front=p;//初始化一个空的链式队列。
q->rear=p;
}
void insertEle(LinkQueue *q,LQEletype e){
QueueP p=(QueueP)malloc(sizeof(QueueNode));
p->data=e;
p->next=NULL;//因为插入时在队列后边插入,next为空
q->rear->next=p;//让队尾指向插入的节点
q->rear=p;//重新指定队尾
}
void deleteEle(LinkQueue *q,LQEletype *e){
if(q->front==q->rear){
printf("该队列为空");
return ;
}else{
QueueP p=q->front->next;//拿到队列的第一个数据
*e=p->data;
q->front->next=p->next;//
if(q->rear==p){//如果拿到的这个数据节点恰巧是队尾,就重新指定队尾
q->rear=q->front;
}
free(p);
}
}
void getEle(LinkQueue q,LQEletype *e){
if(q.front==q.rear){
printf("该队列为空");
return ;
}else{
*e=q.front->next->data;
}
}
int main()
{
LinkQueue q;
init(&q);
LQEletype e,i=888;
getEle(q,&e);
printf("初始化后尝试获取队列里的值:\n%d\n",e);
insertEle(&q,i);
getEle(q,&e);
printf("插入后获取队列里的值:\n%d\n",e);
deleteEle(&q,&i);
getEle(q,&e);
return 0;
}