顺序表,链表,顺序栈,顺序循环队列,链式队列的基本操作

数据结构的学习笔记,有点混杂,以后有时间再来整理

中文解释是用来凑字数的


目录

1.顺序表

2.链表

3.原地逆置链表

4.单链表的基本操作

5.顺序栈(使用数组实现的栈)的基本操作

6.顺序循环队列的基本操作

7.链式队列的基本操作


1.顺序表

#include<stdio.h>

//顺序表

#define MaxSize 50
typedef int ElemType;

typedef struct {
	ElemType data[MaxSize];
	int length;
}SqList;

void printList(bool result, SqList L) {
	if (!result) {
		printf("false");
	}
	else
	{
		for (int i = 0; i < L.length; i++) {
			printf("%3d", L.data[i]);
		}
		printf("\n");
	}
}

bool insertList(SqList& L, int i, ElemType e) {
	if (i<1 || i>L.length + 1) {
		return false;
	}
	if (L.length >= MaxSize) {
		return false;
	}
	for (int j = L.length; j >= i; j--) {
		L.data[j] = L.data[j - 1];
	}
	L.data[i - 1] = e;
	L.length++;
	return true;
}

bool deleteList(SqList& L, int i, ElemType& e) {
	if (i<1 || i>L.length) {
		return false;
	}
	e = L.data[i - 1];
	for (int j = i; j < L.length; j++) {
		L.data[j - 1] = L.data[j];
	}
	L.length--;
	return true;
}

int main() {
	SqList L;
	L.data[0] = 1;
	L.data[1] = 2;
	L.data[2] = 3;
	L.length = 3;
	ElemType e;
	scanf_s("%d", &e);//插入的元素
	bool result;
	result = insertList(L, 2, e);
	printList(result, L);

	int i;
	scanf_s("%d", &i);//删除的位置
	result = deleteList(L, i, e);

	printList(result, L);
	return 0;
}

这段代码实现了一个顺序表(线性表)的基本操作,包括插入元素和删除元素。顺序表的最大容量为50个元素。代码的功能和执行步骤如下:

  1. 定义顺序表结构体:定义了一个结构体 SqList,包括一个存储数据的数组 data 和表示当前长度的变量 length

  2. 打印列表函数printList 函数用于打印顺序表的内容。如果操作失败,打印“false”;否则,依次打印顺序表中的每个元素。

  3. 插入元素函数insertList 函数在顺序表的指定位置插入一个新元素。插入操作成功返回 true,失败返回 false。插入操作的步骤包括:

    • 检查插入位置是否合法。
    • 检查顺序表是否已满。
    • 将插入位置及其后的元素后移一位。
    • 插入新元素,并增加顺序表的长度。
  4. 删除元素函数deleteList 函数删除顺序表中指定位置的元素。删除操作成功返回 true,失败返回 false。删除操作的步骤包括:

    • 检查删除位置是否合法。
    • 记录被删除的元素。
    • 将删除位置后的元素前移一位。
    • 减少顺序表的长度。
  5. 主函数main 函数初始化一个顺序表 L,并进行以下操作:

    • 初始化顺序表,包含三个元素:1、2、3。
    • 从用户输入中读取一个元素,将其插入到顺序表的第2个位置。
    • 调用 printList 函数打印插入操作后的顺序表。
    • 从用户输入中读取一个位置,删除该位置的元素。
    • 调用 printList 函数打印删除操作后的顺序表。

代码中的 scanf_s 函数用于从控制台读取用户输入的插入元素和删除位置。程序的执行结果将根据用户输入的具体值而变化。

2.链表

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

//链表

typedef int ElemType;

typedef struct LNode {
	ElemType data;
	struct LNode* next;
}LNode, * LinkList;

//头插法建立链表
void headInsertList(LinkList& L) {
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;
	ElemType x;
	scanf_s("%d", &x);
	LNode* node;
	while (x != 9999)
	{
		node = (LNode*)malloc(sizeof(LNode));
		node->data = x;
		node->next = L->next;
		L->next = node;
		scanf_s("%d", &x);
	}
}

//尾插法建立链表
void tailInsertList(LinkList& L) {
	L = (LinkList)malloc(sizeof(LNode));
	LNode* r, * node;
	r = L;
	ElemType x;
	scanf_s("%d", &x);
	while (x != 9999)
	{
		node = (LNode*)malloc(sizeof(LNode));
		node->data = x;
		r->next = node;
		r = node;
		scanf_s("%d", &x);
	}
	r->next = NULL;
}

