数据结构 第三章 栈和队列

目录

3.1 堆栈的基本概念

3.2 堆栈的顺序存储结构

一、构造原理

二、代码实现

三. 多栈共享连续空间问题

3.3 堆栈的链式存储结构

一.构造原理

二、代码实现

3.4 队列的基本概念

3.5队列的顺序存储结构

一.构造原理

二、代码实现

三.循环队列

3.5 队列的链式存储结构

一.构造原理

二、代码实现


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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值