本系列主要为了记录在江财的暑期小学期中的刷严蔚敏、李冬梅、吴伟乐版《数据结构 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);
}
}
栈、递归和队列的总结:
-
栈和队列的题目万变不离其宗,紧抓栈FILO,队列FIFO的基本定义和在顺序存储或链式存储下的基本操作;
-
递归的构成要素和三种形式
-
递归的构成要素
- 终止条件(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;
}