//按序号查找节点
LNode* getElemByPos(LinkList L, int i) {
	if (i < 0) {
		return NULL;
	}
	if (i == 0) {
		return L;
	}
	int j = 1;
	LNode* p = L->next; //第一个元素节点
	while (p && j < i)
	{
		p = p->next;
		j++;
	}
	return p;
}

//按值查找节点
LNode* getElemByValue(LinkList L, ElemType e) {
	LNode* p = L->next;
	while (p && p->data != e)
	{
		p = p->next;
	}
	return p;
}

//在指定位置插入节点
bool insertElemByPos(LinkList L, int i, ElemType e) {
	LNode* p = getElemByPos(L, i - 1);
	if (p == NULL) {
		return false;
	}
	LNode* q = (LNode*)malloc(sizeof(LNode));
	q->data = e;
	q->next = p->next;
	p->next = q;
	return true;
}

//删除指定位置节点
bool deleteElemByPos(LinkList L, int i) {
	LNode* p = getElemByPos(L, i - 1);
	if (p == NULL) {
		return false;
	}
	LNode* q = p->next;
	// 要删除的位置是链表长度+1的位置,get函数获取到最后一个节点,p不为空,但后继为NULL
	if (q == NULL)
	{
		return false;
	}
	p->next = q->next;
	free(q);
	return true;
}

void printList(LinkList L) {
	while (L = L->next)
	{
		printf("%3d", L->data);
	}
	printf("\n");
}

int main() {
	LinkList L;

	//headInsertList(L);
	tailInsertList(L);
	printList(L);

	//LNode* result = getElemByPos(L, 2);
	//LNode* result = getElemByValue(L, 4);
	//printf("%d", result->data);

	//bool result = insertElemByPos(L, 2, 99);
	//if (result) {
	//	printList(L);
	//}

	deleteElemByPos(L, 2);
	printList(L);
	return 0;
}

这段代码实现了单链表的基本操作,包括创建、查找、插入和删除节点。链表是一种动态数据结构,允许在任意位置插入和删除元素。以下是代码的详细说明:

  1. 定义链表节点结构体:定义了一个结构体 LNode,包含两个成员:存储数据的 data 和指向下一个节点的指针 next。同时定义了 LinkList 类型,表示指向 LNode 的指针。

  2. 头插法建立链表headInsertList 函数通过头插法创建链表,步骤如下:

    • 初始化头节点 L
    • 从用户输入读取数据 x
    • 当输入值不是 9999 时,创建新节点,并将其插入到链表的头部。
  3. 尾插法建立链表tailInsertList 函数通过尾插法创建链表,步骤如下:

    • 初始化头节点 L 和尾指针 r
    • 从用户输入读取数据 x
    • 当输入值不是 9999 时,创建新节点,并将其插入到链表的尾部。
    • 最后将尾节点的 next 设为 NULL
  4. 按序号查找节点getElemByPos 函数根据给定的位置 i 查找对应的节点。返回找到的节点指针,若未找到则返回 NULL

  5. 按值查找节点getElemByValue 函数根据给定的值 e 查找对应的节点。返回找到的节点指针,若未找到则返回 NULL.

  6. 在指定位置插入节点insertElemByPos 函数在指定位置 i 插入值为 e 的新节点,步骤如下:

    • 先找到位置 i-1 处的节点 p
    • p 为空,返回 false 表示插入失败。
    • 创建新节点 q,将其插入到 p 的后面。
  7. 删除指定位置节点deleteElemByPos 函数删除位置 i 处的节点,步骤如下:

    • 先找到位置 i-1 处的节点 p
    • p 为空或 p 的后继为空,返回 false 表示删除失败。
    • 删除 p 的后继节点 q,并释放其内存。
  8. 打印链表printList 函数从头节点开始,依次打印链表中每个节点的数据。

  9. 主函数main 函数进行以下操作:

    • 初始化一个链表 L
    • 使用尾插法建立链表。
    • 打印链表内容。
    • 删除位置 2 处的节点。
    • 再次打印链表内容。

通过这段代码,可以灵活地进行链表的创建、查找、插入和删除操作,并在控制台上展示结果。

3.原地逆置链表

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

typedef int ElemType;

typedef struct LNode {
	ElemType data;
	struct LNode* next;
}LNode, * LinkList;

