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

本系列主要为了记录在江财的暑期小学期中的刷严蔚敏、李冬梅、吴伟乐版《数据结构 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
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值