《数据结构》第三章算法设计题--栈和队列

本系列主要为了记录在江财的暑期小学期中的刷严蔚敏、李冬梅、吴伟乐版《数据结构 c语言第2版》的算法设计题,主要包括三部分内容,第一部分为对不熟悉的知识点重新回顾总结,第二部分为算法设计题的代码,第三部分为刷题总结;共勉 💪

回顾部分不熟的知识点



刷题部分

3.1

//共享栈节点结构
typedef struct {
	int top[2], bot[2];
	ElementType *T;
	int m;
}DblStack;

//初始化
void IniteStack(DblStack& s) {
	s.m = MAX;
	s.top[0] = -1;
	s.top[1] = s.m;
	s.bot[0] = -1;
	s.bot[1] = s.m;
	s.T = new ElementType[s.m];
}

//判断栈空
bool Stack0Empty(DblStack& s) {
	if (s.top[0] == -1) {
		return true;
	}
	else {
		return false;
	}
}
bool Stack1Empty(DblStack& s) {
	if (s.top[1] == s.m) {
		return true;
	}
	else {
		return false;
	}
}


//判断栈满
bool StackFull(DblStack& s) {
	if (s.top[0] == s.top[1] - 1) {
		return true;
	}
	else {
		return false;
	}
}


//进栈
bool Push0(DblStack& s, ElementType x) {
	if (StackFull(s)) {
		return false;
	}
	else {
		s.top[0] += 1;
		s.T[s.top[0]] = x;
		return true;
	}
}
bool Push1(DblStack& s, ElementType x) {
	if (StackFull(s)) {
		return false;
	}
	else {
		s.top[1] -= 1;
		s.T[s.top[1]] = x;
		return true;
	}
}


//出栈
bool Pop0(DblStack& s, ElementType& x) {
	if (Stack0Empty(s)) {
		return false;
	}
	else {
		x = s.T[s.top[0]];
		s.top[0] -= 1;
		return true;
	}
}






3.2

//判断回文,arr为字符序列,n为序列长度
bool IsPalindrome(ElementType arr[], int n) {
	DblStack s;//为了方便,使用3.1的共享栈存储字符序列的前半段数据
	IniteStack(s);
	int i;
	int mid = n / 2;

	for (i = 0; i < mid; ++i) {
		Push0(s, arr[i]);
	}
	if (n % 2 == 1) {//如果字符序列的个数是	奇数,跳过中间的数
		i = i + 1;
	}

	//对比从栈中弹出的元素和字符序列后半部的元素 比较
	while (i < n && !Stack0Empty(s)) {
		ElementType x;
		Pop0(s, x);
		if (arr[i++] != x) {
			return false;//有一个字符不相等便说明不是回文
		}
	}
	return true;

}

3.3

//为了能使用3.1的栈结构,此题改成字符序列,以 # 结束;
void Input_stack() {

	ElementType x, t;
	DblStack s;
	IniteStack(s);
	cout << "亲,请输入字符,以空格分隔,以 # 结束,结束输入请按回车键:";
	cin >> x;

	while (x != '#') {
		if (StackFull(s)) {
			cout << "栈满" << endl;
			break;
		}
		Push0(s, x);
		cin >> x;

	}
	Pop0(s, t);
	cout << "栈顶元素为:" << t << endl;
}


3.4

//3.10.1  求最大整数
int GetMax(linklist& l) {
	if (l->next->next == NULL) {
		return l->next->data;
	}
	else {
		int a = GetMax(l->next);
		return l->next->data > a ? l->next->data : a;
	}
}

//3.10.2  求节点数
int CountNode(linklist& l) {
	if (l->next == NULL) {
		return 0;
	}
	else {
		return 1 + CountNode(l->next);
	}
}

//3.10.3  求所有节点值的平均值,presum和num的初值为0
int GetAverage(linklist& l, double presum, int num) {
	if (l->next == NULL) {
		return presum / num;
	}
	else {
		return GetAverage(l->next, presum + l->next->data, num + 1);
	}
}

