当前位置:文档之家› 内部排序实验报告

内部排序实验报告

内部排序实验报告
内部排序实验报告

数据结构实验报告

内部排序

班级:13 软工一班

学号:13131113 姓名:吕蒙学号:13131116 姓名:钱剑滨学号:13131142 姓名:孔亚亚学号:13131144 姓名:邱佃雨

13软工转本1 钱剑滨实验报告

内部排序实验报告

信息工程系 13软工转本1 日期 2016年06月07日一、实验内容

编写程序实现各种内部排序(包括:冒泡排序、插入排序、选择排序、希尔排序、快速排序、堆排序、归并排序、基数排序),并运用这些排序对一组随机生成的数组进行排序。

二、时间复杂度

1.冒泡排序(O(n^2))

若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数和

记录移动次数均达到最小值:,。所以,冒泡排序最好

的时间复杂度为。若初始文件是反序的,需要进行趟排序。每趟排序要进

行次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:

冒泡排序的最坏时间复杂度为。综上,因此冒泡

排序总的平均时间复杂度为。

2.插入排序(O(n^2))

如果目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。插入排序的赋值操作是比较操作的次数加上(n-1)次。平均来说插入排序算法的时间复杂度为O(n^2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。

3.选择排序(O(n^2))

选择排序的交换操作介于0 和(n - 1)次之间。选择排序的比较操作为n (n - 1)/ 2 次之间。选择排序的赋值操作介于0 和3 (n - 1)次之间。比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+...+1=n*(n-1)/2。

交换次数O(n),最好情况是,已经有序,交换0次;最坏情况交换n-1次,逆序交换n/2次。交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。

4.希尔排序

希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些。

5.快速排序(O(n^2))

无论适用哪一种方法来选择pivot,由于我们不知道各个元素间的相对大小关系(若知道就已经排好序了),所以我们无法确定pivot的选择对划分造成的影响。因此对各种pivot选择法而言,最坏情况和最好情况都是相同的。

我们从直觉上可以判断出最坏情况发生在每次划分过程产生的两个区间分别包含

n-1个元素和1个元素的时候(设输入的表有n个元素)。下面我们暂时认为该猜测正确,在后文我们再详细证明该猜测。

对于有n个元素的表L[p..r],由于函数Partition的计算时间为θ(n),所以快速排序在序坏情况下的复杂性有递归式如下:T(1)=θ(1),T(n)=T(n-1)+T(1)+θ(n)

(1)用迭代法可以解出上式的解为T(n)=θ(n2)。这个最坏情况运行时间与插入排序是一样的。下面我们来证明这种每次划分过程产生的两个区间分别包含n-1个元素和1个元素的情况就是最坏情况。设T(n)是过程Quick_Sort作用于规模为n的输入上的最坏情况的时间,则T(n)=max(T(q)+T(n-q))+θ(n),其中1≤q≤n-1

(2)我们假设对于任何k

n2-2(n-1)。于是有:T(n)≤cn2-2c(n-1)+θ(n)≤cn2只要c足够大,上面的第二个小于等于号就可以成立。于是对于所有的n都有T(n)≤cn。

这样,排序算法的最坏情况运行时间为θ(n2),且最坏情况发生在每次划分过程产生的两个区间分别包含n-1个元素和1个元素的时候。时间复杂度为o(n2)。

6.堆排序(O(nlgn))

堆排序过程的时间复杂度是O(nlgn)。因为建堆的时间复杂度是O(n)(调用一次);调整堆的时间复杂度是lgn,调用了n-1次,所以堆排序的时间复杂度是O(nlgn)

7.归并排序(O(nlgn))

时间复杂度为O(nlogn) 这是该算法中最好、最坏和平均的时间性能。空间复杂度为O(n)比较操作的次数介于(nlogn) / 2和nlogn - n + 1。赋值操作的次数是(2nlogn)。归并算法的空间复杂度为:0 (n)归并排序比较占用内存,但却是一种效率高且稳定的算法。

8.基数排序(O(d(n+radix)))

时间效率:设待排序列为n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集。空间效率:需要2*radix 个指向队列的辅助空间,以及用于静态链表的n个指针。

三、算法稳定性

1.冒泡排序(稳定)

冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

2.插入排序(稳定)

插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

3.选择排序(不稳定)

选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中两个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法。

4.希尔排序(不稳定)

由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

5.快速排序(不稳定)

快速排序有两个方向,左边的i下标一直往右走,当a[i] <= a[center_index],其中center_index是中枢元素的数组下标,一般取为数组第0个元素。而右边的j下标一直往左走,当a[j] > a[center_index]。如果i和j都走不动了,i <= j, 交换a[i]和a[j],重复上面的过程,直到i>j。交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列5 3 3 4 3 8 9 10 11,现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱,所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j]交换的时刻。

6.堆排序(不稳定)

堆排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成,它们均是通过调用Heapify实现的。堆排序的最坏时间复杂度为O(nlgn)。堆排序的平均性能

较接近于最坏性能。由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。堆排序是就地排序,辅助空间为O(1),它是不稳定的排序方法。

7.归并排序(稳定)

归并排序是一种稳定的排序

8.基数排序(稳定)

基数排序是一种稳定的排序

四、各排序介绍和算法实现

1.冒泡排序

冒泡排序算法的运作如下:(从后往前)

(1)比较相邻的元素。如果第一个比第二个大,就交换他们两个。