//尾插法建立链表
void tailInsertList(LinkList& L) {
	L = (LinkList)malloc(sizeof(LNode));
	LNode* r, * node;
	r = L;
	ElemType x;
	scanf_s("%d", &x);
	while (x != 9999)
	{
		node = (LNode*)malloc(sizeof(LNode));
		node->data = x;
		r->next = node;
		r = node;
		scanf_s("%d", &x);
	}
	r->next = NULL;
}

//找到中间结点,将链表分成两半
void findMiddle(LinkList L, LinkList& L2) {
	L2 = (LinkList)malloc(sizeof(LNode));//给L2头结点分配内存
	LNode* pcur, * ppre;//pcur走两步,ppre走一步
	pcur = ppre = L->next;//同时指向第一个元素结点
	while (pcur != NULL) {
		pcur = pcur->next;
		if (pcur == NULL)
		{
			break;
		}
		pcur = pcur->next;//走两步
		if (pcur == NULL) {
			break;
		}
		ppre = ppre->next;
	}//结束时ppre处于正中间,
	L2->next = ppre->next;//让L2指向后半条链表
	ppre->next = NULL;//前半条链表最后一个结点断链
}

//原地逆转链表
void reverseList(LinkList L2) {
	LNode* r, * s, * t;
	r = L2->next;//r指向L2第1个结点
	if (r == NULL) {//空链表
		return;
	}
	s = r->next;//r指向L2第2个结点
	if (s == NULL) {//链表只有一个结点
		return;
	}
	t = s->next;
	while (t != NULL)
	{
		s->next = r;
		r = s;
		s = t;
		t = t->next;
	}
	s->next = r;
	L2->next->next = NULL;
	L2->next = s;
}

//合并两个链表
void mergeList(LinkList L, LinkList L2) {
	//pcur指向新链表当前位置,p指向L即将被插入的元素,q指向L2即将被插入的元素
	LNode* pcur, * p, * q;
	pcur = p = L->next;//pcur和p指向L1的第一个结点,建立新链
	q = L2->next;//q指向L2的第一个结点
	p = p->next;//L的第一个结点已经在新链中
	while (p != NULL && q != NULL)
	{
		pcur->next = q;
		q = q->next;
		pcur = pcur->next;
		pcur->next = p;
		p = p->next;
		pcur = pcur->next;
	}
	if (p != NULL) {
		pcur->next = p;
	}
	if (q != NULL) {
		pcur->next = q;
	}
}

//打印链表
void printList(LinkList L) {
	while (L = L->next)
	{
		printf("%3d", L->data);
	}
	printf("\n");
}

int main() {
	LinkList L;
	tailInsertList(L);
	printList(L);
	printf("----------------------------------\n");
	LinkList L2;//后半边链表
	findMiddle(L, L2);//分为两个链表
	printList(L);
	printList(L2);
	printf("----------------------------------\n");
	reverseList(L2);//原地逆转L2
	printList(L2);
	printf("----------------------------------\n");
	mergeList(L, L2);
	free(L2);
	printList(L);
	return 0;
}

这段代码实现了对单链表的创建、分割、逆转和合并操作。以下是代码的详细功能和执行步骤:

  1. 定义链表节点结构体

    • 定义了一个结构体 LNode,包含两个成员:存储数据的 data 和指向下一个节点的指针 next
    • 定义了 LinkList 类型,表示指向 LNode 的指针。
  2. 尾插法建立链表

    • tailInsertList 函数通过尾插法创建链表,步骤如下:
      • 初始化头节点 L 和尾指针 r
      • 从用户输入读取数据 x
      • 当输入值不是 9999 时,创建新节点,并将其插入到链表的尾部。
      • 最后将尾节点的 next 设为 NULL
  3. 找到中间节点,将链表分成两半

    • findMiddle 函数找到链表的中间节点,并将链表分成两半,步骤如下:
      • 初始化两个指针 pcurppre,都指向第一个元素节点。
      • pcur 每次走两步,ppre 每次走一步,直到 pcur 走到链表末尾。
      • 结束时,ppre 位于链表中间。
      • L2 指向后半部分链表,pprenext 设为 NULL,断开前半部分链表。
  4. 原地逆转链表

    • reverseList 函数将链表 L2 原地逆转,步骤如下:
      • 初始化指针 rstr 指向第一个节点,s 指向第二个节点,t 指向第三个节点。
      • snext 指向 r,然后 rst 分别向前移动一位。
      • 继续上述操作,直到 t 为空,链表逆转完成。
  5. 合并两个链表

    • mergeList 函数将链表 LL2 交替合并,步骤如下:
      • 初始化指针 pcur 指向新链表的当前位置,p 指向 L 即将被插入的元素,q 指向 L2 即将被插入的元素。
      • 交替插入 pq 到新链表中,直到 pq 为空。
      • p 不为空,将剩余的 p 接到新链表末尾。
      • q 不为空,将剩余的 q 接到新链表末尾。
  6. 打印链表

    • printList 函数从头节点开始,依次打印链表中每个节点的数据。
  7. 主函数

    • main 函数进行以下操作:
      • 初始化一个链表 L 并通过尾插法建立链表。
      • 打印链表内容。
      • 调用 findMiddle 函数将链表分为两半,分别打印前半部分和后半部分。
      • 调用 reverseList 函数逆转后半部分链表,并打印结果。
      • 调用 mergeList 函数合并两个链表,释放 L2 的内存,并打印最终合并的链表。