栈、递归和队列的总结:

  1. 栈和队列的题目万变不离其宗,紧抓栈FILO,队列FIFO的基本定义和在顺序存储或链式存储下的基本操作;

  2. 递归的构成要素和三种形式

    • 递归的构成要素

      • 终止条件(eg:Fibonaci中的当n>=0时才执行)
      • 基本动作(eg:Fibonaci中n=0和n=1时返回0和1)
      • 递归体(eg:Fibonaci中当n>1时返回F(n-1)+F(n-2))
    • 递归的三种形式

      • 问题的定义是递归的;(eg:阶乘、Fibonaci数列)
      • 问题的求解方式是递归的;(eg:汉诺塔问题)
      • 数据结构是递归的;(eg:二叉树)

测试代码

今天有时间,测试代码也写出来了,如果想要验证题目代码,大家可以将函数代码复制到测试代码中;

#include <iostream>
#define ElementType char
#define MAX 10  //共享栈最大容量
using namespace std;
#define NUM 10  //单链表最大长度



//——————单链表结构和创建方法开始——————
//链表节点
typedef struct linknode {
	int data;
	struct linknode *next;
}linknode, *linklist;

//初始化
void Initelist(linklist& listedsq) {
	listedsq = new linknode;
	listedsq->data = 0;
	listedsq->next = NULL;
}
//插入节点(头插)
bool head_Insert(linknode *head, int value) {
	linknode *s = new linknode;
	s->data = value;
	s->next = head->next;
	head->next = s;
	return true;
}
//生成一个大小为n的随机数列,从A[1]开始存储
int* CreatArray(int n) {
	int *A;
	A = new int[n + 1];

	for (int i = 1; i <= n; ++i) {

		A[i] = rand() % 100;
	}

	return A;

}


//打印数列的所有元素
void PrintArray(int A[], int n) {

	for (int i = 1; i <= n; ++i) {
		cout << A[i] << " ";
	}
	cout << endl;
}


//由随机数组创建一个随机链表
void CreateRandomlinklist(linklist& l) {
	int *arr = CreatArray(NUM);
	cout << "随机数组为:";
	PrintArray(arr, NUM);
	Initelist(l);

	for (int i = 1; i <= NUM; ++i) {
		head_Insert(l, arr[i]);
	}

}

//-------单链表结构和创建链表的方法结束——————

//3.1
//共享栈


//3.2
//判断回文,arr为字符序列,n为序列长度

//3.3
//为了能使用3.1的栈结构,此题改成字符序列,以 # 结束;


//3.10
//关于带头节点单链表的递归算法
//对题进行分析,3小题如果不使用递归,都是一次遍历能解决的问题,
//如果使用递归,可以知道单链表本身是递归的(前驱-后继形式),属于总结中的第2中形式(总结在本文的第三部分);

//3.10.1  求最大整数

//3.10.2  求节点数

//3.10.3  求所有节点值的平均值,presum和num的初值为0