(2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

(3)针对所有的元素重复以上的步骤,除了最后一个。

(4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

代码:

void maopao(int numberN[MAX])

{

int temp, i, j, t;

yuan(numberN);

int numberY[MAX];

for(t = 0; t < N; t++)

{

numberY[t] = numberN[t];

}

for(i = 0; i < N - 1; i++)

for(j = 0; j < N - (i + 1); j++)

if(numberY[j] > numberY[j + 1])

{

temp = numberY[j];

numberY[j] = numberY[j + 1];

numberY[j + 1] = temp;

}

sheng(numberY);

}

一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:(1)从第一个元素开始,该元素可以认为已经被排序

(2)取出下一个元素,在已经排序的元素序列中从后向前扫描

(3)如果该元素(已排序)大于新元素,将该元素移到下一位置

(4)重复步骤3,直到找到已排序的元素小于或者等于新元素的位置(5)将新元素插入到下一位置中

(6)重复步骤2~5

代码:

void charu(int numberN[MAX])

{

int i,j,t;

int temp;

int numberY[MAX];

yuan(numberN);

for(t = 0; t < N; t++)

{

numberY[t] = numberN[t];

}

for(i=1;i

{

temp=numberY[i];

for(j=i;j>0&&numberY[j-1]>temp;j--)

{

numberY[j]=numberY[j-1];

}

numberY[j]=temp;

}

sheng(numberY);

}

对比数组中前一个元素跟后一个元素的大小,如果后面的元素比前面的元素小则用一个变量k来记住他的位置,接着第二次比较,前面“后一个元素”现变成了“前一个元素”,继续跟他的“后一个元素”进行比较如果后面的元素比他要小则用变量k记住它在数组中的位置(下标),等到循环结束的时候,我们应该找到了最小的那个数的下标了,然后进行判断,如果这个元素的下标不是第一个元素的下标,就让第一个元素跟他交换一下值,这样就找到整个数组中最小的数了。然后找到数组中第二小的数,让他跟数组中第二个元素交换一下值,以此类推。

代码:

void xuanze(int numberN[MAX])

{

int temp, i, j, t, min;

int numberY[MAX];

yuan(numberN);

for(t = 0; t < N; t++)

{

numberY[t] = numberN[t];

}

for(i = 0; i < N - 1; i++)

{

min = i;

for(j = i + 1; j < N; j++)

{

if(numberY[min] > numberY[j])

{

min = j;

}

}

temp = numberY[i];

numberY[i] = numberY[min];

numberY[min] = temp;

}

sheng(numberY);

}

先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2

代码:

void xier(int numberN[MAX])

{

int d, i, j, t, temp;

int numberY[MAX];

yuan(numberN);

for(t = 0; t < N; t++)

{

numberY[t] = numberN[t];

}

for(d = N/2;d >= 1;d = d/2)

{

for(i = d; i < N;i++)

{

temp = numberY[i];

for(j = i - d;(j >= 0) && (numberY[j] > temp);j = j-d)

{

numberY[j + d] = numberY[j];

}

numberY[j + d] = temp;

}

}

sheng(numberY);

}

设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

一趟快速排序的算法是:

(1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;

(2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];

(3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;

(4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;

(5)重复第3、4步,直到i=j;(3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。

找到符合条件的值,进行交换的时候i,j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。

代码:

int partions(int numberY[MAX],int low,int high)

{

int prvotkey=numberY[low];

while (low

{

while (low=prvotkey)

--high;

numberY[low]=numberY[high];

while (low

++low;

numberY[high]=numberY[low];

}

numberY[low]=prvotkey;

return low;

}

void quicksort(int numberY[MAX],int low,int high)

{

int prvotloc;

if(low

{

prvotloc=partions(numberY,low,high); //将第一次排序的结果作为枢轴

quicksort(numberY,low,prvotloc-1); //递归调用排序由low 到prvotloc-1

quicksort(numberY,prvotloc+1,high); //递归调用排序由prvotloc+1到high

}

}

void kuaisu(int numberN[MAX]) {

int i;

int numberY[MAX];

yuan(numberN);

for(i = 0; i < N; i++)

{

numberY[i] = numberN[i];

}

quicksort(numberY, 0, N-1);

sheng(numberY);

}

6.堆排序

大根堆排序算法的基本操作:

(1)建堆,建堆是不断调整堆的过程,从len/2处开始调整,一直到第一个节点,此处len是堆中元素的个数。建堆的过程是线性的过程,从len/2到0处一直调用调整堆的过程,相当于o(h1)+o(h2)…+o(hlen/2) 其中h表示节点的深度,len/2表示节点的个数,这是一个求和的过程,结果是线性的O(n)。

(2)调整堆:调整堆在构建堆的过程中会用到,而且在堆排序过程中也会用到。利用的思想是比较节点i和它的孩子节点left(i),right(i),选出三者最大(或者最小)者,如果最大(小)值不是节点i而是它的一个孩子节点,那边交互节点i和该节点,然后再调用调整堆过程,这是一个递归的过程。调整堆的过程时间复杂度与堆的深度有关系,是lgn 的操作,因为是沿着深度方向进行调整的。

(3)堆排序:堆排序是利用上面的两个过程来进行的。首先是根据元素构建堆。然后将堆的根节点取出(一般是与最后一个节点进行交换),将前面len-1个节点继续进行堆调整的过程,然后再将根节点取出,这样一直到所有节点都取出。

代码:

// array是待调整的堆数组,i是待调整的数组元素的位置,nlength是数组的长度

//本函数功能是:根据数组array构建大根堆

代码:

// array是待调整的堆数组,i是待调整的数组元素的位置,nlength是数组的长度

//本函数功能是:根据数组array构建大根堆

代码:

void HeapAdjust(int array[], int i, int nLength)

{

int nChild;

int nTemp;

for (nTemp = array[i]; 2 * i + 1 < nLength; i = nChild)

{

// 子结点的位置=2*(父结点位置)+ 1

nChild = 2 * i + 1;

// 得到子结点中较大的结点

if ( nChild < nLength-1 && array[nChild + 1] > array[nChild])

++nChild;

// 如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点

if (nTemp < array[nChild])

{

array[i] = array[nChild];

array[nChild]= nTemp;

}

else

// 否则退出循环

break;

}

}

// 堆排序算法

void dui(int numberN[MAX])

{

int tmp, t, i;

int numberY[MAX];

yuan(numberN);

for(t = 0; t < N; t++)

{

numberY[t] = numberN[t];

}

// 调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素

//length/2-1是第一个非叶节点,此处"/"为整除

for (i = floor(N -1)/ 2 ; i >= 0; --i)

HeapAdjust(numberY, i, N);

// 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素for (i = N - 1; i > 0; --i)

{

// 把第一个元素和当前的最后一个元素交换,

// 保证当前的最后一个位置的元素都是在现在的这个序列之中最大的

/// Swap(&array[0], &array[i]);

tmp = numberY[i];

numberY[i] = numberY[0];

numberY[0] = tmp;

// 不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值

HeapAdjust(numberY, 0, i);

}

sheng(numberY);

}

7.归并排序

归并操作的工作原理如下:

(1)申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列(2)设定两个指针,最初位置分别为两个已经排序序列的起始位置

(3)比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

(4)重复步骤(3)直到某一指针超出序列尾

(5)将另一序列剩下的所有元素直接复制到合并序列尾

代码:

//归并操作

void Merge(int sourceArr[], int targetArr[], int startIndex, int midIndex, int endIndex) {

int i, j, k;

for(i = midIndex+1, j = startIndex; startIndex <= midIndex && i <= endIndex; j++) {

if(sourceArr[startIndex] < sourceArr[i])

{

targetArr[j] = sourceArr[startIndex++];

}

else

{

targetArr[j] = sourceArr[i++];

}

}

if(startIndex <= midIndex)

{

for(k = 0; k <= midIndex-startIndex; k++)

{

targetArr[j+k] = sourceArr[startIndex+k];

}

}

if(i <= endIndex)

{

for(k = 0; k <= endIndex- i; k++)

{

targetArr[j+k] = sourceArr[i+k];

}

}

}

//内部使用递归,空间复杂度为n+logn

void MergeSort(int sourceArr[], int targetArr[], int startIndex, int endIndex)

{

int midIndex;

int tempArr[MAX]; //此处大小依需求更改

if(startIndex == endIndex)

{

targetArr[startIndex] = sourceArr[startIndex];

}

else

{

midIndex = (startIndex + endIndex)/2;

MergeSort(sourceArr, tempArr, startIndex, midIndex);

MergeSort(sourceArr, tempArr, midIndex+1, endIndex);

Merge(tempArr, targetArr,startIndex, midIndex, endIndex);

}

}

//调用

void guibing(int numberN[MAX])

{

int numberY[MAX];

yuan(numberN);

MergeSort(numberN, numberY, 0, N-1);

sheng(numberY);

}

8.基数排序

最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。

最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。

代码:

void jishu(int numberN[MAX])

{

int temp[10][20]={0}; //第一个10表示0~9,第二个20表示a的size

int order[10]={0};

int i,j,k,t,p,n=1; //k表示当前比较的那一位上的具体数字n=1,10,100,1000...取决于a中的最大的数

int numberY[MAX];

yuan(numberN);

for(t = 0; t < N; t++)

{ numberY[t] = numberN[t]; }

while(n <= 100)

{

for(i=0;i

{

k = (numberY[i]/n) % 10;

temp[k][order[k]] = numberY[i];

order[k]++;

}

p=0; //p为一次排序过程中,a的脚标

for(i=0;i<10;i++)

{

if(order[i] != 0)

{

for(j=0;j

{

numberY[p] = temp[i][j];

p++;

}

order[i] = 0;

}

}

n *= 10;

}

sheng(numberY);

}

五、实验测试

初始界面

各排序结果(相同)

《数据结构》实验报告——排序.docx

《数据结构》实验报告排序实验题目: 输入十个数,从插入排序,快速排序,选择排序三类算法中各选一种编程实现。 实验所使用的数据结构内容及编程思路: 1. 插入排序:直接插入排序的基本操作是,将一个记录到已排好序的有序表中,从而得到一个新的,记录增一得有序表。 一般情况下,第i 趟直接插入排序的操作为:在含有i-1 个记录的有序子序列r[1..i-1 ]中插入一个记录r[i ]后,变成含有i 个记录的有序子序列r[1..i ];并且,和顺序查找类似,为了在查找插入位置的过程中避免数组下标出界,在r [0]处设置哨兵。在自i-1 起往前搜索的过程中,可以同时后移记录。整个排序过程为进行n-1 趟插入,即:先将序列中的第一个记录看成是一个有序的子序列,然后从第2 个记录起逐个进行插入,直至整个序列变成按关键字非递减有序序列为止。 2. 快速排序:基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。 假设待排序的序列为{L.r[s] ,L.r[s+1],…L.r[t]}, 首先任意选取一个记录 (通常可选第一个记录L.r[s])作为枢轴(或支点)(PiVOt ),然后按下述原则重新排列其余记录:将所有关键字较它小的记录都安置在它的位置之前,将所有关键字较大的记录都安置在它的位置之后。由此可以该“枢轴”记录最后所罗的位置i 作为界线,将序列{L.r[s] ,… ,L.r[t]} 分割成两个子序列{L.r[i+1],L.[i+2], …,L.r[t]}。这个过程称为一趟快速排序,或一次划分。 一趟快速排序的具体做法是:附设两个指针lOw 和high ,他们的初值分别为lOw 和high ,设枢轴记录的关键字为PiVOtkey ,则首先从high 所指位置起向前搜索找到第一个关键字小于PiVOtkey 的记录和枢轴记录互相交换,然后从lOw 所指位置起向后搜索,找到第一个关键字大于PiVOtkey 的记录和枢轴记录互相 交换,重复这两不直至low=high 为止。 具体实现上述算法是,每交换一对记录需进行3 次记录移动(赋值)的操作。而实际上,

排序操作实验报告

数据结构与算法设计 实验报告 (2016 — 2017 学年第1 学期) 实验名称: 年级: 专业: 班级: 学号: 姓名: 指导教师: 成都信息工程大学通信工程学院

一、实验目的 验证各种简单的排序算法。在调试中体会排序过程。 二、实验要求 (1)从键盘读入一组无序数据,按输入顺序先创建一个线性表。 (2)用带菜单的主函数任意选择一种排序算法将该表进行递增排序,并显示出每一趟排序过程。 三、实验步骤 1、创建工程(附带截图说明) 2、根据算法编写程序(参见第六部分源代码) 3、编译 4、调试 四、实验结果图 图1-直接输入排序

图2-冒泡排序 图3-直接选择排序 五、心得体会 与哈希表的操作实验相比,本次实验遇到的问题较大。由于此次实验中设计了三种排序方法导致我在设计算法时混淆了一些概念,设计思路特别混乱。虽然在理清思路后成功解决了直接输入和直接选择两种算法,但冒泡

排序的算法仍未设计成功。虽然在老师和同学的帮助下完成了冒泡排序的算法,但还需要多练习这方面的习题,平时也应多思考这方面的问题。而且,在直接输入和直接选择的算法设计上也有较为复杂的地方,对照书本做了精简纠正。 本次实验让我发现自己在算法设计上存在一些思虑不周的地方,思考问题过于片面,逻辑思维能力太过单薄,还需要继续练习。 六、源代码 要求:粘贴个人代码,以便检查。 #include #define MAXSIZE 100 typedef int KeyType; typedef int DataType; typedef struct{ KeyType key; DataType data; }SortItem,SqList[MAXSIZE]; /*******直接插入顺序表*******/ void InsertSort(SqList L,int n) { int i,j,x; SortItem p; for(i=1;i

(完整word版)查找、排序的应用 实验报告

实验七查找、排序的应用 一、实验目的 1、本实验可以使学生更进一步巩固各种查找和排序的基本知识。 2、学会比较各种排序与查找算法的优劣。 3、学会针对所给问题选用最适合的算法。 4、掌握利用常用的排序与选择算法的思想来解决一般问题的方法和技巧。 二、实验内容 [问题描述] 对学生的基本信息进行管理。 [基本要求] 设计一个学生信息管理系统,学生对象至少要包含:学号、姓名、性别、成绩1、成绩2、总成绩等信息。要求实现以下功能:1.总成绩要求自动计算; 2.查询:分别给定学生学号、姓名、性别,能够查找到学生的基本信息(要求至少用两种查找算法实现); 3.排序:分别按学生的学号、成绩1、成绩2、总成绩进行排序(要求至少用两种排序算法实现)。 [测试数据] 由学生依据软件工程的测试技术自己确定。 三、实验前的准备工作 1、掌握哈希表的定义,哈希函数的构造方法。 2、掌握一些常用的查找方法。 1、掌握几种常用的排序方法。 2、掌握直接排序方法。

四、实验报告要求 1、实验报告要按照实验报告格式规范书写。 2、实验上要写出多批测试数据的运行结果。 3、结合运行结果,对程序进行分析。 五、算法设计 a、折半查找 设表长为n,low、high和mid分别指向待查元素所在区间的下界、上界和中点,key为给定值。初始时,令low=1,high=n,mid=(low+high)/2,让key与mid指向的记录比较, 若key==r[mid].key,查找成功 若keyr[mid].key,则low=mid+1 重复上述操作,直至low>high时,查找失败 b、顺序查找 从表的一端开始逐个进行记录的关键字和给定值的比较。在这里从表尾开始并把下标为0的作为哨兵。 void chaxun(SqList &ST) //查询信息 { cout<<"\n************************"<=1;j--) if(ST.r[j].xuehao

算法排序问题实验报告

《排序问题求解》实验报告 一、算法的基本思想 1、直接插入排序算法思想 直接插入排序的基本思想是将一个记录插入到已排好序的序列中,从而得到一个新的, 记录数增1 的有序序列。 直接插入排序算法的伪代码称为InsertionSort,它的参数是一个数组A[1..n],包含了n 个待排序的数。用伪代码表示直接插入排序算法如下: InsertionSort (A) for i←2 to n do key←A[i] //key 表示待插入数 //Insert A[i] into the sorted sequence A[1..i-1] j←i-1 while j>0 and A[j]>key do A[j+1]←A[j] j←j-1 A[j+1]←key 2、快速排序算法思想 快速排序算法的基本思想是,通过一趟排序将待排序序列分割成独立的两部分,其中一 部分记录的关键字均比另一部分记录的关键字小,则可对这两部分记录继续进行排序,以达到整个序列有序。 假设待排序序列为数组A[1..n],首先选取第一个数A[0],作为枢轴(pivot),然后按照下述原则重新排列其余数:将所有比A[0]大的数都排在它的位置之前,将所有比A[0]小的数都排在它的位置之后,由此以A[0]最后所在的位置i 作为分界线,将数组A[1..n]分成两个子数组A[1..i-1]和A[i+1..n]。这个过程称作一趟快速排序。通过递归调用快速排序,对子数组A[1..i-1]和A[i+1..n]排序。 一趟快速排序算法的伪代码称为Partition,它的参数是一个数组A[1..n]和两个指针low、high,设枢轴为pivotkey,则首先从high 所指位置起向前搜索,找到第一个小于pivotkey 的数,并将其移到低端,然后从low 所指位置起向后搜索,找到第一个大于pivotkey 的数,并将其移到高端,重复这两步直至low=high。最后,将枢轴移到正确的位置上。用伪代码表示一趟快速排序算法如下: Partition ( A, low, high) A[0]←A[low] //用数组的第一个记录做枢轴记录 privotkey←A[low] //枢轴记录关键字 while low=privotkey do high←high-1 A[low]←A[high] //将比枢轴记录小的记录移到低端 while low

实验报告-排序与查找

电子科技大学实验报告 课程名称:数据结构与算法 学生姓名: 学号: 点名序号: 指导教师: 实验地点:基础实验大楼 实验时间: 5月20日 2014-2015-2学期 信息与软件工程学院

实验报告(二) 学生姓名学号:指导教师: 实验地点:基础实验大楼实验时间:5月20日 一、实验室名称:软件实验室 二、实验项目名称:数据结构与算法—排序与查找 三、实验学时:4 四、实验原理: 快速排序的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按次方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。一躺快速排序的算法是: 1)设置两个变量I、J,排序开始的时候I:=1,J:=N 2)以第一个数组元素作为关键数据,赋值给X,即X:=A[1]; 3)从J开始向前搜索,即(J:=J-1),找到第一个小于X的值,两者交换; 4)从I开始向后搜索,即(I:=I+1),找到第一个大于X的值,两者交换; 5)重复第3、4步,直到I=J。 二分法查找(折半查找)的基本思想: (1)确定该区间的中点位置:mid=(low+high)/2 min代表区间中间的结点的位置,low代表区间最左结点位置,high代表区间最右结点位置(2)将待查a值与结点mid的关键字(下面用R[mid].key)比较,若相等,则查找成功,否则确定新的查找区间: A)如果R[mid].key>a,则由表的有序性可知,R[mid].key右侧的值都大于a,所以等于a的关键字如果存在,必然在R[mid].key左边的表中,这时high=mid-1; B)如果R[mid].key

查找与排序实验报告

实验四:查找与排序 【实验目的】 1.掌握顺序查找算法的实现。 2.掌握折半查找算法的实现。 【实验内容】 1.编写顺序查找程序,对以下数据查找37所在的位置。 5,13,19,21,37,56,64,75,80,88,92 2.编写折半查找程序,对以下数据查找37所在的位置。 5,13,19,21,37,56,64,75,80,88,92 【实验步骤】 1.打开VC++。 2.建立工程:点File->New,选Project标签,在列表中选Win32 Console Application,再在右边的框里为工程起好名字,选好路径,点OK->finish。 至此工程建立完毕。 3.创建源文件或头文件:点File->New,选File标签,在列表里选C++ Source File。给文件起好名字,选好路径,点OK。至此一个源文件就被添加到了你刚创建的工程之中。 4.写好代码 5.编译->链接->调试 #include "stdio.h" #include "malloc.h" #define OVERFLOW -1 #define OK 1 #define MAXNUM 100 typedef int Elemtype; typedef int Status; typedef struct {

Elemtype *elem; int length; }SSTable; Status InitList(SSTable &ST ) { int i,n; ST.elem = (Elemtype*) malloc (MAXNUM*sizeof (Elemtype)); if (!ST.elem) return(OVERFLOW); printf("输入元素个数和各元素的值:"); scanf("%d\n",&n); for(i=1;i<=n;i++) { scanf("%d",&ST.elem[i]); } ST.length = n; return OK; } int Seq_Search(SSTable ST,Elemtype key) { int i; ST.elem[0]=key; for(i=ST.length;ST.elem[i]!=key;--i); return i; } int BinarySearch(SSTable ST,Elemtype key) { int low,high,mid; low=1; high=ST.length;

排序问题实验报告

2010级数据结构实验报告 实验名称:排序 姓名:袁彬 班级: 2009211120 班内序号: 09 学号: 09210552 日期: 2010 年12 月19 日 1.实验要求 试验目的: 通过选择试验内容中的两个题目之一,学习、实现、对比各种排序的算法,掌握各种排序算法的优缺点,以及各种算法使用的情况。 试验内容: 题目一: 使用简单数组实现下面各种排序算法,并进行比较。 排序算法如下: ①插入排序; ②希尔排序 ③冒泡排序; ④快速排序; ⑤简单选择排序; ⑥堆排序 ⑦归并排序 ⑧基数排序 ⑨其他。 具体要求如下: ①测试数据分为三类:正序,逆序,随机数据。 ②对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换记为三次移动)。 ③对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微妙。 ④对②和③的结果进行分析,验证上述各种算法的时间复杂度。 ⑤编写main()函数测试各种排序算法的正确性。 题目二: 使用链表实现下面各种排序算法,并进行比较。 排序算法如下: ①插入排序; ②冒泡排序; ③快速排序;

④简单选择排序; ⑤其他。 具体要求如下: ①测试数据分为三类:正序,逆序,随机数据。 ②对于这三类数据,比较上述排序算法中关键字的比较次数和移动次数(其中关键字交换记为三次移动)。 ③对于这三类数据,比较上述排序算法中不同算法的执行时间,精确到微妙(选作) ④对②和③的结果进行分析,验证上述各种算法的时间复杂度。 ⑤编写main()函数测试各种排序算法的正确性。 2. 程序分析 2.1 存储结构 程序中每一个算法均是用一个类来表示的,类中有自己的构造函数、排序函数。 程序的储存结构采用数组。数组的第一个位置不存储数据。数据从第二个位置开始。数组中的相对位置为数组的下标。 2.2 关键算法分析 ㈠、关键算法: 1、插入排序函数:Insert s ort(int n) ①、从2开始做循环,依次和前面的数进行比较:for(int i=2;i<=n;i++) ②、如果后面的比前面的小,则进行前移:if(number[i]=1;d=d/2) ②、在自己的间隔中进行简单插入排序,进行循环:for(int i=d+1;i<=n;i++) ③、如果后面的数据比前面的小,进行前移:if(number[i]0;j=j-d) ⑥、大的数据后移:number[j+d]=number[j]; ⑦、哨兵归位:number[j+d]=number[0]; 3、冒泡排序函数:Bubble s ort(int n) ①、设置有序无序的边界点:int pos=n; ②、当边界点不为空进行循环:while(pos!=0) ③、边界点传递给bound:int bound=pos; ④、从开始到边界点进行循环:for(int i=1;inumber[i+1]) ⑥、交换:number[0]=number[i];number[i]=number[i+1];number[i+1]=number[0]; ⑦、从小设置边界点:pos=i; 4、一趟快速排序函数:partion(int first,int end) ①、传递设置整个数据的起点和终点:int i=first;int j=end; ②、设置中轴:number[0]=number[i]; ③、当end大于first进行循环:while(i

各种排序实验报告

【一】需求分析 课程题目是排序算法的实现,课程设计一共要设计八种排序算法。这八种算法共包括:堆排序,归并排序,希尔排序,冒泡排序,快速排序,基数排序,折半插入排序,直接插入排序。 为了运行时的方便,将八种排序方法进行编号,其中1为堆排序,2为归并排序,3为希尔排序,4为冒泡排序,5为快速排序,6为基数排序,7为折半插入排序8为直接插入排序。 【二】概要设计 1.堆排序 ⑴算法思想:堆排序只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。将序列所存储的元素A[N]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性质的完全二叉树:树中任一非叶结点的元素均不大于(或不小于)其左右孩子(若存在)结点的元素。算法的平均时间复杂度为O(N log N)。 ⑵程序实现及核心代码的注释: for(j=2*i+1; j<=m; j=j*2+1) { if(j=su[j]) break; su[i]=su[j]; i=j; } su[i]=temp; } void dpx() //堆排序 { int i,temp; cout<<"排序之前的数组为:"<=0; i--) { head(i,N); } for(i=N-1; i>0; i--) {

temp=su[i]; su[i]=su[0]; su[0]=temp; head(0,i-1); } cout<<"排序之后的数组为:"<

顺序表的查找、插入与删除实验报告

《数据结构》实验报告一 学院:班级: 学号:姓名: 日期:程序名 一、上机实验的问题和要求: 顺序表的查找、插入与删除。设计算法,实现线性结构上的顺序表的产生以及元素的查找、插入与删除。具体实现要求: 1.从键盘输入10个整数,产生顺序表,并输入结点值。 2.从键盘输入1个整数,在顺序表中查找该结点的位置。若找到,输出结点的位置;若找 不到,则显示“找不到”。 3.从键盘输入2个整数,一个表示欲插入的位置i,另一个表示欲插入的数值x,将x插 入在对应位置上,输出顺序表所有结点值,观察输出结果。 4.从键盘输入1个整数,表示欲删除结点的位置,输出顺序表所有结点值,观察输出结果。 二、源程序及注释: #include #include /*顺序表的定义:*/ #include #define ListSize 100 /*表空间大小可根据实际需要而定,这里假设为100*/ typedef int DataType; /*DataType可以是任何相应的数据类型如int, float或char*/ typedef struct { DataType data[ListSize]; /*向量data用于存放表结点*/ int length; /*当前的表长度*/ }SeqList; void main() { SeqList L; int i,x; int n=10; /*欲建立的顺序表长度*/ L.length=0; void CreateList(SeqList *L,int n); void PrintList(SeqList L,int n); int LocateList(SeqList L,DataType x); void InsertList(SeqList *L,DataType x,int i); void DeleteList(SeqList *L,int i);

河南工业大学实验报告——查找和排序(排序)——张伟龙

河南工业大学实验报告 课程名称数据结构实验项目实验三查找和排序(二)——排序院系信息学院计科系专业班级计科1203 姓名张伟龙学号 201216010313 指导老师范艳峰日期 2013.6.5 批改日期成绩 一实验目的 掌握希尔排序、快速排序、堆排序的算法实现。 二实验内容及要求 实验内容:1.实现希尔排序。 2.实现快速排序。 3. 实现堆排序。 (三选一) 实验要求:1. 根据所选题目,用C语言编写程序源代码。 2. 源程序必须编译调试成功,独立完成。 三实验过程及运行结果 选择第三题: Source Code: #include #include using namespace std; void HeapAdjust(int *a,int i,int size) //调整堆 { int lchild=2*i; //i的左孩子节点序号

int rchild=2*i+1; //i的右孩子节点序号 int max=i; //临时变量 if(i<=size/2) //如果i是叶节点就不用进行调整 { if(lchild<=size&&a[lchild]>a[max]) { max=lchild; } if(rchild<=size&&a[rchild]>a[max]) { max=rchild; } if(max!=i) { swap(a[i],a[max]); HeapAdjust(a,max,size); //避免调整之后以max为父节点的子树不是堆 } } } void BuildHeap(int *a,int size) //建立堆 { int i; for(i=size/2;i>=1;i--) //非叶节点最大序号值为size/2 { HeapAdjust(a,i,size); } }

数据结构内排序实验报告

一、实验目的 1、了解内排序都是在内存中进行的。 2、为了提高数据的查找速度,需要对数据进行排序。 3、掌握内排序的方法。 二、实验内容 1、设计一个程序e xp10—1.cpp实现直接插入排序算法,并输出{9,8,7,6,5,4,3,2,1,0}的排序 过程。 (1)源程序如下所示: //文件名:exp10-1.cpp #include #define MAXE 20 //线性表中最多元素个数 typedef int KeyType; typedef char InfoType[10]; typedef struct //记录类型 { KeyType key; //关键字项 InfoType data; //其他数据项,类型为InfoType } RecType; void InsertSort(RecType R[],int n) //对R[0..n-1]按递增有序进行直接插入排序 { int i,j,k; RecType temp; for (i=1;i=0 && temp.key

内部排序比较 (实验报告+源程序)C++

实验报告3 实验名称:数据结构与软件设计实习 题目:内部排序算法比较 专业:生物信息学班级:01 姓名:学号:实验日期:2010.07.24 一、实验目的: 比较冒泡排序、直接插入排序、简单选择排序、快速排序、希尔排序; 二、实验要求: 待排序长度不小于100,数据可有随机函数产生,用五组不同输入数据做比较,比较的指标为关键字参加比较的次数和关键字移动的次数; 对结果做简单的分析,包括各组数据得出结果的解释; 设计程序用顺序存储。 三、实验内容 对各种内部排序算法的时间复杂度有一个比较直观的感受,包括关键字比较次数和关键字移动次数。 将排序算法进行合编在一起,可考虑用顺序执行各种排序算法来执行,最后输出所有结果。 四、实验编程结果或过程: 1. 数据定义 typedef struct { KeyType key; }RedType; typedef struct { RedType r[MAXSIZE+1]; int length; }SqList; 2. 函数如下,代码详见文件“排序比较.cpp”int Create_Sq(SqList &L) void Bubble_sort(SqList &L)//冒泡排序void InsertSort(SqList &L)//插入排序 void SelectSort(SqList &L) //简单选择排序int Partition(SqList &L,int low,int high) void QSort(SqList &L,int low,int high)//递归形式的快速排序算法 void QuickSort(SqList &L) void ShellInsert(SqList &L,int dk)//希尔排序 void ShellSort(SqList &L,int dlta[ ]) 3. 运行测试结果,运行结果无误,如下图语速个数为20

《数据结构》实验报告查找

实验四——查找 一、实验目的 1.掌握顺序表的查找方法,尤其是折半查找方法; 2.掌握二叉排序树的查找算法。 二、实验内容 1.建立一个顺序表,用顺序查找的方法对其实施查找; 2.建立一个有序表,用折半查找的方法对其实施查找; 3.建立一个二叉排序树,根据给定值对其实施查找; 4.对同一组数据,试用三种方法查找某一相同数据,并尝试进行性能分析。 三、实验预习内容 实验一包括的函数有:typedef struct ,创建函数void create(seqlist & L),输出函数void print(seqlist L),顺序查找int find(seqlist L,int number),折半查找int halffind(seqlist L,int number) 主函数main(). 实验二包括的函数有:结构体typedef struct,插入函数void insert(bnode * & T,bnode * S),void insert1(bnode * & T),创建函数void create(bnode * & T),查找函数bnode * search(bnode * T,int number),主函数main(). 四、上机实验 实验一: 1.实验源程序。 #include<> #define N 80 typedef struct { int number; umber; for(i=1;[i].number!=0;) { cin>>[i].name>>[i].sex>>[i].age; ++; cout<>[++i].number; } } umber<<"\t"<<[i].name<<"\t"<<[i].sex<<"\t"<<[i].age<

查找排序实验报告

《编程实训》 实验报告书 专业:计算机科学与技术 班级:151班 学号: 姓名: 指导教师: 日期:2016年6月30日

目录 一、需求分析 (3) 1.任务要求 (3) 2.软件功能分析 (3) 3.数据准备 (3) 二、概要设计 (3) 1.功能模块图 (4) 2.模块间调用关系 (4) 3.主程序模块 (5) 4.抽象数据类型描述 (5) 三、详细设计 (6) 1.存储结构定义 (6) 2.各功能模块的详细设计 (7) 四、实现和调试 (7) 1.主要的算法 (7) 2.主要问题及解决 (8) 3.测试执行及结果 (8) 五、改进 (9) 六、附录 (9) 1.查找源程序 (9) 2.排序源程序 (9)

目录 1 需求分析 1.1 任务要求 对于从键盘随机输入的一个序列的数据,存入计算机内,给出各种查找算法的实现; 以及各种排序算法的实现。 1.2 软件功能分析 任意输入n个正整数,该程序可以实现各类查找及排序的功能并将结果输出。 1.3 数据准备 任意输入了5个正整数如下: 12 23 45 56 78 2 概要设计(如果2,3合并可以省略2.4) 2.1 功能模块图(注:含功能说明) 2.2 模块间调用关系 2.3 主程序模块 2.4 抽象数据类型描述 存储结构:数据结构在计算机中的表示(也称映像)叫做物理结构。又称为存储结构。数据类型(data type)是一个“值”的集合和定义在此集合上的一组操作的总称。 3 详细设计 3.1 存储结构定义 查找: typedef int ElemType ; //顺序存储结构 typedef struct { ElemType *elem; //数据元素存储空间基址,建表时按实际长度分配,号单元留空 int length; //表的长度

数据结构(C语言版)实验报告-(内部排序算法比较)

数据结构与算法》实验报告 一、需求分析 问题描述:在教科书中,各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间。试通过随机数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受。 基本要求: (l )对以下 6 种常用的内部排序算法进行比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。 (2 )待排序表的表长不小于100000 ;其中的数据要用伪随机数程序产生;至少要用 5 组不同的输入数据作比较;比较的指标为有关键字参加的比较次数和关键字的移动次数(关键字交换计为 3 次移动)。 ( 3 )最后要对结果作简单分析,包括对各组数据得出结果波动大小的解释。数据测试:二.概要设计 1. 程序所需的抽象数据类型的定义: typedef int BOOL; typedef struct StudentData { } Data; typedef struct LinkList { Data Record[MAXSIZE]; int num; // 存放关键字 int Length; // 数组长度// 用数组存放所有的随机数 // 说明BOOL 是int 的别名 } LinkList int RandArray[MAXSIZE]; // 定义长度为MAXSIZE 的随机数组 void RandomNum() // 随机生成函数

void InitLinkList(LinkList* L) // 初始化链表 // 比较所有排序 2 . 各程序模块之间的层次(调用)关系: BOOL LT(int i, int j,int* CmpNum) // 比较 i 和 j 的大小 void Display(LinkList* L) // 显示输出函数 void ShellSort(LinkList* L, int dlta[], int t,int* CmpNum, int* ChgNum) void QuickSort (LinkList* L, // 快速排序 void HeapSort (LinkList* L, // 堆排序 void BubbleSort(LinkList* L, // 冒泡排序 void SelSort(LinkList* L, // 选择排序 int* CmpNum, int* ChgNum) int* CmpNum, int* ChgNum) int* CmpNum, int* ChgNum) * CmpNum, int* ChgNum) void Compare(LinkList* L,int* CmpNum, int* ChgNum) // 希尔排序

二叉排序树实验报告

二叉排序树的实现 实验内容与要求 1) 实现二叉排序树,包括生成、插入,删除; 2) 对二叉排序树进行先根、中根、和后根非递归遍历; 3) 每次对树的修改操作和遍历操作的显示结果都需要在屏 幕上用树的形状表示出来。 实验方案 1. 选择链表的方式来构造节点,存储二叉排序树的节点。// 树的结构struct BSTNode { // 定义左右孩子指针 struct BSTNode *lchild,*rchild; // 节点的关键字 TElemType key; }; int depth=0; // 定义一个struct BSTNode 类型的指针typedef BSTNode *Tree; 2. 对树的操作有如下方法: // 创建二叉排序树 Tree CreatTree(Tree T) ; // 二叉树的深度,返回一个int 值为该树的深度 int TreeDepth(Tree T) // 树状输出二叉树,竖向输出 void PrintTree(Tree T , int layer) ; // 查找关键字,如果关键字存在则返回所在节点的父节点,如果关键字不存在则返回叶子所在的节点 Status SearchBST(Tree T , TElemType key , Tree f,Tree &p) ; // 向树中插入节点 Status InsertBST(Tree &T , TElemType e) ; // 删除节点 Status Delete(Tree &T) ;

// 删除指定节点,调用Delete(Tree &T) 方法 Status DeleteData(Tree &T , TElemType key) ; // 非递归先序遍历void x_print(Tree T); // 非递归中序遍历 Void z_print(Tree T ); // 非递归后序遍历 void h_print(Tree T); 3. 对二叉排序树非递归先根、中根、后根遍历,采用栈来存储一次遍历过的节点的形式来辅助实现 // 自定义类型以SElemType 作为栈中指针返回的值的类型 // 也就是要返回一个节点的指针 typedef Tree SElemType; // 栈的结构 struct Stack { // 栈底指针SElemType *base; // 栈顶指针SElemType *top; // 栈的容量 int stacksize; }; 4. 栈的操作方法: // 创建一个空栈 Status InitStack(Stack &S) // 获取栈顶元素并删除栈中该位置的元素SElemType Pop(Stack &S,SElemType &elem) // 获取栈顶元素返回栈顶元素不对栈做任何修改SElemType getTop(Stack S,SElemType &elem) // 删除栈顶元素 Status DeleteTop(Stack &S) // 往栈中压入数据 Status Push(Stack &S,SElemType elem) // 判断栈是否为空 Status IsEmpty(Stack S) 三、代码实现 #include #include using namespace std;

数据结构排序实验报告

《数据结构》课程设计报告 实验五排序 一、需求分析: 本演示程序用C++6.0编写,完成各种排序的实现,对输入的一组数字实现不同的排序方法,对其由小到大顺序输出。 (1)分别对直接插入排序、希尔排序、冒泡排序、快速排序、选择排序、堆排序算法进行编写。 (2)、对存储的函数即输入的数字进行遍历。 (3)、初始化函数对输入的数字进行保存。 (4)、主函数实现使用者操作界面的编写,对输入、选择、保存、输出的各种实现。这当中还包括了各个函数的调用的实现。 (5)、程序所能达到的功能:完成对输入的数字的生成,并通过对各排序的选择实现

数字从小到大的输出。 二、程序主要功能以及基本要求: (1)、设计一个菜单,格式如下: 1、直接插入排序 2、希尔排序 3、冒泡排序 4、快速排序 5、选择排序 6、堆排序 7、退出 (2)、选择不同的菜单但进行相应的排序,并给出排序的关键字序列。 三、系统框架图: 本程序包含了9个函数,它们分别是: (1)、直接插入排序的算法函数InsertSort()。 (2)、希尔排序的算法函数ShellSort()。 (4)、快速排序的算法函数Partition()。 (5)、选择排序算法函数SelectSort()。 (6)、堆排序算法函数HeapAdjust()。 (7)、对存储数字的遍历函数Visit()。 (8)、初始化函数InitSqList()。 (9)、主函数main()。 四、详细设计 实现各个算法的主要内容,下面是各个函数的主要信息: (1)各个排序函数的算法:

一、直接插入排序 void InsertSort(SqList &L) { int i,j; for( i=2; i<=L.length;i++) { if(L.r[i].key < L.r[i-1].key) { L.r[0] = L.r[i]; L.r[i] = L.r[i-1]; for( j=i-2; (L.r[0].key < L.r[j].key); j--) L.r[j+1] = L.r[j]; L.r[j+1] = L.r[0]; } } } 二、希尔排序 void ShellSort(SqList &L) { int i, j; int dk = 1;//增量 while(dk <=L.length/3) dk = 3*dk+1;//增大增量 while(dk>0) { dk /= 3;//减小增量 for (i = dk; i <=L.length; i++) { L.r[0].key = L.r[i].key; j = i;

河南工业大学实验报告_实验三 查找和排序(一)——查找

xxx大学实验报告 课程名称数据结构实验项目实验三查找和排序(一)——查找 院系信息学院计类系专业班级计类1501 姓名学号 指导老师日期 批改日期成绩 一实验目的 1.掌握哈希函数——除留余数法的应用; 2. 掌握哈希表的建立; 3. 掌握冲突的解决方法; 4. 掌握哈希查找算法的实现。 二实验内容及要求 实验内容:已知一组关键字(19,14,23,1,68,20,84,27,55,11,10,79),哈希 函数定义为:H(key)=key MOD 13, 哈希表长为m=16。实现该哈希表的散列,并 计算平均查找长度(设每个记录的查找概率相等)。 实验要求:1. 哈希表定义为定长的数组结构;2. 使用线性探测再散列或链 地址法解决冲突;3. 散列完成后在屏幕上输出数组内容或链表;4. 输出等概率 查找下的平均查找长度;5. 完成散列后,输入关键字完成查找操作,要分别测 试查找成功与不成功两种情况。 注意:不同解决冲突的方法会使得平均查找长度不同,可尝试使用不同解决 冲突的办法,比较平均查找长度。(根据完成情况自选,但至少能使用一种方法 解决冲突) 三实验过程及运行结果 #include #include #include #define hashsize 16

#define q 13 int sign=2; typedef struct Hash { int date; //值域 int sign; //标记 }HashNode; void compare(HashNode H[],int p,int i,int key[]) //线性冲突处理{ p++; if(H[p].sign!=0) { sign++; compare(H,p,i,key); } else { H[p].date=key[i]; H[p].sign=sign; sign=2; } } void Hashlist(HashNode H[],int key[]) { int p; for(int i=0;i<12;i++) { p=key[i]%q; if(H[p].sign==0) { H[p].date=key[i]; H[p].sign=1; } else compare(H,p,i,key); } } int judge(HashNode H[],int num,int n) //查找冲突处理 {

相关主题
文本预览
相关文档 最新文档