这段代码通过一系列的操作展示了链表的基本操作及其应用,能够处理链表的分割、逆转和合并等复杂操作。

4.单链表的基本操作

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

typedef int ElemType;

typedef struct LNode {
	ElemType data;
	struct LNode* next;
}LNode, * LinkList;


//尾插法建立链表
LinkList tailInserList(LinkList& L) {
	L = (LNode*)malloc(sizeof(LNode));
	LNode* r, * s;
	r = L;
	ElemType x;
	scanf_s("%d", &x);
	while (x != 9999)
	{
		s = (LNode*)malloc(sizeof(LNode));
		s->data = x;
		r->next = s;
		r = s;
		scanf_s("%d", &x);
	}
	r->next = NULL;
	return L;
}

//按位置查找元素
LNode* getElemByPos(LinkList L, int i) {
	LNode* p;
	int j = 1;
	p = L->next;
	if (i < 0) {
		return NULL;
	}
	if (i == 0)
	{
		return L;
	}
	while (p && j < i)
	{
		p = p->next;
		j++;
	}
	return p;
}

//按位置插入元素
bool insertElemByPos(LinkList L, int i, ElemType e) {
	LNode* p = getElemByPos(L, i - 1);
	if (p == NULL) {
		return false;
	}
	LNode* q = (LNode*)malloc(sizeof(LNode));
	q->data = e;
	q->next = p->next;
	p->next = q;
	return true;
}

//按位置删除元素
bool deleteElemByPos(LinkList L, int i) {
	LNode* p = getElemByPos(L, i - 1);
	if (p == NULL) {
		return false;
	}
	LNode* q = p->next;
	if (q == NULL) {
		return false;
	}
	p->next = q->next;
	free(q);
	q = NULL;
	return true;
}

//打印链表
void printList(LinkList L) {
	while (L = L->next)
	{
		printf("%3d", L->data);
	}
	printf("\n");
}

int main() {
	LinkList L;
	tailInserList(L);
	printf("%d\n", getElemByPos(L, 2)->data);
	insertElemByPos(L, 2, 99);
	printList(L);
	deleteElemByPos(L, 4);
	printList(L);

	return 0;
}

这段代码实现了一个单链表的基本操作,包括链表的创建、按位置查找、按位置插入和按位置删除元素,以及打印链表。以下是代码的详细说明:

  1. 定义链表节点结构体

    • 定义了一个结构体 LNode,包含两个成员:存储数据的 data 和指向下一个节点的指针 next
    • 定义了 LinkList 类型,表示指向 LNode 的指针。
  2. 尾插法建立链表

    • tailInserList 函数通过尾插法创建链表,步骤如下:
      • 初始化头节点 L 和尾指针 r
      • 从用户输入读取数据 x
      • 当输入值不是 9999 时,创建新节点 s,并将其插入到链表的尾部。
      • 最后将尾节点的 next 设为 NULL
      • 返回链表的头指针 L
  3. 按位置查找元素

    • getElemByPos 函数根据给定的位置 i 查找对应的节点,步骤如下:
      • 初始化指针 p,指向头节点的下一个节点,计数器 j 从1开始。
      • i 小于0,返回 NULL
      • i 为0,返回头节点 L
      • 遍历链表,直到找到位置 i 的节点,返回该节点指针,若未找到则返回 NULL
  4. 按位置插入元素

    • insertElemByPos 函数在指定位置 i 插入值为 e 的新节点,步骤如下:
      • 先找到位置 i-1 处的节点 p
      • p 为空,返回 false 表示插入失败。
      • 创建新节点 q,将其插入到 p 的后面。
      • 返回 true 表示插入成功。
  5. 按位置删除元素

    • deleteElemByPos 函数删除位置 i 处的节点,步骤如下:
      • 先找到位置 i-1 处的节点 p
      • p 为空或 p 的后继为空,返回 false 表示删除失败。
      • 删除 p 的后继节点 q,并释放其内存。
      • 返回 true 表示删除成功。
  6. 打印链表

    • printList 函数从头节点开始,依次打印链表中每个节点的数据。
  7. 主函数

    • main 函数进行以下操作:
      • 初始化一个链表 L 并通过尾插法建立链表。
      • 打印链表中第2个位置的元素值。
      • 在第2个位置插入值为99的新节点,并打印链表。
      • 删除第4个位置的节点,并打印链表。

