从无到有学算法
吾日三省吾身,今天有写代码乎?🙄
🙄抠门渣男语录:我的果汁分你一半(月亮弯弯 绵绵绵绵缠缠) - 李金源 - 单曲 - 网易云音乐
千年之后的你在哪里:星月神话 - 我觉得我还能再吃点 - 单曲 - 网易云音乐
目录
第一节 解密QQ号--队列
第二节 解密回文--栈
第三节 纸牌游戏--小猫钓鱼
题目
思路 + 代码
完整代码
输入输出
第四节 链表
基础概念
实现链表
完整代码1
插入数据
完整代码2
第五节 模拟链表
先补充个理解:
1,栈中的“先进后出,后进先出”什么意思
栈类似于弹匣,就像装子弹压弹进弹匣一样,一粒一粒压进去,但是退子弹是从最上面开始的,最先压进去的最后弹出来,最后一个压进去的第一个弹出来,这就是“先进后出”,也叫“后进先出”
2,栈的定义
栈就是数据暂时存储的地方,所以才有进栈,出栈的说法
3,栈与队列的区别
栈是把子弹子弹压进弹匣,后进的先出;队列就像排队,你第一个排,那就第一个轮到你,这就是先进先出,也叫后进后出。dfs(深度优先搜索)应用栈,而bfs(广度优先搜索)应用队列。栈占用空间小,而堆中的bfs常用于最短路。
4,栈在计算机领域的解释
栈作为一种数据结构,是只能在一端进行插入和删除的特殊线性表,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始读。允许进行插入和删除操作的一段称为栈顶(top),另一端称为栈底(bottom)。栈底固定,而栈顶浮动;栈中元素个数为0时成为空栈。插入数据称为进栈(PUSH),删除数据称为退栈(POP),栈也称后进先出表。栈在函数调用时可以可以存储断点,做递归时要用到栈!
5,堆和栈的区别
栈快捷但自由度小,堆过程长但自由度大
第一节 解密QQ号--队列
介绍
队列是一种特殊的线性结构,遵循“先进先出”,First In First Out,FIFO原则
它是BFS(Breadth First Search广度优先搜索)和队列优化的Bellman-Ford最短路算法的核心数据结构
比如排队买票,打电话中的人工服务,都是队列的例子,来的越早的人,越早买到票并离开
队首(head)删除数据,称之为“出队”
队尾(tail)插入数据,称之为“入队”
当队列中没有元素时(head == tail),称为空队列
题目
小哼问小哈QQ号是多少,小哈是个大美女,小哈给了他一串加密后的数字,解密规则是:
先将第1个数删除,然后把第2个数放到这串数末尾,再将第3个数删除,并把第4个数放到末尾......
直到剩下最后一个数,把最后一个数也删除。把删除的数连在一起就是小哈的QQ号了。小哈给他加密过的一串数是“920430714”,求小哈的QQ号是多少?
解析
队首删除一个数的操作是:head++;
队尾增加一个数的操作是:q[tail] = x; tail++;
现在有9个数,把9个数放入队列后,head == 1,tail == 10,此时head和tail之间的数就是目前队列中“有效”的数
代码1
#include<iostream>
using namespace std;
int main()
{
int q[102] = {0, 9, 2, 0, 4, 3, 0, 7, 1, 4}; //q[0]是额外加上的
int head = 1, tail = 10; //head指向队首,tail指向队尾下一个位置
while(head < tail) {//队列不为空
cout<<q[head]; //打印队首
head++; //队首出队
q[tail] = q[head]; //新的队首添加到队尾
tail++;
head++; //新队首出队
}
return 0;
}
903744102
代码2
将队列三个基本元素(一个数组,两个变量)封装为一个结构体类型
代码臃肿(本题不必用结构体),只是为了敲多一遍加深印象
#include<iostream>
using namespace std;
struct que
{
int a[100]; //队列主体,存储数据
int head; //队首
int tail; //队尾
};
int main()
{
struct que q;
q.head = 1;
q.tail = 1;
for(int i = 1; i <= 9; ++i) {
cin>>q.a[q.tail]; //在队尾插入数据
q.tail++;
}
while(q.head < q.tail) {//队列不为空
cout<<q.a[q.head]; //打印队首
q.head++; //队首出队
q.a[q.tail] = q.a[q.head]; //新的队首添加到队尾
q.tail++;
q.head++; //新队首出队
}
return 0;
}
9 2 0 4 3 0 7 1 4
903744102
第二节 解密回文--栈
队列先进先出,栈后进先出,生活中的例子有:
1,吃桶装薯片,得先吃完前面的才能吃到最后一片
2,浏览网页退回之前某个网页,需要一步步点击后退键
3,给弹夹装子弹,最后装入的子弹是第一个被打出去的,或者说第一个被退出来的
4,又比如一个小桶,小桶的直径只能放入一个球,依次放入2,1,3号小球,想取出2号球就得先将3号取出来,再将1号取出来,最后才能取最先放进去的2号小球
下面我们用栈的思路判断回文:
只需要一个一维数组a[110]保存读入的数据
一个一维数组s[110]作为栈的主体和一个指向栈顶的变量top就可以
初始化top = 0
入栈的操作:s[++top] = a[i];
通过strlen(a)得到字符串长度len,mid = len / 2 - 1;
代码第14行 s[++top] = a[i]; 为什么用++top呢,为了使后续top = 1(最后一个字符)后,再 top--,即top = 0时可判断为YES
第8行 cin.get(a, 110); 等价于 gets(a),都可读入字符数组的字符串,不过后者头文件为#include<cstdio>,前者头文件为#include<cstring>
#include<iostream>
#include<cstring> //strlen(), cin.get()
using namespace std;
int main()
{
char a[110], s[110];
int len, mid, next, top;
cin.get(a, 110); //读入字符串
len = strlen(a); //求长度
mid = len / 2 - 1;
top = 0;
for(int i = 0; i <= mid; ++i)
s[++top] = a[i]; //mid前的字符入栈
if(len % 2 == 0) next = mid + 1;
else next = mid + 2; //奇偶匹配的起始下标不一样
//开始匹配
for(int i = next; i <= len - 1; ++i) {
if(a[i] != s[top])
break;
top--;
}
if(top == 0) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}
aininia
YES
nihuai
NO
下面是不用栈的思路,它需要一个数组a和两个变量left, right
#include<iostream>
#include<cstring> //cin.get(), strlen()
using namespace std;
char a[666];
bool repeat(int left, int right) //判断回文
{
int flag = 1;
while(left < right) {
if(a[left++] == a[right--]) continue;
else flag = 0; //出现不相等
}
return flag;
}
int main()
{
cin.get(a, 666);
int right = strlen(a) - 1;
if(repeat(0, right))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}
bananab
YES
bababb
NO
栈还可验证括号匹配,end~
第三节 纸牌游戏--小猫钓鱼
本题结合了栈和队列
我们需要两个队列,一个栈来模拟整个游戏
题目
寒假到了,小哼和小哈出来约会,他们来到了一家咖啡馆玩桌游。
这款桌游是一个叫“小猫钓鱼”的扑克游戏:
1,
将一份扑克牌平均分两份,每人一份。小哼先拿出了自己手中的第一张扑克牌放到桌上,然后小哈也拿出自己受手中的第一张扑克牌,并放在小哼刚打出的扑克牌上面,就像这样两人交替出牌
2,
出牌时,如果某人打出的牌与桌上某张牌牌面相同,即可将两张相同的牌及中间所夹的牌全部取走,并依次放到自己手中牌的末尾
3,
当任意一人手中的牌全部出完,游戏结束,对手获胜,
假设游戏开始,小哼有6张牌,小哈也有6张,且牌的牌面只有1~9
思路 + 代码
(以下思路中,存在游戏永远无法结束的情况,只是简陋版本)
容易得知,胜负从拿到牌开始就确定了,且桌上每种牌面最多一张
创建一个结构体来实现队列
struct queue
{
int data[1000];
int head;
int tail;
};
head存储队首,tail存储队尾,数组data存储队列元素,当然大小的设置可以不止1000,数组不越界就好
创建一个结构体来实现栈
struct stack
{
int data[10];
int top;
};
top存储栈顶,数组data存储栈元素,大小设为10,因为只有9种不同牌面,考虑到打出的牌与桌面相同则可取走,桌上最多只能有9张牌,所以10够用了
定义队列变量q1, q2,q1模拟小哼的牌,q2模拟小哈的牌,定义栈变量s模拟桌上的牌
struct queue q1, q2;
struct stack s;
初始化队列和栈
//初始化q1, q2为空,此时小哼小哈手中无牌
q1.head = 1; q1.tail = 1;
q2.head = 1; q2.tail = 1;
//初始化栈s为空,最开始桌上无牌
s.top = 0;
分别读入小哼,小哈的牌,每次读入6个数,分别插入q1, q2
for(int i = 1; i <= 6; ++i) {
cin>>q1.data[q1.tail]; //读入一个数到队尾
q1.tail++; //队尾往后挪一位
}
for(int i = 1; i <= 6; ++i) {
cin>>q2.data[q2.tail];
q2.tail++;
}
小哼出牌
t = q1.data[q1.head]; //小哼亮出一张牌
小哼打出第一张牌,即q1队首,将这张牌存放在临时变量t种,接下来判断桌上有无与t相同的牌
用一个数组记录桌上的牌,由于牌面只有1~9,开一个大小为10的数组即可
int book[10];
将book[1]~book[9]初始化为0,因为开始桌上无牌
for(int i = 0; i <= 9; ++i)
book[i] = 0;
如果桌上多了一张牌面2的牌,则book[2] = 1,因为牌面为2的牌桌上有了。若牌面2的牌被拿走,就将book[2]设置为0,表示桌上没有牌面2的牌了,此时只需一个if来判断桌上是否有某张牌(类似桶排序)
t = q1.data[q1.head]; //小哼先出牌
if(book[t] == 0) { //桌面没有牌面为t的牌,小哼本轮没有赢牌
q1.head++; //已打出的牌出队
s.top++; //注意top初始为0
s.data[s.top] = t; //已打出的牌入栈,即放到桌面
book[t] = 1; //标记桌上有牌面t的牌
}
如果不满足book[t] == 0,小哼可以赢得桌上的牌,将赢得的牌依次放入小哼手中
else {
q1.head++; //小哼已出牌,所以要把这张牌出队
q1.data[q1.tail] = t; //可赢牌,就把刚打出的牌放回手中牌的末尾
q1.tail++;
while(s.data[s.top] != t) { //桌上可赢的,依次放到手中末尾
q1.data[q1.tail] = s.data[s.top]; //依次放入队尾
q1.tail++;
s.top--; //栈种少了一张牌,栈顶减1
}
}
以上,就是小哼出牌阶段,小哈类似,只是q1变q2
在模拟两人出牌外,加一个while循环判断是否有人出完牌
while(q1.head < q1.tail && q2.head < q2.tail)
//队列q1, q1都不为空,双方都有牌,继续循环
最后,输出winner,以及获胜者手中的牌 和 桌上的牌
若小哼获胜,小哈手中无牌,此时q2.head == q2.tail
if(q2.head == q2.tail) {
cout<<"小哼win"<<endl;
cout<<"小哼当前手中的牌是";
for(i = q1.head; i <= q1.tail - 1; ++i)
cout<<q1.data[i];
cout<<endl;
if(s.top > 0) {//若桌上有牌,依次输出
cout<<"桌上的牌是";
for(i = 1; i <= s.top; ++i)
cout<<s.data[i];
cout<<endl;
}
else
cout<<"桌上已经没有牌了"<<endl;
}
完整代码
#include<iostream>
using namespace std;
struct queue
{
int data[1000]; //队列的主体,表示玩家的牌
int head; //队首
int tail; //队尾
};
struct stack
{
int data[10]; //栈的主体,表示桌上的牌
int top; //栈顶
};
int main()
{
struct queue q1, q2; //队列变量
struct stack s; //栈变量
int book[10];
int i, t;
//初始化队列
q1.head = 1; q1.tail = 1;
q2.head = 1; q2.tail = 1;
//初始化栈
s.top = 0;
//初始化标记桌上牌的数组
for(i = 1; i <= 9; ++i)
book[i] = 0;
//依次向队列插入小哼的6张牌
for(i = 1; i <= 6; ++i) {
cin>>q1.data[q1.tail];
q1.tail++;
}
//依次向队列插入小哈的6张牌
for(i = 1; i <= 6; ++i) {
cin>>q2.data[q2.tail];
q2.tail++;
}
while(q1.head < q1.tail && q2.head < q2.tail) { //队列不为空
t = q1.data[q1.head]; //小哼出的第一张
//判断当前能否赢
if(book[t] == 0) {//桌上没有这个牌面的牌
q1.head++; //打出的牌出队
s.top++;
s.data[s.top] = t; //打出的牌入栈
book[t] = 1; //标记桌上有了牌面t的牌
}
else { //桌上有这个牌
q1.head++; //已打出的出队
q1.data[q1.tail] = t; //打出的牌放到末尾
q1.tail++;
while(s.data[s.top] != t) {//可赢的牌
book[s.data[s.top]] = 0; //取消标记
q1.data[q1.tail] = s.data[s.top]; //依次放入队尾
q1.tail++;
s.top--; //桌上少了一张,栈顶减1
}
//遇到牌面与打出一样的,跳出上面的while
book[s.data[s.top]] = 0;
q1.data[q1.tail] = s.data[s.top];
q1.tail++;
s.top--;
}
if(q1.head == q1.tail) break; //牌出完,游戏结束
t = q2.data[q2.head]; //小哈出的第一张
//判断当前能否赢
if(book[t] == 0) {//桌上没有这个牌面的牌
q2.head++; //打出的牌出队
s.top++;
s.data[s.top] = t; //打出的牌入栈
book[t] = 1; //标记桌上有了牌面t的牌
}
else { //桌上有这个牌
q2.head++; //已打出的出队
q2.data[q2.tail] = t; //打出的牌放到末尾
q2.tail++;
while(s.data[s.top] != t) {//可赢的牌
book[s.data[s.top]] = 0; //取消标记
q2.data[q2.tail] = s.data[s.top]; //依次放入队尾
q2.tail++;
s.top--;
}
//遇到牌面与打出一样的,跳出上面的while
book[s.data[s.top]] = 0;
q2.data[q2.tail] = s.data[s.top];
q2.tail++;
s.top--;
}
}
if(q2.head == q2.tail) {
cout<<"小哼win"<<endl;
cout<<"小哼当前手中的牌是 ";
for(i = q1.head; i <= q1.tail - 1; ++i)
cout<<q1.data[i]<<" ";
cout<<endl;
if(s.top > 0) { //桌上有牌就输出
cout<<"桌上的牌是 ";
for(i = 1; i <= s.top; ++i)
cout<<s.data[i]<<" ";
}
else
cout<<"桌上已经没有牌了"<<endl;
}
else {
cout<<"小哈win"<<endl;
cout<<"小哈当前手中的牌是 ";
for(i = q2.head; i <= q2.tail - 1; ++i)
cout<<q2.data[i]<<" ";
cout<<endl;
if(s.top > 0) { //桌上有牌就输出
cout<<"桌上的牌是 ";
for(i = 1; i <= s.top; ++i)
cout<<s.data[i]<<" ";
}
else
cout<<"桌上已经没有牌了"<<endl;
}
return 0;
}
输入输出
2 4 1 2 5 6
3 1 3 5 6 4
小哈win
小哈当前手中的牌是 1 6 5 2 3 4 1
桌上的牌是 3 4 5 6 2
1 6 2 8 5 5
3 4 6 7 3 2
小哈win
小哈当前手中的牌是 2 6 2 4 6 3 5 7 8 3
桌上的牌是 1 5
7 8 9 1 2 3
6 4 2 3 3 8
小哼win
小哼当前手中的牌是 3 3 2 4 1 9 3 8 2
桌上的牌是 7 6 8
跟着书本敲完一遍,好像学到了什么,又好像什么都没学到 🙄(只能说有了印象,大概理解)
由于是简陋版本,只能通过部分测试数据,这个程序显然是不够“健壮”的
第四节 链表
只通过啊哈算法里讲的那一点点,是不够的,所以我通过网上的资源加深理解
要善用网上资源,网络不是只让你打游戏,撩妹😂,娱乐的
1,blibli(1.5倍速) (40分钟)
1个小时学会单链表,C语言数据结构专题_哔哩哔哩_bilibili
2,blibli(1.5倍速) (15分钟)
2.4链表_哔哩哔哩_bilibili
3,CSDN(30分钟) 链表基础知识详解(非常详细简单易懂)_不秃也很强的博客-CSDN博客_链表
然后我开始结合自己的理解,照着书本敲关键知识点(90分钟)
基础概念
1,
链表由一个个节点构成,每个节点采用结构体的形式组织,它是一种物理存储上非连续,通过指针连接的线性存储结构
2,
链表与数组的区别:
数组通过开辟连续的内存来存储数据,有起始和结束地址;
而链表通过对节点的插入和删除实现对数据的读取,没有头尾之分
使用链表可以更灵活地对数据进行插入和删除
3,
链表由结构体变量(节点)相连构成,每一个节点由数据域和指针域组成,数据域存放具体数值,指针域存放下一节点首地址
4,
结构体中的"."和"->"可以读作“的”,比如p->next读作p的next,p->data读作p的data,用来访问结构体成员,区别是,指针变量用"->",一般变量用"."访问成员
实现链表
如何实现链表呢?使用指针和动态分配内存函数malloc来实现
指针:
指针中的 * 表示取内容或者说解引用,& 表示取地址,比如
int a; cin>>a; int *p; p = &a; cout<<*p;
&将a变量的地址赋值给指针p,指针p表示a变量的地址
*使p取得a所指向地址的值,*p表示a变量的地址所指向的值
malloc函数:(头文件#include<cstdlib>)
1,malloc(sizeof(int))
等价于 malloc(4); 从内存中申请分配4个字节大小的内存空间
2,
现在已经成功从内存中申请了4个字节的空间来存放一个整数,如何对这个空间操作呢?
这就需要一个指针来指向这个空间,即存储这个空间的首地址
3,(int *)
malloc()函数返回类型使void *类型,表示未确定类型的指针,该类型可强制转换为任何其他类型指针,此处我们需要强转整型,所以是(int *)
int *p; //定义指针p
p = (int *)malloc(sizeof(int));
malloc()函数动态申请空间:
#include<iostream>
#include<cstdlib> //malloc()
using namespace std;
int main()
{
int *p; //定义指针p
//指针p获取动态分配的内存地址
p = (int *)malloc(sizeof(int));
*p = 10; //向p所指向的内存存入10
cout<<*p<<endl; //输出p指向内存中的值
return 0;
}
10
每一个节点由两部分组成,左边部分存放具体数值,右边部分存储下一个节点的地址(称为后继指针),这里我们定义一个结构体类型来存储这个节点
struct node //节点node
{
int data; //数据域
struct node *next; //指针域,存放下一节点首地址
};
上面代码中,我们定义了一个叫node的结构体类型,它有俩成员,第一个成员叫data,用来存储具体的数值;第二个成员是一个指针,用来存储下一节点的地址。因为下一节点的类型也是struct node,所以这个指针的类型也必须是struct node *类型的指针。
如何建立链表呢?首先需要一个头指针head指向链表的最开始,链表未建立时头指针为空(可理解为指向空节点)
struct node *head;
head = NULL; //头指针初始为空
现在创建第一个节点,并用临时指针p指向这个节点
struct node *p;
p = (struct node *)malloc(sizeof(struct node));
//使指针p变成了结构体变量
设置第一个节点的左半部分和右半部分
int a;
cin>>a;
p->data = a; //将a的值存储到节点的数据域中
p->next = NULL; //后继指针为空,即下一节点为空
可以这样念“p的data等于a,p的next为空”,->是结构体指针运算符,用来访问内部成员
设置头指针:(方便从头遍历整个链表)
1,如果这是第一个创建的节点,头指针指向这个节点
2,如果不是,上一节点的后继指针指向这个节点
if(head == NULL)
head = p; //第一个节点被头指针指向
else
q->next = p; //否则上一节点后继指针指向这里
最后将指针p也指向当前节点,因为下一步临时指针p会指向新节点
q = p; //指针q指向当前节点
完整代码1
#include<iostream>
#include<cstdlib> //malloc()
using namespace std;
struct node
{
int data;
struct node *next;
};
int main()
{
struct node *head, *p, *q, *t;
int i, n, a;
cin>>n;
head = NULL; //头指针初始为空
for(i = 1; i <= n; ++i) {
cin>>a;
//动态申请一个空间存放节点,临时指针p指向这个节点
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) {
cout<<t->data<<" ";
t = t->next; //继续下一节点
}
return 0;
}
9
2 3 5 8 9 10 18 26 32
2 3 5 8 9 10 18 26 32
注意,上述代码没有free(释放动态申请的空间),很不安全
插入数据
接下来,往链表插入6
关于插入,这里有个关键:
下方完整代码第38,39行,初始指针t指向5,p指向6,t的next指向8
-
p->next = t->next;
-
t->next = p;
这两步相当于链表断开,接上了一个新的元素
p的next指向原来的t的next(指向了8的地址)
t的next再指向p的地址,顺序不能调换
插入后,t的next指向p的地址,p的next指向8的地址
首先用临时指针t从链表头部开始遍历
t = head; //从链表头部开始遍历
等指针t下一节点的值比6大,将6插到两节点中间,即t->next->data大于6时插入
t->next->data跟我念“t的next的data”
cin>>a; //读入待插入的数
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; //继续下一节点
}
完整代码2
#include<iostream>
#include<cstdlib> //malloc()
using namespace std;
//创建一个结构体表示节点
struct node
{
int data;
struct node *next;
};
int main()
{
struct node *head, *p, *q, *t; //p,q,t都是临时指针
int i, n, a;
cin>>n; //n个数
head = NULL; //头指针初始为空
for(i = 1; i <= n; ++i) {
cin>>a;
//动态申请空间存放一个节点,临时指针p指向该节点
p = (struct node *)malloc(sizeof(struct node));
p->data = a;
p->next = NULL; //当前节点下一节点为空
if(head == NULL)
head = p; //若为第一个创建的,头指针指向该节点
else
q->next = p; //上一节点后继指针指向当前节点
q = p; //指针q指向当前节点
}
cin>>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) {
cout<<t->data<<" ";
t = t->next; //继续下一节点
}
return 0;
}
9
2 3 5 8 9 10 18 26 32
6
2 3 5 6 8 9 10 18 26 32
耗时3.5小时终于完成了第四节的学习
第五节 模拟链表
模拟链表不需要指针,却能起到链表的作用,模拟链表还能实现双向链表和循环链表
学习模拟链表可以加深我们对链表的理解,因为它们的思想是一样的,只是工具不同
它使用一个数组存放序列中的数字,使用另一个数组存放下一数字的下标
比如上面两个数组,
right[1] == 2表示数组data第1个元素右边元素的下标为2,
right[9] == 0表示数组data第9个元素右边元素不存在
现在需要将6插入5和8中间,怎么做呢?只需要
data[10] = 6; //加在最后
right[3] = 10; //3号右边的元素存放在data[10]
right[10] = 4; //10号元素右边的元素存放在data[4]
完整代码
#include<iostream>
using namespace std;
int main()
{
int data[110], right[110];
int n;
cin>>n;
for(int i = 1; i <= n; ++i)
cin>>data[i]; //读入数据
for(int i = 1; i <= n; ++i) { //初始化数组right
if(i != n) right[i] = i + 1;
else right[i] = 0;
}
cin>>data[n + 1]; //待插入数
//从链表头部开始遍历
int t = 1;
while(t != 0) {
if(data[right[t]] > data[n + 1]) {
right[n + 1] = right[t]; //right[10] = right[3]
right[t] = n + 1; //right[3] = 10
break; //插入完跳出循环
}
t = right[t]; //t自增至满足条件或遍历完
}
//输出链表所有数
t = 1; //类似链表中 指针t = head;
//t = 1少了会从中间开始输出
while(t != 0) {
cout<<data[t]<<" ";
t = right[t];
}
return 0;
}
9
2 3 5 8 9 10 18 26 32
6
2 3 5 6 8 9 10 18 26 32
代码中 data[n + 1] == 6 ,当满足插入条件时,t == 3, right[n + 1] = 4, right[t] == 10