数据结构实验三 链队

#include <iostream>
#include "stdio.h"
#include "stdlib.h"

using namespace std;

#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int QElemType;//因为要求是输入整数型数据元素

//00 数据结构定义
typedef struct QNode { // 结点QNode定义
        QElemType data;
        struct QNode *next;
    } QNode, *QueuePtr;

typedef struct { // 链队LinkQueue定义
      QueuePtr front; // 队头指针
      QueuePtr rear; // 队尾指针
    } LinkQueue;

//01 初始化链队Q
Status InitLQueue(LinkQueue &Q)//Q为什么加&?Q是一个有两个指针域的结构体变量,有一个指针的值修改了,Q这个结构体变量就发生变化了。如果想让Q返回给主函数,这个子函数就要加&。
{
  Q.rear=Q.front = new QNode;
  Q.front->next = NULL;//头结点需要修改next为NULL;
  return OK;0
}

//02 根据随机输入的队列长度和队列中整数型数据元素的值,创建一个非空链队列;
Status CreateLQueue(LinkQueue &Q)//即使已经初始化了,但每在队尾插入一个节点,Q的尾指针就要修改指向这个新加入的节点,故而Q发生了变化,想让主函数同时改变,则需加&。
{
  if (!Q.front)
    InitLQueue(Q);

  int len, n;
  QueuePtr p;

  cout<< "请输入链队的长度(大于0的整数):";
  cin >> len;

  cout << "请输入" << len << "个整数:";
  int i=0;
  while (i<len)
  {
    cin >> n;
    p = new QNode;
    p->data = n;
    p->next = NULL;
    Q.rear->next = p;//首先,要把新结点链上去
    Q.rear = p;          //其次,修改尾指针rear指向这个新结点p
    i++;
  }
  return OK;
}

//03 入队
Status EnQueue(LinkQueue &Q, QElemType e)
{
  QueuePtr p;

  if(Q.front)
  {
    p = new QNode;
    p->data = e;
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p;
    return OK;
  }
  else
  {
    cout << "链队不存在!" <<endl;
    return ERROR;
  }
}

//04 出队
Status DeQueue(LinkQueue &Q, QElemType &e)//出队是要删除对头元素,如果队中的节点大于等于2个,Q的f, r均不用修改,修改的头结点的next域,Q没发生变化,不用加&,但如果队中只有一个结点出队,则需修改Q.rear,Q发生变化了,故加&。同理e的值需要返回给主函数,故要加&。
{
  if (Q.front == Q.rear)
  {
    printf("空链队\n");
    return ERROR;
  }
  QueuePtr p;
  p = Q.front->next;               //p指向队头元素
  e = p->data;
  Q.front->next = p->next;    //头结点的next指向p-next(p的后继结点);
  if (Q.rear == p)
  {
    Q.rear = Q.front;       //如果只有一个结点,尾指针也要修改;
  }
  delete p;
  return OK;
}

//05 判定队列是否为空,若不空输出队头元素;注意与教材上的区别,两种不同的形式返回一个值
Status GetLQHead(LinkQueue Q, QElemType &e)//Q没变不加,e需要返回给主函数故加&。
{
  if (Q.front != Q.rear)
  {
    e = Q.front->next->data;
    return OK;
  }
  else
  {
    printf("当前链队为空,无头元素!\n");
    return ERROR;
  }
}

//06 输出链队当前元素个数;

Status GetLength(LinkQueue Q, int &len)//Q没变不加,len需要返回给主函数故加&。
{
  len = 0;
  if (Q.front != Q.rear)
  {
    QueuePtr p = Q.front->next;
    while (p)
    {
      len++;
      p = p->next;
    }
  }
  return OK;
}

//07 输出队列中所有元素;
Status DisplayLQueue(LinkQueue Q)//Q没变不加&
{
  if (Q.front == Q.rear)
  {
    printf("空链队\n");
    return ERROR;
  }
  QueuePtr p=Q.front->next;
  while (p)
  {
    cout << p->data << " ";
    p = p->next;
  }
  return OK;
}

void main()
{
  LinkQueue Q;

  int i = InitLQueue(Q);//01初始化
  printf("链队始化状态(OK-1;ERROR-0):%d\n", i);//测试链队初始化是否成功,OK-1

  CreateLQueue(Q);//02链队的创建
  printf("链队从对头到队尾的元素是:");
  DisplayLQueue(Q);

  printf("\n入队(只能在队尾),请输入一个整数:");
  int x;
  cin >> x;
  EnQueue(Q, x);//03入队
  DisplayLQueue(Q);

  int y;
  printf("\n出队(只能是队头)元素是:");
  DeQueue(Q, y);//04出队,要删除队头元素
  cout << y << endl;
  cout << "出队后(Q少了一个元素),链队为:";
  DisplayLQueue(Q);

  int z;
  printf("\n读取队头元素:");
  GetLQHead(Q, z);//05读队头元素
  cout << z << endl;
  cout << "读队头元素后(Q不变),链队仍为:";
  DisplayLQueue(Q);

  int len;
  GetLength(Q, len);//06当前链队长度
  cout << "\n当前链队元素个数是:"<<len<<endl;

  system("pause");//用于函数输出屏幕暂停,以便观察
}

 

 

posted @   师大无雨  阅读(2021)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示