int main()
{
	//测试3.1
	DblStack s;
	ElementType x;
	IniteStack(s);
	Push0(s, '5');
	Pop0(s, x);
	cout << "操作成功弹出:" << x << endl;

	//测试3.2
	ElementType arr[] = { 'a','b','c','g','c','b','a' };
	cout << "是否是回文:" << IsPalindrome(arr, 7) << endl;
	cout << "是否是回文:" << IsPalindrome(arr, 6) << endl;

	//测试3.3
	Input_stack();


	//测试3.10
	linklist l;
	CreateRandomlinklist(l);
	cout << "链表中的最大整数:" << GetMax(l) << endl;
	cout << "链表节点数:" << CountNode(l) << endl;
	cout << "链表中所有整数的平均值:" << GetAverage(l, 0, 0) << endl;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1章 绪论 1.1 数据结构的基本概念和术语 1.1.1 引言 1.1.2 数据结构有关概念及术语 1.1.3 数据结构和抽象数据类型(ADT) 1.2 算法描述与分析 1.2.1 什么是算法 1.2.2 算法描述工具——C语言 1.2.3 算法分析技术初步 习一 第2章 线性表 2.1 线性表的定义及其运算 2.1.1 线性表的定义 2.1.2 各种运算简介 2.2 线性表的顺序存储结构(向量) 2.2.1 顺序存储结构(向量) 2.2.2 向量中基本运算的实现 2.3 线性表的链表存储结构 2.3.1 单链表与指针 2.3.2 单链表的基本运算 2.4 循环链表和双向链表 2.4.1 循环链表 2.4.2 双向链表 2.4.3 顺序存储结构与链表存储结构的综合分析与比较 2.5 多项式相加问 2.5.1 多项式相加的链表存储结构 2.5.2 多项式相加的算法实现 2.6 线性表的算法实现举例 2.6.1 实现线性表顺序存储结构及运算的C语言源程序 2.6.2 单链表处理的C语言源程序 习二 第3章 栈和队列 3.1 3.1.1 的定义及其运算 3.1.2 的顺序存储结构(向量) 3.1.3 的链表存储结构 3.1.4 的应用 3.2 队列 3.2.1 队列的定义及运算 3.2.2 队列的顺序存储结构(向量) 3.2.3 队列的链表存储结构 3.3 栈和队列算法实现举例 习三 第4章 串 4.1 串的基本概念 4.2 串的存储结构 4.2.1 串的顺序存储 4.2.2 串的链表存储 4.2.3 串变量的存储映象 4.3 串的运算 4.3.1 串的运算简介 4.3.2 串的匹配运算 4.4 文本编辑 习四 第5章 数组和广义表 5.1 数组的基本概念 5.1.1 数组的概念 5.1.2 数组的顺序表示 5.1.3 特殊矩阵的压缩存储 5.2 稀疏矩阵的三元组存储 5.2.1 三元组表 5.2.2 稀疏矩阵的运算 5.3 稀疏矩阵的十字链表存储 5.3.1 十字链表的组成 5.3.2 十字链表的有关算法 5.4 广义表 5.4.1 广义表的概念和特性 5.4.2 广义表的存储结构 5.4.3 求广义表的深度 5.4.4 广义表的输出 5.4.5 建立广义表的存储结构 5.5 迷宫问五 第6章 树 6.1 树的基本概念和术语 6.1.1 树的定义 6.1.2 树的常用术语 6.1.3 树的表示方法 6.2 二叉树 6.2.1 二叉树的定义 6.2.2 二叉树的重要性质 6.2.3 二叉树的存储结构 6.2.4 二叉树二叉链表的一个生成算法 6.3 遍历二叉树 6.3.1 先根遍历 6.3.2 中根遍历 6.3.3 后根遍历 6.3.4 二叉树遍历算法的应用 6.4 线索二叉树 6.4.1 线索二叉树的基本概念 6.4.2 线索二叉树的逻辑表示图 6.4.3 中根次序线索化算法 6.4.4 在中根线索树上检索某结点的前趋或后继 6.4.5 在中根线索树上遍历二叉树 6.5 二叉树、 树和森林 6.5.1 树的存储结构 6.5.2 树与二叉树之间的转换 6.5.3 森林与二叉树的转换 6.5.4 一般树或森林的遍历 6.6 树的应用 6.6.1 二叉排序树 6.6.2 哈夫曼树及其应用 6.7 二叉树的建立和遍历C语言源程序示例 习六 第7章 图 7.1 图的基本概念和术语 7.1.1 图的基本概念 7.1.2 路径和回路 7.1.3 连通图 7.1.4 顶点的度 7.2 图的存储结构 7.2.1 邻接矩阵 7.2.2 邻接链表 7.3 图的遍历和求图的连通分量 7.3.1 图的建立 7.3.2 图的遍历 7.3.3 求图的连通分量 7.4 图的生成树 7.4.1 生成树的概念 7.4.2 最小生成树 7.4.3 普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法 7.5 最短路径 7.5.1 单源顶点最短路径问求解 7.5.2 求有向网中每对顶点间的路径 7.6 有向无环图及应用 7.6.1 拓扑排序 7.6.2 关键路径 7.7 图的算法C语言程序实现举例 7.7.1 无向图的邻接表的建立和遍历 7.7.2 有向无环图的拓扑排序和求关键路径 习七 第8章 查找 8.1 基本概念

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值