线性结构——栈、队列

一、栈

栈是一种只能从表的一端存取数据且遵循 “先进后出” 原则的线性存储结构。

  • 向栈中添加元素,此过程被称为"进栈"(入栈或压栈);
  • 从栈中提取出元素,此过程被称为"出栈"(或弹栈);
  • 栈的开口端被称为栈顶;封口端被称为栈底
    在这里插入图片描述
    如图,1最先进栈,4最先出栈

栈的具体实现

实现分为 顺序栈链栈

  • 顺序栈:采用顺序存储结构可以模拟栈存储数据的特点,从而实现栈存储结构;
  • 链栈:采用链式存储结构实现栈结构;

1.1 顺序栈

可以用数组或者连续内存,本文使用连续内存。
在这里插入图片描述

1.1.1 定义数据类型

typedef struct
{
  datatype *bottom;  // 栈底指针
  int size;          // 栈容量
}stack_o;

1.1.2 初始化栈

stack_o *Init_stack_o (void)  //初始化栈
{
  stack_o *stack = NULL;

  stack = malloc (sizeof (stack_o));

  stack->bottom = malloc (STACK_MAXSIZE * sizeof (datatype));
  stack->size = 0;
  
  return stack;
}

1.1.3 判空

int isempty_stack_o (stack_o *stack) //判空
{
  //检查参数

	return  stack->size == 0? 1 : 0;
}

1.1.4 判满

int isfull_stack_o(stack_o *stack) //判满
{
  //检查参数
  
	return stack->size == STACK_MAXSIZE ? 1 : 0;
}

1.1.5 入栈

int push_stack_o (stack_o *stack, datatype data) //入栈
{
  if (isfull_stack_o(stack)) {
    printf ("stack is null! \n");
    return -1;
  }

  stack->bottom[stack->size++] = data;

  return 0;
}

1.1.6 出栈

int pop_stack_o (stack_o *stack) //出栈
{
  if (isempty_stack_o(stack)) {
    printf ("stack is full! \n");
    return -1;
  }
  
  stack->bottom[stack->size--] = 0;

  return 0;
}

1.1.7 打印

int display_stack_o (stack_o *stack) //打印
{
  int i;
  
  printf ("stack bottom: ");
  for (i = 0; i < stack->size; i++) {
    printf ("%d - %p --> ",stack->bottom[i], &stack->bottom[i]);
  }
  printf ("\n");

  return 0;
}

1.1.8 销毁栈

int destory_stack_o (stack_o *stack)   //销毁栈
{
  //检查参数
  
  free (stack->bottom);
  free (stack);
}

1.1.9 测试

int main(void)
{
  datatype data[5] = {5, 4, 1, 3, 2};
  stack_o *stack = NULL;
  stack = Init_stack_o();

  if (isempty_stack_o (stack)) {
    printf ("stack is null\n");
  }

  push_stack_o (stack, data[0]);
  push_stack_o (stack, data[1]);
  push_stack_o (stack, data[2]);
  push_stack_o (stack, data[3]);
  push_stack_o (stack, data[4]);
  display_stack_o (stack);

  pop_stack_o (stack);
  display_stack_o (stack);

	return 0;
}

在这里插入图片描述

1.2 链栈

在这里插入图片描述

1.2.1 定义数据类型

typedef int datatype;

typedef struct stack
{
  struct stack *next;     // 指针域
  datatype     data;      // 数据
}stack_l;

1.2.2 初始化栈

stack_l *create_stack_l (void)  //创建头节点
{
  stack_l *head = NULL;
  head = malloc(sizeof(*head));
	
	head->next=NULL;

	return head;
}

1.2.3 判空

int isempty_stack_l (stack_l *head) //判空
{
  return head->next == NULL ? 1 : 0;
}

1.2.4 入栈

int push_stack_l (stack_l *head, datatype data)  //入栈
{
  stack_l *stack = NULL;
  stack_l *q = NULL;

  stack = malloc (sizeof (stack_l));
  memcpy (&stack->data, &data, sizeof (datatype));

  for(q = head; q->next != NULL; q = q->next);
	q->next = stack;
  stack->next = NULL;
  
  return 0;
}

1.2.5 出栈

int pop_stack_l (stack_l *head)  //出栈
{
  stack_l *tmp = NULL;
  for (tmp = head; tmp->next->next != NULL; tmp=tmp->next);

  free(tmp->next);

  tmp->next = NULL;
  
  return 0;
}

1.2.6 打印

int display_stack_l (stack_l *head) //打印
{
  stack_l *q = NULL;
  printf ("head : %p -> ",head);
  for (q = head->next ; q != NULL ; q = q->next) {
    printf ("%d - %p -> ",q->data,q);
  }
  printf ("\n");

  return 0;
}

1.2.7 销毁栈

int destory_stack_l (stack_l *head) //销毁栈
{
  stack_l *q,*p;
  
  for (p = head->next, q = p; q != NULL; q = p) {
    p = q->next;
    q->next = NULL;
    free (q);
  }
  
  head->next = NULL;

  free (head);
  head = NULL;

  return 0;
}

1.2.8 测试

int main(void)
{
  datatype data[5] = {5, 4, 1, 3, 2};
  stack_l *head = NULL;
  head = create_stack_l();

  if (isempty_stack_l (head)) {
    printf ("stack is null\n");
  }

  push_stack_l (head, data[0]);
  push_stack_l (head, data[1]);
  push_stack_l (head, data[2]);
  push_stack_l (head, data[3]);
  push_stack_l (head, data[4]);
  display_stack_l (head);

  pop_stack_l (head);
  display_stack_l (head);
  pop_stack_l (head);
  display_stack_l (head);
  
  destory_stack_l (head);

	return 0;
}

