链表的选择排序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

排序采用选择法:
把30 接到80后面
45接到90后面
90替原来45的位置
***************************
预备知识:
NODE *v,*u,*p,*h;
U,v,h,p都是指针,它们只是地址性的可以指向结构
而链表中的表
有next指针
**************************************** 链表排序
h
45 65 54 80 90 30
要实现45和90 的交换:
30要接到80后面
45要接到90后面
90要接到h后面
90 45 65 54 80 30
要实现45和80 的交换:
30 接到54后面
45接到80后面
80要接到90后面。

即插入到90后面
所以一般情况需要用:
两个指针vold v 指出45
两个指针mold max 指出最大
这样可以方便的实现v 或max,移走或被替换时,其它的可以接上。

但如果要被替换的是第一个,如45被90替换。

h,vold,v max
45 65 54 80 90 30
Max指向90,30 放到80后面,
h,vold,v max
45 65 54 80 30 90
45 放到90后面,h,v,vold都跟着45移动,
max h,vold,v
90 45 65 54 80 30
h=max
还要一个游动指针,u,用于不断和v比较
为了继续进行,下一轮开始前应该为:
h ,vold v,max u
90 45 65 54 80 30
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 < u->next->score ) ,……….
比出最大后,90要插入到u的位置时,要做下面的步骤:
1. 30 接到80后面 . max独立出来
2. max->next =u;
3. v->next=max;
v=v-.>next, u=v->next
将来输出时
return h->next;, 就可以把空表让过
具体分析:
引进一个v
NODE *v=(NODE*)malloc(sixeof(NODE));
V u
h p p1 p2 p3 p4 p5 p6
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) p=u;
找出最大的表u->next->score==(90), 然后交换(90) (45)
) 把30 接到80后面: 90 的指针要保存
45接到90后面
90替代45位置
一、90要独立出来,同时30 接到80后面,需要两个指针:
1. p=u?, u=p->next : p指向80 u指向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;
} return h->next; //h;
}
*******************************
14.Sort()排序
由于学生信息采用的是单链表存储结构,所以选用直接插入算法较为简单。

直接插入算法的基本方法是:每步将一个待排序的记录按其排序码值的大小插到前面已经排好序的表中,直到全部插入为止。

基于这样的方法首先将链表的头结点看作是已排好序的结点,然后取下一个结点作为待排序的结点,插入到已排好序的表中。

由于单链表的特性,所以具体的思路如下:
(1)先将原表头结点作为新排好序表的头结点h,原表下一个结点作为原表头结点h1。

设原表如图1l—所示,表中只列出总分数据。

图.11设新表头结点
即h是新链表,h1是旧链表
(2)原表头结点为待排序结点,
将其总分与新表结点的总分进行比较,如果待排序结点总分
大,则插在新表的头,否则插入在其后,原表头结点后移一位,如图.12所示。

(3)重复第二步,即将原表头结点的总分和新表结点的总分进行比较,如果待排序结点总分小,则移动新表指针,直到找到合适的位置将其插入,直到原表为空,所有结点排序完毕,如图.13所示。

这个排序算法实际上是先从原表删除头结点,
然后在新表中查找到合适的位置,进行插入。

待排序结点的插入
位置总是插在表头、表尾和表中间三种情况之一,
由于单链表的特性,实际插入结点时,并不需要移动和交换结点信息,而是只改变指针关系,所以排序时间主要用在比较上。

排好序后将其名次数据写入数据域order中。

STUDENT *sort(STUDENT *h)
{ int i=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 < p->sum && p!=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("sort sucess!!!\n"); /*排序成功*/
return h; /*返回头指针*/
}。

相关文档
最新文档