链表的选择排序.docx
- 文档编号:5211246
- 上传时间:2022-12-14
- 格式:DOCX
- 页数:9
- 大小:65.73KB
链表的选择排序.docx
《链表的选择排序.docx》由会员分享,可在线阅读,更多相关《链表的选择排序.docx(9页珍藏版)》请在冰豆网上搜索。
链表的选择排序
排序采用选择法:
30
65
90
80
54
45
把30接到80后面
45接到90后面
90替原来45的位置
***************************
预备知识:
NODE*v,*u,*p,*h;
U,v,h,p都是指针,它们只是地址性的可以指向结构
next
而链表中的表
有next指针
****************************************
链表排序
h
456554809030
要实现45和90的交换:
30要接到80后面
45要接到90后面
90要接到h后面
904565548030
要实现45和80的交换:
30接到54后面
45接到80后面
80要接到90后面。
即插入到90后面
所以一般情况需要用:
两个指针voldv指出45
两个指针moldmax指出最大
这样可以方便的实现v或max,移走或被替换时,其它的可以接上。
但如果要被替换的是第一个,如45被90替换。
h,vold,vmax
456554809030
Max指向90,30放到80后面,
h,vold,vmax
456554803090
45放到90后面,h,v,vold都跟着45移动,
maxh,vold,v
904565548030
h=max
还要一个游动指针,u,用于不断和v比较
为了继续进行,下一轮开始前应该为:
h,voldv,maxu
904565548030
vold要指向90,v指向45,u指向54
所以对于第一次交换后还要移动vold
if(vold==v)时,vold=h;
总之一个比较可行的程序为:
while(v->next!
=NULL)//省去空的v,//选择法
{for(max=v,uold=u=v->next;u->next!
=NULL;
uold=u,u=u->next)
{if(u->score>max->score){mold=uold;max=u;}//找到最大的
}//u已移动,但队列未动
//u->next==NULL即u是最后一个表,跳出循环,
//还要判别u指向的表是最大吗?
if(u->score>max->score){mold=uold;max=u;}//最后一个
if(max!
=v){
mv->next=max->next;
max->next=v;
if(vold==v){h=max;}
else{vold->next=max;}
}
。
。
。
。
。
可见用以上方法指针比较多,而且指针移动比较麻烦。
因为一开始,不能够用vold=vold->next;方式。
并且上述程序还未完全调通
***************************************
为此,一种常用的方法,引入一个空表接到h的后面
先比较45和65:
if(v->next->score
比出最大后,90要插入到u的位置时,要做下面的步骤:
1.30接到80后面.max独立出来
2.max->next=u;
3.v->next=max;
v=v-.>next,u=v->next
将来输出时
returnh->next;,就可以把空表让过
具体分析:
引进一个v
NODE*v=(NODE*)malloc(sixeof(NODE));
Vu
30
45
65
90
80
54
h
pp1p2p3p4p5p6
v->next=h;h=v;把v插入h和p1(45)之间
先比较p1==u(45)和p2(65)
为了适合循环:
v->next->score,u->next->score表示要比较的数据:
u->score==45,p2.score==65
P=v;u=v->next;(v->next==u)
u->score==45,v->next->score==45
p2==u->next==65
p2.score=u->next->score==65
for(p=v,u=v->next;u->next!
=NILL;u=u->next)
if(p->next->score
找出最大的表u->next->score==(90),然后交换(90)(45)
vuuu(即max)
30
90
80
54
65
45
p
把30接到80后面:
90的指针要保存
45接到90后面
90替代45位置
一、90要独立出来,同时30接到80后面,需要两个指针:
1.p=u?
u=p->next:
p指向80u指向90
90要独立出来,所以要用指针u指向它,以免丢掉,
u要移走,所以先用p指向80
2.p->next=u->next:
30接到80后面
二、:
45接到90后面,u->next=v->next;
三、90替代45位置
v->next=u:
V=v->next,u=v-.next准备下一轮
NODE*bubblesort(NODE*h)
{NODE*v,*u,*p;
v=(NODE*)malloc(sizeof(NODE));
v->next=h;h=v;
while(v->next!
=NULL)//选择法
{for(p=v,u=v->next;u->next!
=NULL;u=u->next)
if(u->next->score>p->next->score)p=u;//找到最大的
//u已移动,但队列未动
if(p!
=v){u=p->next;p->next=u->next;//ok
u->next=v->next;v->next=u;}
v=v->next;
}returnh->next;//h;
}
*******************************
14.Sort()排序
由于学生信息采用的是单链表存储结构,所以选用直接插入算法较为简单。
直接插入算法的基本方法是:
每步将一个待排序的记录按其排序码值的大小插到前面已经排好序的表中,直到全部插入为止。
基于这样的方法首先将链表的头结点看作是已排好序的结点,然后取下一个结点作为待排序的结点,插入到已排好序的表中。
由于单链表的特性,所以具体的思路如下:
(1)先将原表头结点作为新排好序表的头结点h,原表下一个结点作为原表头结点h1。
设原表如图1l—所示,表中只列出总分数据。
图.11设新表头结点
即h是新链表,h1是旧链表
(2)原表头结点为待排序结点,
将其总分与新表结点的总分进行比较,如果待排序结点总分大,则插在新表的头,否则插入在其后,原表头结点后移一位,如图.12所示。
(3)重复第二步,即将原表头结点的总分和新表结点的总分进行比较,如果待排序结点总分小,则移动新表指针,直到找到合适的位置将其插入,直到原表为空,所有结点排序完毕,如图.13所示。
这个排序算法实际上是先从原表删除头结点,
然后在新表中查找到合适的位置,进行插入。
待排序结点的插入位置总是插在表头、表尾和表中间三种情况之一,
由于单链表的特性,实际插入结点时,并不需要移动和交换结点信息,而是只改变指针关系,所以排序时间主要用在比较上。
排好序后将其名次数据写入数据域order中。
STUDENT*sort(STUDENT*h)
{inti=0;/*保存名次*/
STUDENT*p,*q,*t,*hl;/*定义临时指针*/
hl=h->next;/*将原表头指针所指的下一个结点作为头指针*/
h1->next=NULL;/*第一个结点为新表的头结点*/?
?
?
while(hl!
=NULL)/*当原表不为空时,进行排序*/
{t=hl;/*取原表的头结点*/
hl=hl->next;/*原表头结点指针后移*/
p=h;/*设定移动指针P,从头指针开始,
即,h1中的每一个,从h的头比较起*/
q=h;/*设定移动指针q作为P的前一个==pold,初值为头指针*/
原表取第一个和新表从头进行比较
while(t->sum
=NULL)/*进行总分比较*/
{q=p;/*待排序点值小,则新表指针后移*/
p=p->next;}/*直到t->sum>p->sum时,t插到p的前面
if(p==q)/*说明待排序点值最大,应排在首位*/
{t->next=p;/*待排序点的后继为p*/
h=t;}/*新头结点为待排序点*/
else/*待排序点应插入在中间某个位置q和P之间,
如果P为空则是尾部*/
{t->next=p;/*t的后继是P*/
q->next=t;}/*q的后继是t*/
}
p=h;/*排序完成p指针回到链表头,准备填写名次*/
//因为是降序i=1即第一名,i=2,第二名
while(p!
=NULL)/*P不为空时,进行下列操作*/
{i++;/*结点序号*/
p->order=i;/*将名次赋值*/
p=p->next;/*指针后移*/
}
printf("sortsucess!
!
!
\n");/*排序成功*/
returnh;/*返回头指针*/
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 选择 排序