通过这段代码,用户可以创建一个链表,并进行查找、插入、删除和打印操作,以方便地操作和管理链表中的数据。

5.顺序栈(使用数组实现的栈)的基本操作

#include <stdio.h>

#define MaxSize 50

typedef int ElemType;

typedef struct {
	ElemType data[MaxSize];
	int top;
}SqStack;

//栈初始化
void initStack(SqStack &S) {
	S.top = -1;
}

//判断栈空
bool emptyStack(SqStack	S) {
	if (S.top == -1)
	{
		return true;
	}
	return false;
}

//入栈
bool pushStack(SqStack &S, ElemType e) {
	if (S.top == MaxSize - 1) {
		return false;
	}
	S.data[++S.top] = e;
	return true;
}

//出栈
bool popStack(SqStack& S, ElemType& e) {
	if (S.top == -1)
	{
		return false;
	}
	e = S.data[S.top--];
	return true;
}

//获取栈顶元素
bool getTopStack(SqStack S, ElemType &e) {
	if (S.top == -1) {
		return false;
	}
	e = S.data[S.top];
	return true;
}

int main() {
	SqStack S;
	bool flag;
	ElemType e;
	initStack(S);
	flag = emptyStack(S);
	if (flag)
	{
		printf("栈空\n");
	}
	pushStack(S, 3);
	pushStack(S, 4);
	pushStack(S, 5);
	flag = getTopStack(S, e);
	if (flag)
	{
		printf("栈顶元素是%d\n", e);
	}
	flag = popStack(S, e);
	if (flag)
	{
		printf("弹出元素是%d\n", e);
	}
	return 0;
}

这段代码实现了一个顺序栈(使用数组实现的栈)的基本操作,包括初始化栈、判断栈是否为空、入栈、出栈和获取栈顶元素。以下是代码的详细说明:

  1. 定义顺序栈结构体

    • SqStack 结构体包含一个存储数据的数组 data 和一个表示栈顶位置的变量 top
  2. 栈初始化

    • initStack 函数将栈的 top 初始化为 -1,表示栈为空。
  3. 判断栈是否为空

    • emptyStack 函数检查栈的 top 是否为 -1,如果是,则返回 true 表示栈为空,否则返回 false
  4. 入栈操作

    • pushStack 函数将元素 e 压入栈中,步骤如下:
      • 检查栈是否已满(top 是否等于 MaxSize - 1),若满则返回 false 表示入栈失败。
      • 否则,将 e 存入 data 数组中 top 的下一个位置,并更新 top
      • 返回 true 表示入栈成功。
  5. 出栈操作

    • popStack 函数从栈中弹出一个元素,步骤如下:
      • 检查栈是否为空(top 是否为 -1),若空则返回 false 表示出栈失败。
      • 否则,将 data 数组中 top 位置的元素赋值给 e,并更新 top
      • 返回 true 表示出栈成功。
  6. 获取栈顶元素

    • getTopStack 函数获取栈顶元素,步骤如下:
      • 检查栈是否为空(top 是否为 -1),若空则返回 false 表示获取栈顶元素失败。
      • 否则,将 data 数组中 top 位置的元素赋值给 e
      • 返回 true 表示获取栈顶元素成功。
  7. 主函数

    • main 函数进行以下操作:
      • 初始化一个栈 S
      • 检查栈是否为空并打印结果。
      • 将元素 345 依次压入栈中。
      • 获取栈顶元素并打印结果。
      • 从栈中弹出一个元素并打印结果。

这段代码演示了如何使用顺序栈存储和管理数据,通过一系列的栈操作展示了栈的基本功能。

6.顺序循环队列的基本操作

#include <stdio.h>

#define MaxSize 5

typedef int ElemType;

