先看视频,更好理解:
插入排序算法可视化演示程序
(同福客栈内,灯火通明。白展堂手持算盘,佟湘玉坐镇柜台后,郭芙蓉挥着抹布,吕秀才捧着书摇头晃脑,李大嘴在厨房探出头来,莫小贝则趴在桌上画圈圈。)
佟湘玉 (拍桌而起):
"各位乡亲们!今天咱们不讲江湖恩怨,不聊儿女情长,而是要说------这'插入排序'的玄机!"
白展堂 (眯眼一笑):
"哟?排序?跟咱客栈排队打饭似的?"
郭芙蓉 (翻了个白眼):
"哼!要是这么简单,我早就把厨房那堆锅碗瓢盆排得整整齐齐了!"
第一幕:混乱初现
(此时,门口走进一群"彩色小球",个个圆滚滚、颜色各异,有的红得像辣椒,有的绿得像青菜,还有粉的像胭脂......它们摇摇晃晃地站成一排,位置乱七八糟。)
吕秀才 (推眼镜):
"此乃无序数组也!若不排序,何以治国平天下?"
莫小贝 (蹦跳上前):
"我来我来!看我把它们排成一条龙!"
佟湘玉 (拉住她):
"别急!排序有法,不可蛮干。今日我们要用的是------插入排序!"
第二幕:插入排序登场
白展堂 (模仿旁白腔调):
"话说这插入排序,就像你吃饭时夹菜------先夹一口尝味道,再决定放哪盘里。"
李大嘴 (从厨房探头):
"那我是不是也算'插入'?每次端菜都得找空位儿......"
众人 (齐声):
"闭嘴!做饭去!"
第三幕:实战演练
(场景切换:一个黑色屏幕浮现,上面漂浮着几个彩色小球,每个都标着数字,大小不一,高低错落。)
郭芙蓉 (指着最大的红球):
"这谁啊?一来就占C位!"
吕秀才 (解释):
"这是第一个元素,我们认为它是有序的起点。接下来每一个新来的,都要跟它比一比。"
白展堂 (掏出折扇,指向第二个黄球):
"来了第二位!数值30,个头不大,但脾气不小。现在要给他找个合适座位。"
(红球往后挪一个单位,然后橙球开始往前移动一个单位,于是它果断插队到前面。)
佟湘玉 (拍手叫好):
"看!这就是'插入'!找到位置,腾出空档,稳稳坐下!"
第四幕:高潮迭起
(第三个小黄球登场,数值10,身材苗小。)
莫小贝 (兴奋大喊):
"他又要比了!又要挪人了!"
(小黄球一路向前,发现红球太大,跳过;黄球太小,继续前进......最终停在最左位置。)
吕秀才 (感慨万千):
"人生如戏,全靠移位。每一次后退,都是为了更好的前进。"
白展堂 (突然严肃):
"注意!这不是普通的搬家,这是逻辑的胜利!每一步都稳扎稳打,绝不冒进!"
第五幕:尘埃落定
(所有小球依次归位,从小到大整齐排列,色彩斑斓却井然有序。)
郭芙蓉 (擦汗):
"终于排完了!比我练惊涛掌还累!"
李大嘴 (端菜出来):
"早说嘛,让我炒一盘'有序排列土豆丝'不就行了?"
众人 (再次齐声):
"滚回去炒菜!"
尾声总结
佟湘玉 (深情款款):
"插入排序之道,在于耐心与细致。取一人,观全局,步步为营,终得正果。"
白展堂 (收扇点头):
"正如江湖传言:从前有个数,它很孤独;后来学会了插入,从此不再迷路。"
全体演员谢幕鞠躬:
"谢谢观看!愿你的程序,也能像我们的客栈一样------越排越顺,越跑越快!"
✨ 插入排序口诀(附赠版):
我自前来,君且安坐;
若我不小,请你挪窝;
一路倒退,直到对位;
轻轻一插,完美收官!
cpp
#include "sprites.h" //包含C++精灵库
using namespace std;
Sprite rocket; //建立角色叫rocket
struct Node{
int value,x; //值和坐标
Sprite *sp;
};
vector<Node *> datas; //所有彩色圆形(节点)的指针存入这个向量
vector<string> colors = {"red","orange","yellow","green",
"cyan","blue","purple","pink"};
int startX; // 记录起始x坐标
int step = 100; // 每个节点之间的间隔
void movebackward(int j){ //把索引为j的节点后挪一个单位
// 只需要更新节点的x坐标和精灵位置
datas[j+1] = datas[j];
// 计算新位置
int newX = startX + (j+1) * step;
datas[j+1]->x = newX;
datas[j+1]->sp->go(newX, -50);
// 添加短暂的延迟以便观察
rocket.wait(0.2);
}
void placekey(int j, Node *key){ //放置key节点在索引j这里
datas[j] = key;
// 计算新位置
int newX = startX + j * step;
key->x = newX;
key->sp->go(newX, -50);
// 添加短暂的延迟以便观察
rocket.wait(0.2);
}
int main(){ //主功能块
g_screen->bgcolor("black");
int n= randint(5,8);
startX = 50 - 100*n/2; // 保存起始坐标
int x = startX;
for(int i=0;i<n;i++){ //生成5到8个圆形,放到datas中
int v = randint(30,200);
Node *node = new Node;
node->value = v;
node->x = x;
string s = "res/circle_" + colors[i] + ".png";
Sprite *js = new Sprite(s);
js->scale(v/100.0);
js->penup(); js->go(x,-50); js->speed(1);
node->sp = js;
datas.push_back(node);
x = x + 100;
}
Sprite pen{"blank"};
//pen.up().color(0).sety(300).write("插入排序算法可视化演示程序",50);
//pen.color(30).sety(230).write("作者:李兴球,采用C++精灵库",30);
//pen.color(60).sety(180).write("C++精灵库作者:李兴球",20);
rocket.wait(1).color("yellow").penup().sety(130).hide();
rocket.color("yellow").sety(130).write("开始排序...", 20);
//建立指示器角色,它的方向向下,总是指向当前需要插入的节点
Sprite ptr{"res/pointer_pink.png"}; //prt角色的造型是箭头
ptr.penup().scale(0.6).right(90).sety(30).speed(1);
// 插入排序算法
for(int i=1; i<n; i++){
ptr.setx(datas[i]->x); //指示器到达当前需要寻找位置的角色的x位置
datas[i]->sp->tremble(); //默认颤抖10次,实际效果为闪动,当前节点需要寻找合适的位置了
Node *key = datas[i]; // 保存当前key节点
int j = i-1;
// 从当前节点向前比较
while(j>=0 && key->value < datas[j]->value){
movebackward(j); // 把索引为j的节点往后挪一个单位
j--;
}
placekey(j+1, key); // 将key节点放入正确位置
rocket.wait(0.5);
}
ptr.hide();
rocket.cleartxts(1).write("演示完毕!",42).done(); //完成了
return 0; //返回0
}

