目录
标黄表示重点,亮蓝色鸡汤hhh
这次是P17的笔记✌
视频教程地址👇
http://www.bilibili.com/video/BV1Fv4y1f7T1?p=17&vd_source=02dfd57080e8f31bc9c4a323c13dd49c
接触数组和链表也有一段时间了,浅浅觉得数组比链表简洁很多(代码短hh
补充知识:c++中stack类
stack类是c++ STL容器中的一种,嗯,STL是个挺常见的知识类好像,本小白还没有仔细了解过,只是在现阶段数据结构算法的学习上,有些涉及到其中一些应用。比如这里的stack类,还有之前使用过的vector容器。还是老样子,遇到陌生的知识不用担心,需要用什么随时补充就好。这里就浅浅了解一下stack把。现在够用即可。以我现在粗浅的认知,这些类呀什么的,就是封装了一些常用的函数,需要使用的时候直接调用即可。
在stack类中,封装的有下面这些函数:
push(x):在栈顶添加元素x。(调用时需要有参数哦
pop():删除栈顶元素。(无参数
top():返回当前栈顶元素
empty():判断栈是否为空。返回类型是布尔值真或者假。无参数
size():返回栈的大小。(这里栈的大小表示的是栈中元素的个数哈
这里我提到有无参数的原因是在我最开始刚接触这些东西的时候,认识并不清晰,有时候会忘记写括号[笑]。哦,那也应该强调一下,这些都是封装好的函数哦。
数组实现栈---反转字符串
数组来反转思路就是,先建立一个栈,将数组元素按顺序入栈,再通过依次出栈来给数组的元素重新赋值即可。
数组实现比较简单,我们在写Reverse函数的时候,需要有两个参数,一个是需要反转的数组,一个是数组的大小。前者很容易理解,我们想反转它,肯定需要它,后者,由于我们在反转过程中是需要通过数组的大小来确定循环的终止条件的,所以需要提前在主函数中使用strlen函数计算并传参。记得引头文件#include<cstring>
代码如下
//用栈反转字符串
#include <iostream>
#include <stack>
#include <cstring>
using namespace std;
// 数组呈现的栈
void Reverse(char C[], int n)
{
stack<char> S;
//入栈
for (int i = 0; i < n; i++)
{
S.push(C[i]);
}
for (int i = 0; i < n; i++)
{
C[i] = S.top();//逆序了
S.pop();
}
}
int main()
{
char C[51];
printf("Enter a string: ");
gets(C);
Reverse(C, strlen(C));
printf("Output = %s", C);
return 0;
}
链表实现栈--反转字符串
相比数组,链表就复杂多了。造成这样的主要原因就是,链表的插入元素的过程比较复杂[hh这好像也是这两者唯一的区别]。这个在前面的内容里都提到过,就不再重复叙述啦。
这里默认插入方式为:从链表头部插入。这部分内容也都讲过咯。(所以想一下,我们插入节点的顺序其实就是反转之后的顺序对吧
就主要叙述反转函数的实现把。
我们不需要传递任何参数,第一,因为链表通过头节点索引,头节点我们定义为全局变量,程序的任何地方都可以使用;第二,链表区别于数组就是并不需要预先知道数组中有多少个元素,通过每个节点的地址位即可依次索引到链表末尾,即NULL来判断即可。
首先判断链表是否为空,好像关于链表的很多操作都是需要判断是否为空的,是因为链表并不预先知道其中的元素个数。
当不为空的时候,我们的操作才有意义。创建一个栈,将链表的元素依次入栈,这里使用while循环。
注意:①需要创建一个临时节点并赋值为头节点top来代替top本身进行下面需要的遍历操作,这是为了避免丢失头节点从而丢失该链表。(也是老朋友了
②循环的出口,从temp=头节点开始,在链表中还有元素时就一直执行入栈,每次更新temp的值使其指向下一个节点。
入栈之后,就是一个中转站了
temp=S.top();//这里将temp这个临时节点赋值为 栈顶的元素 即链表的最后一个元素
top=temp;//将链表的头节点 赋值为 链表的最后一个元素->反转的第一步 这样后面对temp之后结点的更改也就真实的改变了原链表的每个元素咯(值的覆盖
S.pop();//反转的第一个节点出栈
其后就是while循环当栈中还有元素时就一直进行出栈进行链表元素的重新赋值。记得将最后一个元素指向NULL作为链表结束的标志
代码如下
#include<iostream>
#include<stack>
using namespace std;
//节点
struct Node
{
char data;
Node* link;
};
//建立链表 实现栈
struct Node* top=NULL;
void Push(int x)
{
struct Node *temp = (struct Node *)malloc(sizeof(struct Node *));
temp->data = x;
temp->link = top;
top = temp;
}
void Reverse()
{
if(top==NULL)//空表
{
return;
}
stack<struct Node*> S;//创建了一个 元素为节点类型 的栈
Node* temp=top;
//从链表第一个元素开始 按顺序将元素入栈
while(temp!=NULL){
S.push(temp);
temp=temp->link;//最后一次循环将temp赋值为 链表的最后一个节点
}
temp=S.top();//这里将temp这个临时节点赋值为 栈顶的元素 即链表的最后一个元素
top=temp;//将链表的头节点 赋值为 链表的最后一个元素->反转的第一步 这样后面对temp之后结点的更改也就真实的改变了原链表的每个元素咯(值的覆盖
S.pop();//反转的第一个节点出栈
//当栈不为空的时候,依次出栈,实现整个链表的反转
while(!S.empty())
{
temp->link=S.top();
S.pop();
temp=temp->link;
}
temp->link = NULL;
}
int main()
{
Push('q');
Push('h');
Push('5');
Push('e');
Reverse();
while(top!=NULL)
{
cout<<top->data<<" ";
top=top->link;
}
return 0;
}
好啦。就先写到这里。最近进度真的很慢,我慢慢调整吧。还是要尽快结束数据结构
如果有问题欢迎指出,非常感谢!!
也欢迎交流建议哦。