//顺序循环队列
typedef struct {
	ElemType data[MaxSize];
	int front, rear;
}SqQueue;

//循环队列初始化
void initQueue(SqQueue& Q) {
	Q.front = Q.rear = 0;
}

//队列判空
bool emptyQueue(SqQueue Q) {
	if (Q.rear == Q.front)
	{
		return true;
	}
	return false;
}

//入队
bool enQueue(SqQueue& Q, ElemType e) {
	if ((Q.rear + 1) % MaxSize == Q.front) {
		return false;
	}
	Q.data[Q.rear] = e;
	Q.rear = (Q.rear + 1) % MaxSize;
	return true;
}

//出队
bool deQueue(SqQueue& Q, ElemType& e) {
	if (Q.rear == Q.front) {
		return false;
	}
	e = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;
	return true;
}
int main() {
	SqQueue Q;
	bool ret;
	ElemType e;
	initQueue(Q);
	ret = emptyQueue(Q);
	if (ret)
	{
		printf("栈空\n");
	}
	enQueue(Q, 3);
	enQueue(Q, 4);
	enQueue(Q, 5);
	enQueue(Q, 6);
	ret = enQueue(Q, 7);
	if (!ret) {
		printf("入队失败\n");
	}
	ret = deQueue(Q, e);
	if (ret)
	{
		printf("出队成功,元素为%d\n", e);
	}
	return 0;
}

这段代码实现了一个顺序循环队列的基本操作,包括初始化队列、判断队列是否为空、入队和出队。以下是代码的详细说明:

  1. 定义顺序循环队列结构体

    • SqQueue 结构体包含一个存储数据的数组 data 和两个整型变量 frontrear,分别表示队列的头部和尾部位置。
  2. 循环队列初始化

    • initQueue 函数将队列的 frontrear 初始化为 0,表示队列为空。
  3. 判断队列是否为空

    • emptyQueue 函数检查 rear 是否等于 front,如果相等,则返回 true 表示队列为空,否则返回 false
  4. 入队操作

    • enQueue 函数将元素 e 入队,步骤如下:
      • 检查队列是否已满((rear + 1) % MaxSize 是否等于 front),若满则返回 false 表示入队失败。
      • 否则,将 e 存入 data 数组的 rear 位置,并更新 rear
      • 返回 true 表示入队成功。
  5. 出队操作

    • deQueue 函数从队列中出队一个元素,步骤如下:
      • 检查队列是否为空(rear 是否等于 front),若空则返回 false 表示出队失败。
      • 否则,将 data 数组的 front 位置的元素赋值给 e,并更新 front
      • 返回 true 表示出队成功。
  6. 主函数

    • main 函数进行以下操作:
      • 初始化一个队列 Q
      • 检查队列是否为空并打印结果。
      • 将元素 3456 依次入队。
      • 尝试将元素 7 入队,由于队列已满,打印入队失败信息。
      • 从队列中出队一个元素并打印结果。

这段代码展示了如何使用顺序循环队列存储和管理数据,通过一系列的队列操作展示了队列的基本功能。

7.链式队列的基本操作

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

typedef int ElemType;

typedef struct LinkNode {
	ElemType data;
	struct LinkNode* next;
}LinkNode;

typedef struct {
	LinkNode* front, * rear;
}LinkQueue;

//初始化队列
void initQueue(LinkQueue& Q) {
	Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));//指向头结点
	Q.front->next = NULL;
}

//入队
bool enQueue(LinkQueue& Q, ElemType e) {
	LinkNode* p = (LinkNode*)malloc(sizeof(LinkNode));
	p->data = e;
	p->next = NULL;
	Q.rear->next = p;
	Q.rear = p;
	return true;
}

//出队
bool deQueue(LinkQueue& Q, ElemType& e) {
	if (Q.front == Q.rear) {
		return false;
	}
	LinkNode* q = Q.front->next;
	e = q->data;
	Q.front->next = q->next;
	if (q == Q.rear) {//队列只有一个元素
		Q.rear = Q.front;//将队列置空
	}
	free(q);
	return true;
}

int main() {
	LinkQueue Q;
	initQueue(Q);
	enQueue(Q, 3);
	enQueue(Q, 4);
	ElemType e;
	deQueue(Q, e);
	printf("%d\n", e);
	deQueue(Q, e);
	printf("%d\n", e);
	if (!deQueue(Q, e)) {
		printf("队空\n");
	}
	printf("%d\n", deQueue(Q, e));
	return 0;
}
  • 11
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

juechen333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值