二:栈,队列和链表
1.栈
1.1:什么是栈?
栈是一种后进先出的数据结构,且它限定为只能在一端进行插入和删除。
例子:比如说装羽毛球的盒子,打开一端,先放进去的羽毛球只能在在最后被取出。
1.2:图解

1.3 : 如何解决栈溢出问题和访问栈顶元素
#include<iostream>
#include<vector>
using namespace std;
struct Stack{
int data[10000];
int top = -1;
void push(int x){
top++;
if(top < 10000){
data[top] = x;
}else{
top--;
cout << "Stack overflow" << endl;
}
}
void pop(int x){
if(top >= 0){
top--;
}
}
int topval(){
if(top >= 0){
return data[top];
}
}
};
int main(){
Stack s;
for(int i = 1;i <= 10;i++){
s.push(i);
}
for(int i = 1;i <= 10;i++){
cout << s.topval() << ' ';
s.top--;
}
return 0;
}
1.4: 题目:如何来判断一段字符串是否是回文
/回文是指正读和反读均相同的字符序列/
代码如下:
#include<stdio.h>
#include<string.h>
int main()
{
char a[101],s[101];
int i,len,mid,next,top;
gets(a);
len = strlen(a);
mid = len / 2 - 1;
top = 0;
for(i = 0;i <= mid;i++)
{
top++;
s[top] = a[i];
}
if(len % 2 == 0)
{
next = mid + 1;
}
else
{
next = mid + 2;
}
for(i = next;i <= len-1;i++)
{
if(a[i] != s[top])
break;
top--;
}
if(top == 0)
{
printf("Yes");
}
else
{
printf("No");
}
return 0;
}
2.队列
2.1: 什么是队列?
队列是一种特殊的线性结构,它只允许在队列的首部(head)进行删除操作,这叫做'出队',而只能在队列的尾部(tail)进行插入操作,这叫做‘入队’,当队列中为空时,我们称它为空队列。
2.2 图解

2.3: 例题 :
输入一串数,将第一个数删除,将第二个数放到这串数字的末尾,再将第三个数删除并将第四个数放到这串数字的末尾,再将第五个数删除……,直到剩下最后一个数,将最后一个数也删除,按照删除的顺序,将这些删除的数连在一起并输出。
代码如下:
#include<stdio.h>
int main()
{
int q[102] = {0,6,3,1,7,5,9,8,4,2},head,tail;
head = 1;
tail = 10;
while(head < tail)
{
printf("%d ",q[head]);
head++;
q[tail] = q[head];
tail++;
head++;
}
return 0;
}
2.4 : 思路
队列遵循的是FIFO原则,即First in First out,那么我们就可以创建一个队列,将数据入队,因为我习惯于把数组从1号单元开始使用,所以在前面加一个0占着0号单元,将9个数全部放进队列以后head = 1,tail = 10,如果要删除一个数的话,现在只需要将head++就可以了,要是想新增加一个数的话只需要将tail++就可以了.
2.5!!!队列的尾部永远都指向队列最后一个元素的下一个位置。
/我们也可以将队列进行封装成一个结构体进行使用/
2.6:图示

代码如下:
#include<stdio.h>
struct queue{
int data[100];
int head;
int tail;
};
int main()
{
struct queue q;
int i;
q.head = 1;
q.tail = 1;
for(i = 1;i <= 9;i++)
{
scanf("%d",&q.data[q.tail]);
q.tail++;
}
while(q.head < q.tail)
{
printf("%d ",q.data[q.head]);
q.head++;
q.data[q.tail] = q.data[q.head];
q.tail++;
q.head++;
}
return 0;
}
2.7 总结:
上面这个方法可以加助对队列的理解,队列的三个基本元素是一个数组和两个变量,C++的STL库里已经有了队列的实现,且队列是广度优先算法(BFS)以及队列优化的Bellman-Ford最短路径算法的核心数据结构.
3.链表
3.1 :什么是链表?
图解:

3.2:什么是指针?
指针有什么作用?答案很多人都知道:存储地址,准确的说是存储一个内存空间的地址,使用'*'来定义一个指针变量,即定义一个指针,例如:
double *p;
那么指针如何存储a的地址呢?
p = &a;
&是取地址符,这样p就获得了a的地址,我们形象的称为p指向了a.
3.3 :如何动态存储变量?
我们在程序中存储一个数5的时候,除了使用int a这种在内存中申请一块区域来存放的方式以外,还有着另外一种动态存储方法。
malloc(4);
malloc函数的作用是从内存中申请分配指定字节大小的内存空间,上面这一行就申请了4个字节,int变量就是四个字节的,如果你不知道,没有关系,我们可以使用sizeof(int)来获取int类型变量所占用的字节数,如:
malloc(sizeof(int));
现在已经申请了四个字节的变量用来存储一个整数,接下来就需要对这个内存空间进行操作了,这里我们就需要一个指针来指向这个空间,也就是存储这个空间的首地址.
int *p;
p = (int *)maoolc(sizeof(int));
(int *)是强制类型转换,malloc函数的返回值类型是void *型,在C和C++中,void *类型可以强制转换为任何类型.
3.4 :链表的存储
Note:链表的每一个节点都由两部分组成,数据域和指针域,数据域用来存放具体的数值,指针域用来存放下一个结点的地址,也称为前驱和后继.
代码如下:
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
};
int main()
{
struct node *head,*p,*q,*t;
int i,n,a;
scanf("%d",&n);
head = NULL;
for(i = 1;i <= n;i++)
{
scanf("%d",&a);
p = (struct node *)malloc(sizeof(struct node));
p -> data = a;
p -> next = NULL;
if(head == NULL)
{
head = p;
}
else
{
q -> next = p;
}
q = p;
}
t = head;
while(t != NULL)
{
printf("%d ",t ->data);
t = t->next;
}
return 0;
}
/声明/:上面的代码没有使用释放动态申请的空间,虽然没有错误,但是会很不安全,可以使用free命令进行释放.
3.5 :链表的插入
代码如下:
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
};
int main()
{
struct node *head,*p,*q,*t;
int n,a;
scanf("%d",&n); //n表示输入n个数
head = NULL;
for(int i = 1;i <= n;i++)
{
scanf("%d",&a);
p = (struct node *)malloc(sizeof(struct node));
p -> data = a;
p -> next = NULL;
if(head == NULL)
{
head = p;
}
else
{
q -> next = p;
}
q = p;
}
scanf("%d",&a);
t = head;
while(t != NULL)
{
if(t -> next == NULL || t -> next -> data > a)
{
p = (struct node *)malloc(sizeof(struct node));
p -> data = a;
p -> next = t -> next;
t -> next = p;
break;
}
t = t->next;
}
t = head;
while(t != NULL)
{
printf("%d ",t -> data);
t = t->next;
}
return 0;
}