通过栈判断链表是否对称
设单链表的表头指针为L,data域为字符型,判断该链表的全部n个字符是否中心对称
xyx,xyyx
算法思想
使用栈来判断链表中的数据是否中心对称,让链表的前一半元素依次进栈
在处理链表的后一半元素时,当访问到链表的一个元素后,就从栈中弹出一个元素,两个元素比较,若相等,则将链表中的下一个元素与栈中再弹出的元素进行比较,直至链表尾。这时若栈是空栈,则得出链表中心对称的结论;否则当链表中的元素与栈中弹出元素不等时,结论为链表非中心对称,结束算法的执行
假设n是奇数,5
n/2=2,前两个元素入栈
![![[Pasted image 20241115141716.png]]](https://i-blog.csdnimg.cn/direct/12eed713af0040adbb09cf1448e4c20b.png)
创建s字符数组,大小是n/2=2
![![[Pasted image 20241115141836.png]]](https://i-blog.csdnimg.cn/direct/27b491d689e348afa6dfde39a53a7ff2.png)
用i开始遍历数组,同时cur指针遍历链表,将链表前半的数据入栈
![![[Pasted image 20241115142006.png]]](https://i-blog.csdnimg.cn/direct/7690de8ae5be413bb395a5489c342444.png)
![![[Pasted image 20241115142021.png]]](https://i-blog.csdnimg.cn/direct/c5903408d0194e1e8232bf185e9086a2.png)
入栈完毕,如果n是偶数,则这时cur直接指向后半部分的首元素,由于这里n是奇数cur指向中间元素,需要后移一位
![![[Pasted image 20241115142222.png]]](https://i-blog.csdnimg.cn/direct/29cd8bd6333644a6b2a9b6c9003149eb.png)
由于for循环最后一轮是i=2=n/2,循环结束
所以需要将i–,让i指向栈顶元素
通过while循环判断是否中心对称
若d4等于s1,i–,cur指向cur的next
![![[Pasted image 20241115142803.png]]](https://i-blog.csdnimg.cn/direct/0e9ea6e3c2b749069fc8a0eca01f0c6f.png)
若d5等于s0,i–,cur指向cur的next
这时cur指向NULL,循环结束
此时i=-1,说明链表中心对称,返回true
bool dc(LinkList L, int n)
{
int i;
// s字符栈
char s[n/2];
// 工作指针cur,指向待处理的当前元素
LNode* cur = L->next;
// 链表前一半元素入栈
for (i = 0; i < n; i++)
{
s[i] = cur->data;
cur = cur->next;
}
// 恢复最后的i值
i--;
// 若n是奇数,后移过中心节点
if (n % 2 == 1)
cur = cur->next;
// 检测是否中心对称
while (cur && s[i] == cur->data)
{
// i充当栈顶指针
i--;
cur = cur->next;
}
// 若栈为空栈
if (i == -1)
// 链表中心对称
return true;
else
// 链表中心不对称
return false;
}
共享栈入栈出栈
设有两个栈S1和S2都采用顺序栈的方式,并共享一个存储区,0-maxsize-1,为了尽量利用空间,减少溢出的可能,可采用栈顶相向,迎面增长的存储方式
实现入栈和出栈
算法思想
两个栈共享向量空间,将两个栈的栈底设在向量两端,初始时,S1栈顶指针为-1,S2栈顶指针为maxsize,两个栈顶指针相邻时为栈满
两个栈顶相向,迎面增长,栈顶指针指向栈顶元素
top指向的是栈顶元素,所以入栈的时候,先移动top指针,然后再输入x
出栈的时候,先返回出栈的元素值,再移动top指针
![![[Pasted image 20241115145446.png]]](https://i-blog.csdnimg.cn/direct/d4628c70506b48048925488d1a5f7fb7.png)
#define maxsize 100
// 两个栈共享顺序存储空间所能达到的最多元素数,初始化为100
#define ElemType int
// 假设元素类型为整型
typedef struct
{
// 栈空间
ElemType st[maxsize];
// top为两个栈顶指针
int top[2];
}ST;
ST s;
// 入栈操作,i为栈号,i=0表示S1栈,i=1表示S2栈,x是入栈元素
// 入栈成功返回1,否则返回0
int push(int i, ElemType x)
{
// 如果i不是0也不是1,退出程序
if (i < 0 || i > 1)
{
printf("栈号输入错误");
exit(0);
}
// 如果两个栈顶指针相差1,即相邻,表示栈满
if (s.top[1] - s.top[0] == 1)
{
printf("栈已满");
return 0;
}
switch(i)
{
// 输入0,在S1栈输入x
case 0:
// 先移动top0,再输入x
s.st[++s.top[0]] = x;
return 1;
break;
case 1:
// 先移动top1,再输入x
s.st[--s.top[1]] = x;
return 1;
}
}
// 出栈算法,i表示栈号,0表示S1栈,1表示S2栈
int pop(int i)
{
if (i < 0 || i > 1)
{
printf("栈号输入错误");
exit(0);
}
switch(i)
{
case 0:
// 如果top0指向-1,表示S1栈空
if (s.top[0] == -1)
{
printf("栈空\n");
return -1;
}
else
// 先返回栈顶元素,再移动top0指针
return s.st[s.top[0]--];
break;
case 1:
if (s.top[1] == maxsize)
{
printf("栈空\n");
return -1;
}
else
return s.st[s.top[1]++];
break;
}
}
括号匹配
设表达式以字符形式已存入数组E[n]中,’#‘为表达式的结束符
判断表达式中的括号是否配对:EXYX(E)
算法思想
判断表达式中的括号是否匹配,可以通过栈,是左括号时进栈,右括号时出栈
出栈时,若栈顶元素是左括号,则新读入的右括号与栈顶左括号就可以消去
输入表达式结束时,栈空则正确,否则括号不匹配
int EXYX(char E[], int n)
{
// s是一维数组,容量足够大,用作存放括号的栈
char s[30];
// 用top做括号的栈顶指针
int top = 0;
// #先入栈,用于和表达式结束符号#匹配
s[top] = '#';
// 字符数组的工作指针
int i = 0;
// 逐字符处理字符表达式的数组
while (E[i] != '#')
{
switch(E[i])
case '(':
// 左括号,入栈
s[++top] = '(';
i++;
break;
case ')':
// 右括号,如果和栈顶匹配,左括号出栈
if (s[top] == '(')
{
top--;
i++;
break;
}
else
{
printf("括号不配对");
exit(0);
}
case '#':
if (s[top] == '#')
{
pritnf("括号配对");
return 1;
}
else
{
printf("括号不配对");
return 0;
}
default:
i++;
}
}
多种括号配对
设计一个算法,判断一个算数表达式中的括号是否匹配,算数表达式保存在带头节点的单循环链表中,每个节点有两个域,ch和next
算法思想
括号有三种圆括号,方括号和大括号
使用栈,当为左括号时,入栈,右括号时,若栈顶是其对应的左括号,则出栈,若不是其对应的左括号,则结论为括号不配对,
当表达式结束,若栈为空,则结论表达式括号配对,否则,结论表达式括号不配对
int Match(LinkList L)
{
char s[];
LNode* cur = L->next;
STInit(s);
while (cur != L)
{
switch (cur->ch)
{
case '(':
STPush(s, cur->ch);
break;
case ')':
if (STEmpty(s) || STTop(s) != '(')
{
printf("括号不配对");
return 0;
}
else
{
STPop(s);
break;
}
case '[':
STPush(s, cur->ch);
break;
case ']':
if (STEmpty(s) || STTop(s) != '[')
{
printf("括号不配对");
return 0;
}
else
{
STPop(s);
break;
}
case '{':
STPush(s, cur->ch);
break;
case '}':
if (STEmpty(s) || STTop(s) != '{')
{
printf("括号不配对");
return 0;
}
else
{
STPop(s);
break;
}
}
cur = cur->next;
}
if (STEmpty(s))
{
printf("括号配对");
return 1;
}
else
{
printf("括号不配对");
return 0;
}
}
递归求序列最大值
设整数序列a1,a2,…,an,使用递归思想求解最大值
int findMax(int a[], int left, int right)
{
if(left == right)
{
return a[left];
}
int mid = (left + right) / 2;
int leftMax = findMax(a, left, mid);
int rightMax = findMax(a, mid + 1, right);
return max(leftMax, rightMax);
}
链表对称及括号匹配等算法思想
667

被折叠的 条评论
为什么被折叠?