在这里插入图片描述

二、队列

队列中数据的进出要遵循 “先进先出” 的原则

  • 向队列中添加元素,此过程被称为入队;
  • 从队列中提取出元素,此过程被称为出队;
  • 出队 口被称为 队头;入队 口被称为 队尾

在这里插入图片描述

队列的具体实现

实现分为 顺序队列链队列

  • 顺序队列:在顺序表的基础上实现的队列结构;
  • 链式队列:在链表的基础上实现的队列结构;

2.1 顺序队列

在这里插入图片描述

2.1.1 定义数据类型

typedef int datatype;

typedef struct {
  datatype *data;  //数据域指针
  int front;       //队头
  int rear;        //队尾
}queue_o;

2.1.2 初始化队列

queue_o *Init_queue_o (void)  //初始化队列
{
  queue_o  *queue = NULL;

  queue = malloc (sizeof (queue_o));
  queue->data = malloc (QUEUE_MAXSIZE * sizeof (datatype));
  queue->front = 0;
  queue->rear = 0;

  return queue;
}

2.1.3 判空

int isempty_queue_o (queue_o *queue) //判空
{
  //检查参数

	return  queue->front == 0? 1 : 0;
}

2.1.4 判满

int isfull_queue_o(queue_o *queue) //判满
{
  //检查参数
  
	return queue->front == QUEUE_MAXSIZE ? 1 : 0;
}

2.1.5 入队

int push_queue_o (queue_o *queue, datatype data) //入队
{
  queue->data[queue->rear++] = data;

  return 0;
}

2.1.6 出队

int pop_queue_o (queue_o *queue) //出队
{
   int i;

  for (i = queue->front; i < queue->rear; i++) {
    queue->data[i] = queue->data[i + 1];
  }
  
  queue->rear--;

  return 0;
}

2.1.7 打印

int display_queue_o (queue_o *queue) //打印
{
  int i;
  
  printf ("queue head: ");
  for (i = queue->front; i < queue->rear; i++) {
    printf ("%d - %p --> ",queue->data[i], &queue->data[i]);
  }
  printf ("queue tail\n");

  return 0;
}

2.1.8 销毁队列

int destory_stack_o (queue_o *queue)   //销毁队列
{
  //检查参数
  
  free (queue->data);
  free (queue);
}

2.1.9 测试

int main(void)
{
	datatype data[5] = {1, 2, 3, 4, 5};
  queue_o *queue = NULL;
  queue = Init_queue_o();

  if (isempty_queue_o (queue)) {
    printf ("queue is null\n");
  }

  push_queue_o (queue, data[0]);
  push_queue_o (queue, data[1]);
  push_queue_o (queue, data[2]);
  push_queue_o (queue, data[3]);
  push_queue_o (queue, data[4]);
  display_queue_o (queue);

  pop_queue_o (queue);
  display_queue_o (queue);

	return 0;
}

在这里插入图片描述

2.2 链式队列

在这里插入图片描述

2.2.1 定义数据类型

typedef int datatype;

typedef struct queue
{
  struct queue *next;     // 指针域 队头
  datatype     data;      //数据
}queue_l;

2.2.2 初始化队列

queue_l *create_queue_l (void)  //创建头节点
{
  queue_l *head = NULL;
  head = malloc(sizeof(*head));
	
	head->next=NULL;

	return head;
}

2.2.3 判空

int isempty_queue_l (queue_l *head) //判空
{
  return head->next == NULL ? 1 : 0;
}

2.2.4 打印

int display_queue_l (queue_l *head) //打印
{
  queue_l *q = NULL;
  printf ("tail : %p -> ",head);
  for (q = head->next ; q != NULL ; q = q->next) {
    printf ("%d - %p -> ",q->data,q);
  }
  printf ("\n");

  return 0;
}

2.2.5 入队

int push_queue_l (queue_l *head, datatype data)  //入队
{
  queue_l *queue = NULL;
  queue_l *q = NULL;

  queue = malloc (sizeof (queue_l));
  memcpy (&queue->data, &data, sizeof (datatype));

  for(q = head; q->next != NULL; q = q->next);
	q->next = queue;
  queue->next = NULL;
  
  return 0;
}

2.2.6 出队

int pop_queue_l (queue_l *head)  //出队
{
  queue_l *tmp = NULL;

  for (tmp = head; tmp->next->next != NULL; tmp=tmp->next);

  free(tmp->next);

  tmp->next = NULL;
  
  return 0;
}

2.2.7 销毁队列

int destory_queue_l (queue_l *head) //销毁队列
{
  queue_l *q,*p;
  
  for (p = head->next, q = p; q != NULL; q = p) {
    p = q->next;
    q->next = NULL;
    free (q);
  }
  
  head->next = NULL;

  free (head);
  head = NULL;

  return 0;
}

2.2.8 测试

int main(void)
{
  datatype data[5] = {5, 4, 1, 3, 2};
  queue_l *head = NULL;
  head = create_queue_l();

  if (isempty_queue_l (head)) {
    printf ("queue_l is null\n");
  }

  push_queue_l (head, data[0]);
  push_queue_l (head, data[1]);
  push_queue_l (head, data[2]);
  push_queue_l (head, data[3]);
  push_queue_l (head, data[4]);
  display_queue_l (head);

  pop_queue_l (head);
  display_queue_l (head);
  pop_queue_l (head);
  display_queue_l (head);
  
  destory_queue_l (head);
  
  return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值