数据结构实验报告排序算法Word文件下载.docx
《数据结构实验报告排序算法Word文件下载.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告排序算法Word文件下载.docx(15页珍藏版)》请在冰豆网上搜索。
(1)快速排序:
例:
初始关键字3673659713
ij
j向左扫描后3673659713
R[j]移入R[i]1373659736
i向右扫描1373659736
R[i]移入R[j]后1336659773
i向左扫描1336659773
i向左扫描1336659773
i=j第一次结束
1次排序结束后1336659773
2次排序结束后1336659773
3次排序结束后1336657397(排序结束)
4333618272(初始状态)
例:
初始值61211108
1.把数据建成堆,n=5,就从第三个数据开始,3,2,1个数据筛选过程如下图:
2.建立好了初始堆后,就要从最后一个元素开始,把第k个元素和根交换,然后把根筛选一次
3.再从第--k个元素开始进行与跟交换这时,再进行筛选,直到所有的k<
=0时堆排序完毕。
分为两个部分,第一个分配位数,第二个收集。
创建一个结构体数组用于分配时保存同一关键位的元素。
个位数字为低关键字位,十位数字为高关键字位。
关键字位值的范围为0—9,qu[i].f与qu[i].r为第i个队列的头指针和尾指针。
将不qu[i].f不为空的链表相连,分个位和十位先后进行收集。
直到所有的关键字位都被分配完毕,收集完成后退出。
流程图:
调用到的partition(i,j)函数:
(2)堆排序:
调用到的函数sift(j,n):
(3)基数排序:
实验步骤:
[程序代码]
#include"
stdlib.h"
alloc.h"
#defineN030000
typedefintkeytype;
typedefstructnode/*创建待排序的数*/
{
keytypekey;
/*待排序的数*/
}Element;
ElementR[N0+1];
/*存储一组待排序的数*/
intn=150;
/*定义随机生成数的个数为150*/
voidgetData()/*随机产生150个数*/
{inti;
randomize();
for(i=1;
i<
=n;
i++)
R[i].key=random(1000);
}
voidprintData()/*将getData()函数产生的数据输出*/
for(i=1;
i++)
{printf("
%6d"
R[i].key);
/*输出数据*/
if(i%8==0)printf("
\n"
);
}
printf("
longcount;
/*用来计算排序的次数*/
intpartition(inti,intj)/*快速排序的一次排序过程*/
{R[0]=R[i];
/*确定分割基准*/
while(i<
j)
{while(R[j].key>
=R[0].key&
&
j){j--;
count++;
}/*自后向前扫描小于基准关键字的数*/
R[i]=R[j];
/*当扫描到小于基准关键字的数时将小的数赋给当前关键字所在的位置*/
while(R[i].key<
j){i++;
}/*自前向后扫描大于基准关键字的数*/
R[j]=R[i];
/*当扫描到大于基准关键字的数时将大的数赋给当前关键字所在的位置*/
R[i]=R[0];
/*将基准记录移入最终位置*/
returni;
/*返回基准记录的最终位置*/
voidquickSort()/*快速排序*/
{struct/*用来对待排序数进行区间分割*/
{intlow,high;
/*把区间分割成两块,分别用low和high标记*/
}s[N0/2+1];
/*最多分割成N0/2+1个区间*/
inttop=0,i,j,k;
/*i,j为指示器变量*/
s[++top].low=1;
s[top].high=n;
while(top)
{i=s[top].low;
j=s[top--].high;
k=partition(i,j);
/*进行排序*/
if(k-1>
i)
{s[++top].low=i;
s[top].high=k-1;
if(k+1<
{s[++top].low=k+1;
s[top].high=j;
voidsift(inti,intm)/*调整堆*/
{intk=2*i;
/*k初始化为2i,即指向待筛记录的左孩子*/
R[0]=R[i];
/*待筛记录送临时工作单元中*/
while(k<
=m)/*逐层向下筛选*/
{
if(k<
m&
R[k+1].key>
R[k].key)k++;
/*若右孩子记录关键字值小,让count指向右孩子*/
count++;
if(R[k].key>
R[0].key)/*如果孩子的值大于其父亲,则进行调整*/
{R[i]=R[k];
/*孩子记录上移*/
i=k;
/*为继续向下筛选做准备*/
k=2*i;
count++;
}
elsebreak;
/*孩子记录关键字大时,筛选结束,退出循环*/
}
/*将最初的筛选记录填入正确位置*/
voidheapSort()/*堆排序*/
{intj;
/*定义循环变量*/
for(j=n/2;
j>
=1;
j--)sift(j,n);
/*调用筛选法,初始化堆*/
for(j=n;
=2;
j--)/*n-1次输出堆顶记录并调整堆*/
{R[0]=R[1];
R[1]=R[j];
R[j]=R[0];
/*堆顶记录与当前堆中最后一个记录交换*/
sift(1,j-1);
/*调用筛选法重建堆*/
voidradixSort()/*基数排序*/
{typedefstructnode/*用链表来存储待排序数组*/
{keytypekey;
/*数据域*/
structnode*next;
/*指向下个结点的指针域*/
}ND;
struct
{ND*f,*r;
/*定义队头和队尾指针*/
}qu[10];
/*定义队头和队尾指针数组*/
ND*p,*head;
inti,j,k;
longdd=1;
for(i=0;
10;
i++)qu[i].f=qu[i].r=NULL;
/*初始化队列为空*/
{k=R[i].key/dd%10;
count++;
/*先取个位数进行比较*/
p=(ND*)malloc(sizeof(ND));
if(qu[k].f==NULL)qu[k].f=qu[k].r=p;
/*如果队列为空作为队头结点插入*/
else/*否则插入队尾*/
{qu[k].r->
next=p;
qu[k].r=p;
p->
key=R[i].key;
/*数据给p*/
next=NULL;
/*队尾指向NULL为后续做准备*/
while
(1)
{intflag=0;
i=0;
while(qu[i].f==NULL)i++;
/*找第一个非空队列*/
head=qu[i].f;
while(i<
9)/*控制一次的收集*/
{j=i+1;
while(j<
10&
qu[j].f==NULL)j++;
if(j>
=10)break;
qu[i].r->
next=qu[j].f;
flag=1;
i=j;
if(flag==0)break;
/*如果没有数据,退出循环*/
p=head;
dd*=10;
while(p)
{head=p->
next;
k=p->
key/dd%10;
/*取十位数进行比较*/
else
{qu[k].r->
qu[k].r=p;
}
qu[k].r->
}
p=qu[0].f;
i=1;
/*p指向第一个队列的头一个*/
{qu[0].f=p->
R[i++].key=p->
key;
free(p);
main()
{clrscr();
\n------------------------date-----------------------\n"
getData();
/*产生随机数*/
printData();
count=0;
/*计数器初始化为0*/
quickSort();
getch();
printf("
---------------------quickSort---------------------\n"
/*输出比较后的数据*/
count=%ld\n"
count);
heapSort();
---------------------heapSort----------------------\n"
radixSort();
/*调用基数排序函数*/
---------------------radixSort---------------------\n"
五、调试过程:
错误1:
分析原因:
没有将基准记录移入最终位置
修改方法:
将基准记录移入最终位置,程序运行成功
堆排序出错
错误2:
一趟排序结束后,没有重建堆,造成排序出错
一趟排序结束后,重建堆
程序运行正常
六.实验结果:
随机产生150个数:
快速排序:
随机产生10个数:
七、总结:
通过这次实验我学会了基数,快速和堆排序的基本思想,排序原理以及它们之间的的特点,知道了什么情况下应该用什么样的排序方法。